Skip to content

Commit

Permalink
Convert document show/index views to support and use view components
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeer committed Jul 31, 2020
1 parent b07a073 commit ed83514
Show file tree
Hide file tree
Showing 22 changed files with 444 additions and 54 deletions.
29 changes: 29 additions & 0 deletions app/components/blacklight/document_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<%= content_tag @component,
id: @id,
data: {
'document-id': @document.id.to_s.parameterize,
'document-counter': @counter,
},
itemscope: true,
itemtype: @document.itemtype,
class: classes.flatten.join(' ') do %>
<%= header %>
<% if body.present? %>
<%= body %>
<% else %>
<div class="document-main-section">
<header class="documentHeader row">
<%= content_tag @title_component, class: 'index_title document-title-heading' do %>
<%= before_title %><%= title %><%= after_title %>
<% end %>
<%= actions %>
</header>

<%= content %>
<%= metadata %>
</div>

<%= thumbnail %>
<% end %>
<%= footer %>
<% end %>
117 changes: 117 additions & 0 deletions app/components/blacklight/document_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# frozen_string_literal: true

module Blacklight
class DocumentComponent < ::ViewComponent::Base
# Available content areas; some have defaults provided by
# the accessors below.
with_content_areas :header, :body, :footer,
:before_title, :title, :after_title,
:actions, :metadata, :thumbnail,
:partials
with_collection_parameter :document

# rubocop:disable Metrics/ParameterLists
# @param document [Blacklight::Document]
# @param id [String] HTML id for the root element
# @param classes [Array, String] additional HTML classes for the root element
# @param component [Symbol, String] HTML tag type to use for the root element
# @param title_component [Symbol, String] HTML tag type to use for the title element
# @param presenter [Blacklight::DocumentPresenter]
# @param metadata_component [Blacklight::DocumentMetadataComponent]
# @param counter [Number, nil]
# @param show [Boolean] are we showing only a single document (vs a list of search results); used for backwards-compatibility
def initialize(document:, id: nil, classes: [], component: :article, title_component: :h4, presenter: nil, metadata_component: Blacklight::DocumentMetadataComponent, counter: nil, show: false)
@document = document

@component = component
@title_component = title_component
@id = id || ('document' if show)
@classes = classes

@presenter = presenter
@metadata_component = metadata_component

@counter = counter

@show = show
end
# rubocop:enable Metrics/ParameterLists

# HTML classes to apply to the root element
def classes
[
@classes,
@view_context.render_document_class(@document),
'document',
("document-position-#{@counter}" if @counter)
].compact.flatten
end

# Content for the document title area; should be an inline element
def title
@title || begin
if show?
content_tag('span', presenter.heading, itemprop: "name")
else
@view_context.link_to_document @document, counter: @counter, itemprop: 'name'
end
end
end

# Content for the document actions area
def actions
return if @show

@actions || begin
@view_context.render_index_doc_actions @document, wrapping_class: "index-document-functions col-sm-3 col-lg-2"
end
end

# Content for the document thumbnail area
def thumbnail
return if @show

@thumbnail || begin
return unless presenter.thumbnail.exists?

content_tag :div, class: "document-thumbnail" do
presenter.thumbnail.thumbnail_tag({ alt: '' }, 'aria-hidden': true, tabindex: -1, counter: @counter)
end
end
end

# Content for the document metadata area
def metadata
@metadata || @view_context.render(@metadata_component.new(fields: presenter.field_presenters, show: show?))
end

# Content that goes before the document title (e.g. the counter)
def before_title
@before_title || counter
end

private

def counter
return unless @counter

content_tag :span, class: 'document-counter' do
t('blacklight.search.documents.counter', counter: @counter)
end
end

def presenter
@presenter ||= begin
if show?
@view_context.show_presenter(@document)
else
@view_context.index_presenter(@document)
end
end
end

def show?
@show
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<dl class="document-metadata dl-invert row">
<% @fields.each do |field| -%>
<%= @view_context.render(field_component(field).new(field: field, show: @show)) %>
<% end -%>
</dl>
21 changes: 21 additions & 0 deletions app/components/blacklight/document_metadata_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Blacklight
class DocumentMetadataComponent < ::ViewComponent::Base
with_collection_parameter :fields

