diff --git a/app/components/blacklight/document_component.html.erb b/app/components/blacklight/document_component.html.erb index cd9bcd6d8..301c75435 100644 --- a/app/components/blacklight/document_component.html.erb +++ b/app/components/blacklight/document_component.html.erb @@ -8,14 +8,20 @@ itemtype: document.itemtype, class: classes.flatten.join(' ') do %> <%= header %> + <% header_components.each do |component| %> + <%= render component.new(presenter: @presenter, counter: @counter, document_counter: @document_counter) %> + <% end %> + <% if body.present? %> <%= body %> <% else %>
<%= title %> - <%= embed %> - <%= content %> - <%= metadata %> + + <% section_components.each do |section| %> + <%= section %> + <% end %> + <% metadata_sections.each do |section| %> <%= section %> <% end %> @@ -27,5 +33,10 @@ <%= thumbnail %> <% end %> + + <% footer_components.each do |component| %> + <%= render component.new(presenter: @presenter, counter: @counter, document_counter: @document_counter) %> + <% end %> + <%= footer %> <% end %> diff --git a/app/components/blacklight/document_component.rb b/app/components/blacklight/document_component.rb index e6199ceb3..4896a8c02 100644 --- a/app/components/blacklight/document_component.rb +++ b/app/components/blacklight/document_component.rb @@ -127,6 +127,27 @@ def before_render end end + def header_components + view_config.document_header_components + end + + def section_components + return to_enum(:section_components) unless block_given? + + view_config.document_section_components&.each do |component_or_key| + case component_or_key + when Symbol, String + yield public_send(component_or_key) + when Class + yield render component_or_key.new(presenter: @presenter, counter: @counter, document_counter: @document_counter) + end + end + end + + def footer_components + view_config.document_footer_components + end + private delegate :view_config, to: :@presenter diff --git a/lib/blacklight/configuration.rb b/lib/blacklight/configuration.rb index 6fb8a1f34..5c9ac5765 100644 --- a/lib/blacklight/configuration.rb +++ b/lib/blacklight/configuration.rb @@ -156,6 +156,9 @@ def initialized_default_configuration? document_metadata_component: Blacklight::DocumentMetadataComponent, document_thumbnail_component: Blacklight::Document::ThumbnailComponent, document_title_component: Blacklight::DocumentTitleComponent, + document_header_components: [], + document_section_components: [:embed, :content, :metadata], + document_footer_components: [], sidebar_component: Blacklight::Search::SidebarComponent, dropdown_component: Blacklight::System::DropdownComponent, # solr field to use to render a document title diff --git a/lib/blacklight/configuration/view_config.rb b/lib/blacklight/configuration/view_config.rb index 7560c7b7f..258b15d33 100644 --- a/lib/blacklight/configuration/view_config.rb +++ b/lib/blacklight/configuration/view_config.rb @@ -8,6 +8,12 @@ class ViewConfig < Blacklight::OpenStructWithHashAccess # @return [Class] document presenter class used by helpers and views # @!attribute document_component # @return [Class] component class used to render a document; defaults to Blacklight::DocumentComponent + # @!attribute document_header_components + # @return [Array] component classes that render above the main document section + # @!attribute document_section_components + # @return [Array] component classes (or slot names) that render the main document section below the title + # @!attribute document_footer_components + # @return [Array] component classes that render below the main document section # @!attribute document_title_component # @return [Class] component class used to render a document title # @!attribute document_metadata_component diff --git a/spec/components/blacklight/document_component_spec.rb b/spec/components/blacklight/document_component_spec.rb index accb9f85f..09182d92a 100644 --- a/spec/components/blacklight/document_component_spec.rb +++ b/spec/components/blacklight/document_component_spec.rb @@ -269,4 +269,32 @@ def call expect(page).to have_content "Prefix!" end end + + context 'with configured components' do + let(:static_component) do + lambda { |text| + inline = Class.new(ViewComponent::Base) do + class_attribute :text + def self.name = 'StaticComponent' + def initialize(**); end + + def call + text + end + end + + inline.tap { |klass| klass.text = text } + } + end + + it 'renders header, section, and footer components' do + blacklight_config.index.document_header_components = [static_component.call('Header')] + blacklight_config.index.document_section_components = [static_component.call('Section')] + blacklight_config.index.document_footer_components = [static_component.call('Footer')] + + render_inline component + puts page.native.inner_html + expect(page).to have_content('Header').and have_content('Section').and have_content('Footer') + end + end end