diff --git a/lib/blacklight/configuration.rb b/lib/blacklight/configuration.rb index 6fb8a1f34..e8a81b8af 100644 --- a/lib/blacklight/configuration.rb +++ b/lib/blacklight/configuration.rb @@ -142,29 +142,35 @@ def initialized_default_configuration? # set to nil if a checkbox is prefered to the icon property :bookmark_icon_component, default: Blacklight::Icons::BookmarkIconComponent - # @!attribute index - # General configuration for all views + # @!attribute defaults + # Default configuration for all views # @return [Blacklight::Configuration::ViewConfig::Index] - property :index, default: ViewConfig::Index.new( + property :defaults, default: ViewConfig.new( # document presenter class used by helpers and views document_presenter_class: Blacklight::IndexPresenter, - # document presenter used for json responses - json_presenter_class: Blacklight::JsonPresenter, # component class used to render a document document_component: Blacklight::DocumentComponent, document_embed_component: nil, document_metadata_component: Blacklight::DocumentMetadataComponent, document_thumbnail_component: Blacklight::Document::ThumbnailComponent, document_title_component: Blacklight::DocumentTitleComponent, - sidebar_component: Blacklight::Search::SidebarComponent, - dropdown_component: Blacklight::System::DropdownComponent, # solr field to use to render a document title title_field: nil, # solr field to use to render format-specific partials - display_type_field: nil, + display_type_field: nil + ) + + # @!attribute index + # General configuration for search views + # @return [Blacklight::Configuration::ViewConfig::Index] + property :index, default: ViewConfig::Index.new( + document_actions: NestedOpenStructWithHashAccess.new(ToolConfig), + # document presenter used for json responses + json_presenter_class: Blacklight::JsonPresenter, + sidebar_component: Blacklight::Search::SidebarComponent, + dropdown_component: Blacklight::System::DropdownComponent, # the "field access" key to use to look up the document display fields document_fields_key: :index_fields, - document_actions: NestedOpenStructWithHashAccess.new(ToolConfig), collection_actions: NestedOpenStructWithHashAccess.new(ToolConfig), # what field, if any, to use to render grouped results group: false, @@ -192,7 +198,7 @@ def initialized_default_configuration? property :show, default: ViewConfig::Show.new( # document presenter class used by helpers and views document_presenter_class: Blacklight::ShowPresenter, - document_component: Blacklight::DocumentComponent, + document_actions: NestedOpenStructWithHashAccess.new(ToolConfig), document_thumbnail_component: nil, show_tools_component: Blacklight::Document::ShowToolsComponent, show_header_tools_component: nil, @@ -205,20 +211,19 @@ def initialized_default_configuration? # Set this to a hash with additional arguments to merge into the route, # or set `controller: :current` to route to the current controller. route: nil, - document_actions: NestedOpenStructWithHashAccess.new(ToolConfig), header_actions: NestedOpenStructWithHashAccess.new(ToolConfig) ) # @!attribute action_mapping # @since v7.16.0 - # @return [Hash{Symbol => Blacklight::Configuration::ViewConfig}] + # @return [Hash{Symbol => Blacklight::Configuration::ActionConfigMapEntry}] property :action_mapping, default: NestedOpenStructWithHashAccess.new( - ViewConfig, - default: { top_level_config: :index }, - show: { top_level_config: :show }, - citation: { parent_config: :show }, - email_record: { top_level_config: :email }, - sms_record: { top_level_config: :sms } + ActionConfigMapEntry, + default: { blacklight_config_property: :index, default: [:index, :defaults] }, + show: { blacklight_config_property: :show }, + citation: { parent_action_key: :show }, + email_record: { blacklight_config_property: :email }, + sms_record: { blacklight_config_property: :sms } ) # @!attribute sms @@ -528,12 +533,7 @@ def view_config(view_type = nil, action_name: :index) view_type = nil end - @view_config[[view_type, action_name]] ||= if view_type.nil? - action_config(action_name) - else - base_config = action_config(action_name) - base_config.merge(view.fetch(view_type, {})) - end + @view_config[[view_type, action_name]] ||= action_config(action_name, (view.fetch(view_type, nil) if view_type)) end # YARD will include inline disabling as docs, cannot do multiline inside @!macro. AND this must be separate from doc block. @@ -646,8 +646,8 @@ def _deep_copy(value) end end - def action_config(action, default: :index) - action_config = action_mapping[action] + def action_config(action_name, view_type_specific_config, default: :index) + action_config = action_mapping[action_name] action_config ||= action_mapping[:default] if action_config.parent_config && action_config.parent_config != :default @@ -658,9 +658,19 @@ def action_config(action, default: :index) end action_config = action_config.reverse_merge(action_mapping[:default]) if action_config != action_mapping[:default] - action_config = action_config.reverse_merge(self[action_config.top_level_config]) if action_config.top_level_config - action_config = action_config.reverse_merge(show) if default == :show && action_config.top_level_config != :show - action_config.reverse_merge(index) + view_config = if action_config.blacklight_config_property + self[action_config.blacklight_config_property] + else + self[default] + end + + view_config = Array(action_config.default - [action_config.blacklight_config_property || default]).inject(view_config) do |config, top_level_config| + config.reverse_merge(self[top_level_config]) + end + + view_config = view_config.merge(view_type_specific_config) if view_type_specific_config + + view_config end end end diff --git a/lib/blacklight/configuration/action_config_map_entry.rb b/lib/blacklight/configuration/action_config_map_entry.rb new file mode 100644 index 000000000..94955583c --- /dev/null +++ b/lib/blacklight/configuration/action_config_map_entry.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Blacklight + class Configuration::ActionConfigMapEntry < OpenStructWithHashAccess + # @!attribute parent_action_key + # Pull in the configuration for this action from another action's config + # @return [Symbol] + + def parent_config = parent_action_key + + def parent_config=(value) + self.parent_action_key = value + end + + # + # @!attribute blacklight_config_property + # Pull in the configuration for this action from a top-level config + # @return [Symbol] + + def top_level_config = blacklight_config_property + + def top_level_config=(value) + self.blacklight_config_property = value + end + + # + # @!attribute default + # Pull in additional default configuration for this action from a top-level config + # @return [Array] + end +end diff --git a/spec/models/blacklight/configuration_spec.rb b/spec/models/blacklight/configuration_spec.rb index c5f5c4104..e0dae4b44 100644 --- a/spec/models/blacklight/configuration_spec.rb +++ b/spec/models/blacklight/configuration_spec.rb @@ -670,25 +670,6 @@ expect(config.view_config(action_name: :show)).to have_attributes config.show.to_h end - it 'includes the default action mapping configuration' do - config.action_mapping.default.whatever = :some_value - - expect(config.view_config(action_name: :show)).to have_attributes whatever: :some_value - end - - it 'includes the action-specific mappings' do - config.action_mapping.foo.document_presenter_class = Blacklight::DocumentPresenter - - expect(config.view_config(action_name: :foo)).to have_attributes config.action_mapping.foo.to_h - end - - it 'allows the action mapping to specific a parent configuration with some more defaults' do - config.action_mapping.foo.parent_config = :bar - config.action_mapping.bar.whatever = :bar_value - - expect(config.view_config(action_name: :foo)).to have_attributes whatever: :bar_value - end - context 'with the :citation action' do it 'also includes the show config' do expect(config.view_config(action_name: :citation)).to have_attributes config.show.to_h diff --git a/spec/views/catalog/_document.html.erb_spec.rb b/spec/views/catalog/_document.html.erb_spec.rb index 29584ce79..9f8a55f0c 100644 --- a/spec/views/catalog/_document.html.erb_spec.rb +++ b/spec/views/catalog/_document.html.erb_spec.rb @@ -16,7 +16,7 @@ stub_template "catalog/_a_default.html.erb" => "a_partial" stub_template "catalog/_b_default.html.erb" => "b_partial" stub_template "catalog/_c_default.html.erb" => "c_partial" - render partial: "catalog/document", locals: { document: document, document_counter: 1, view_config: blacklight_config.index } + render partial: "catalog/document", locals: { document: document, document_counter: 1, view_config: blacklight_config.view_config(:index) } expect(rendered).to match /a_partial/ expect(rendered).to match /b_partial/ expect(rendered).to match /c_partial/ @@ -38,7 +38,7 @@ def call end it 'renders the document component' do - render partial: "catalog/document", locals: { document: document, document_counter: 1, view_config: blacklight_config.index } + render partial: "catalog/document", locals: { document: document, document_counter: 1, view_config: blacklight_config.view_config(:index) } expect(rendered).to match /blah/ end end