# @param fields [Enumerable<Blacklight::FieldPresenter>] Document field presenters
def initialize(fields:, show: false)
@fields = fields
@show = show
end

def render?
@fields.any?
end

def field_component(field)
field.try(:component) || Blacklight::MetadataFieldComponent
end
end
end
8 changes: 8 additions & 0 deletions app/components/blacklight/metadata_field_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<%= render(@layout.new(field: @field)) do |component| %>
<% component.with(:label) do %>
<%= label %>
<% end %>
<% component.with(:value) do %>
<%= @field.render %>
<% end %>
<% end %>
31 changes: 31 additions & 0 deletions app/components/blacklight/metadata_field_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module Blacklight
class MetadataFieldComponent < ::ViewComponent::Base
with_collection_parameter :field

# @param field [Blacklight::FieldPresenter]
# @param layout [Blacklight::MetadataFieldLayoutComponent] alternate layout component to use
# @param show [Boolean] are we showing only a single document (vs a list of search results); used for backwards-compatibility
def initialize(field:, layout: nil, show: false)
@field = field
@layout = layout || Blacklight::MetadataFieldLayoutComponent
@show = show
end

# @private
def label
Deprecation.silence(Blacklight::BlacklightHelperBehavior) do
if @show
@view_context.render_document_show_field_label @field.document, label: @field.label, field: @field.key
else
@view_context.render_index_field_label @field.document, label: @field.label, field: @field.key
end
end
end

def render?
@field.render_field?
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<dt class="blacklight-<%= @key %> <%= @label_class %>"><%= label %></dt>
<dd class="blacklight-<%= @key %> <%= @value_class %>"><%= value %></dd>
16 changes: 16 additions & 0 deletions app/components/blacklight/metadata_field_layout_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module Blacklight
class MetadataFieldLayoutComponent < ::ViewComponent::Base
with_collection_parameter :field
with_content_areas :label, :value

# @param field [Blacklight::FieldPresenter]
def initialize(field:, label_class: 'col-md-3', value_class: 'col-md-9')
@field = field
@key = @field.key.parameterize
@label_class = label_class
@value_class = value_class
end
end
end
14 changes: 11 additions & 3 deletions app/helpers/blacklight/blacklight_helper_behavior.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true
# Methods added to this helper will be available to all templates in the hosting application
module Blacklight::BlacklightHelperBehavior
extend Deprecation

include Blacklight::UrlHelperBehavior
include Blacklight::HashAsHiddenFieldsHelperBehavior
include Blacklight::LayoutHelperBehavior
Expand Down Expand Up @@ -148,9 +150,12 @@ def render_index_field_label *args
document = args.first

field = options[:field]
label = options[:label] || index_field_label(document, field)
label = Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
options[:label] || index_field_label(document, field)
end
html_escape t(:"blacklight.search.index.#{document_index_view_type}.label", default: :'blacklight.search.index.label', label: label)
end
deprecation_deprecate render_index_field_label: 'Use Blacklight::MetadataFieldComponent instead'

##
# Render the show field label for a document
Expand All @@ -170,10 +175,13 @@ def render_document_show_field_label *args
document = args.first

field = options[:field]
label = options[:label] || document_show_field_label(document, field)
label = Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
options[:label] || document_show_field_label(document, field)
end

t(:'blacklight.search.show.label', label: label)
end
deprecation_deprecate render_document_show_field_label: 'Use Blacklight::MetadataFieldComponent instead'

##
# Get the value of the document's "title" field, or a placeholder
Expand Down Expand Up @@ -253,7 +261,7 @@ def with_format(format)
# Should we render a grouped response (because the response
# contains a grouped response instead of the normal response)
def render_grouped_response? response = @response
response.grouped?
response&.grouped?
end

##
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/blacklight/configuration_helper_behavior.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true
module Blacklight::ConfigurationHelperBehavior
extend Deprecation

##
# Index fields to display for a type of document
#
Expand Down Expand Up @@ -60,6 +62,7 @@ def index_field_label document, field

field_config.display_label('index')
end
deprecation_deprecate :index_field_label

##
# Look up the label for the show field
Expand All @@ -69,6 +72,7 @@ def document_show_field_label document, field

field_config.display_label('show')
end
deprecation_deprecate :document_show_field_label

##
# Look up the label for the facet field
Expand Down
10 changes: 9 additions & 1 deletion app/presenters/blacklight/document_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ def fields_to_render
end
end

def field_presenters
return to_enum(:field_presenters) unless block_given?

fields_to_render.each { |_, _, config| yield config }
end

##
# Get the value of the document's "title" field, or a placeholder
# value (if empty)
Expand Down Expand Up @@ -63,7 +69,7 @@ def display_type(base_name = nil, default: nil)
# @param [Hash] options
# @option options [String] :value
def field_value field_config, options = {}
field_presenter(field_config, options).render
field_presenter(field_config, options)&.render
end

def thumbnail
Expand Down Expand Up @@ -93,6 +99,8 @@ def retrieve_values(field_config)
deprecation_deprecate retrieve_values: 'Use FieldPresenter#values'

def field_presenter(field_config, options = {})
return unless field_config

presenter_class = field_config.presenter || Blacklight::FieldPresenter
presenter_class.new(view_context, document, field_config, options)
end
Expand Down
1 change: 1 addition & 0 deletions app/presenters/blacklight/field_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def initialize(view_context, document, field_config, options = {})
end

attr_reader :view_context, :document, :field_config, :except_operations, :options
delegate :key, to: :field_config

def render
Rendering::Pipeline.new(values, field_config, document, view_context, pipeline_steps, options).render
Expand Down
10 changes: 5 additions & 5 deletions app/views/catalog/_document.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<% # container for a single doc -%>
<article class="document <%= render_document_class document %> document-position-<%= document_counter%> " data-document-counter="<%= document_counter %>" itemscope itemtype="<%= document.itemtype %>">
<%= render_document_partials document,
blacklight_config.view_config(document_index_view_type).partials,
document_counter: document_counter %>
</article>
<%= render (blacklight_config.view_config(document_index_view_type).document_component || Blacklight::DocumentComponent).new(document: document, counter: document_counter_with_offset(document_counter)) do |component| %>
<% component.with(blacklight_config.view_config(document_index_view_type).document_component.blank? && blacklight_config.view_config(document_index_view_type).partials.any? ? :body : :partials) do %>
<%= render_document_partials document, blacklight_config.view_config(document_index_view_type).partials, component: component, document_counter: document_counter %>
<% end %>
<% end %>
11 changes: 1 addition & 10 deletions app/views/catalog/_index.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
<% doc_presenter = index_presenter(document) %>
<%# default partial to display solr document fields in catalog index view -%>
<dl class="document-metadata dl-invert row">

<% doc_presenter.fields_to_render.each do |field_name, field, field_presenter| -%>
<dt class="blacklight-<%= field_name.parameterize %> col-md-3"><%= render_index_field_label document, label: field_presenter.label, field: field_name %></dt>
<dd class="blacklight-<%= field_name.parameterize %> col-md-9"><%= field_presenter.render %></dd>
<% end -%>

</dl>
<%= render(Blacklight::DocumentMetadataComponent.new(fields: index_presenter(document).field_presenters)) %>
14 changes: 6 additions & 8 deletions app/views/catalog/_show.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<% doc_presenter = show_presenter(document) %>
<%# default partial to display solr document fields in catalog show view -%>
<dl class="row dl-invert document-metadata">
<% doc_presenter.fields_to_render.each do |field_name, field, field_presenter| -%>
<dt class="blacklight-<%= field_name.parameterize %> col-md-3"><%= render_document_show_field_label document, label: field_presenter.label, field: field_name %></dt>
<dd class="blacklight-<%= field_name.parameterize %> col-md-9"><%= field_presenter.render %></dd>
<% end -%>
</dl>
<%= render(
Blacklight::DocumentMetadataComponent.new(
fields: show_presenter(document).field_presenters,
show: true
)
) %>
Loading

0 comments on commit ed83514

Please sign in to comment.