Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Follow the established pattern for using Presenters #1329

Closed
flyingzumwalt opened this issue Nov 12, 2015 · 2 comments
Closed

Follow the established pattern for using Presenters #1329

flyingzumwalt opened this issue Nov 12, 2015 · 2 comments
Milestone

Comments

@flyingzumwalt
Copy link

The Pattern

Using Presenters allows you to encapsulate logic that tends to become smeared across many view helpers and templates. The established pattern is to have a View Helper method that instantiates your Presenter and then yields that presenter to a block for rendering.

module ApplicationHelper
  def present(object, klass = nil)
    klass ||= "#{object.class}Presenter".constantize
    presenter = klass.new(object, self)
    yield presenter if block_given?
    presenter
  end
end

In Blacklight, if we are using the default Presenter and pass a SolrDocument into that method, it would be the equivalent of calling

    presenter = Blacklight::DocumentPresenter.new(document, self) 
    yield presenter
    presenter

Applying this to Blacklight

module BlacklightHelperBehavior
  def present(object, klass = nil)
    klass ||= presenter_class(object)
    presenter = klass.new(object, self)
    yield presenter if block_given?
    presenter
  end

  def presenter_class(object)
     case object
        when SolrDocument
           blacklight_config.document_presenter_class
        else
           "#{object.class}Presenter".constantize
      end
  end
end

this allows us to have a view partial that says

    <% present @document do |document_presenter| %>
        <div id="document">
            ... 
        </div>
    <% end %>

which could be wrapped in another presenter like this

<% present @document_list do |search_results_presenter| %>
    <div id="documents">
        <% search_results_presenter.present_documents do |document_presenter| %>
            <div id="document">
                     ... 
             </div>
        <% end %>
    </div>
<% end %>

Why Blacklight needs this

Rendering search results in blacklight involves diving head-first down a rabbit hole that starts here:

# in app/views/catalog/_search_results.html.erb
<%- if @response.empty? %>
  <%= render "zero_results" %>
<%- elsif render_grouped_response? %>
  <%= render_grouped_document_index %>
<%- else %>
  <%= render_document_index %>
<%- end %>

this leads into a vortex of helper methods with names like render_grouped_document_index, which in turn rely on a nested set of helper methods and view partials that reference each other. A DocumentListPresenter and DocumentPresenter should allow us to contain most of that sprawl, making it much more readable, predictable, testable and customizable.

References

http://nithinbekal.com/posts/rails-presenters/
http://railscasts.com/episodes/287-presenters-from-scratch?autoplay=true

@barmintor
Copy link
Contributor

@jcoyne at a glance, this looks like the way Presenters are being used. Is this issue still open?

@dkinzer
Copy link
Member

dkinzer commented Oct 30, 2018

I started doing a little bit of this on the Temple instance and quickly realized that moving everything to presenters is a really big haul. Perhaps this can be broken up into smaller chunks by targeting specific helper modules and methods?

@barmintor barmintor modified the milestones: 7.0, 8.x Nov 26, 2018
@jcoyne jcoyne closed this as completed Oct 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants