blacklight 7.33.1 → 7.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -0
  3. data/.github/workflows/ruby.yml +21 -1
  4. data/.rubocop.yml +2 -0
  5. data/Gemfile +4 -0
  6. data/VERSION +1 -1
  7. data/app/components/blacklight/advanced_search_form_component.html.erb +1 -1
  8. data/app/components/blacklight/advanced_search_form_component.rb +5 -5
  9. data/app/components/blacklight/content_areas_shim.rb +1 -1
  10. data/app/components/blacklight/document/action_component.html.erb +2 -9
  11. data/app/components/blacklight/document/action_component.rb +18 -0
  12. data/app/components/blacklight/document/actions_component.rb +1 -1
  13. data/app/components/blacklight/document_component.rb +33 -10
  14. data/app/components/blacklight/document_metadata_component.html.erb +4 -2
  15. data/app/components/blacklight/document_metadata_component.rb +6 -2
  16. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +2 -2
  17. data/app/components/blacklight/facet_field_list_component.html.erb +2 -2
  18. data/app/components/blacklight/header_component.html.erb +2 -0
  19. data/app/components/blacklight/header_component.rb +26 -0
  20. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  21. data/app/components/blacklight/metadata_field_layout_component.rb +7 -4
  22. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  23. data/app/components/blacklight/response/pagination_component.rb +5 -1
  24. data/app/components/blacklight/response/view_type_component.rb +1 -1
  25. data/app/components/blacklight/search_navbar_component.html.erb +5 -0
  26. data/app/components/blacklight/search_navbar_component.rb +34 -0
  27. data/app/components/blacklight/system/dropdown_component.rb +2 -2
  28. data/app/components/blacklight/system/flash_message_component.rb +1 -1
  29. data/app/components/blacklight/top_navbar_component.html.erb +12 -0
  30. data/app/components/blacklight/top_navbar_component.rb +17 -0
  31. data/app/controllers/concerns/blacklight/base.rb +5 -0
  32. data/app/controllers/concerns/blacklight/catalog.rb +4 -1
  33. data/app/controllers/concerns/blacklight/controller.rb +3 -2
  34. data/app/helpers/blacklight/blacklight_helper_behavior.rb +2 -2
  35. data/app/helpers/blacklight/render_partials_helper_behavior.rb +1 -0
  36. data/app/models/concerns/blacklight/document/attributes.rb +50 -0
  37. data/app/models/concerns/blacklight/document.rb +12 -20
  38. data/app/presenters/blacklight/rendering/join.rb +1 -1
  39. data/app/values/blacklight/types.rb +99 -11
  40. data/app/views/catalog/_document.html.erb +1 -1
  41. data/app/views/catalog/_facet_layout.html.erb +2 -2
  42. data/app/views/catalog/_search_form.html.erb +1 -1
  43. data/app/views/catalog/_show_main_content.html.erb +2 -2
  44. data/app/views/catalog/_show_sidebar.html.erb +1 -1
  45. data/app/views/catalog/_show_tools.html.erb +4 -3
  46. data/app/views/catalog/facet.html.erb +3 -3
  47. data/app/views/layouts/blacklight/base.html.erb +7 -7
  48. data/app/views/shared/_header_navbar.html.erb +1 -22
  49. data/blacklight.gemspec +1 -2
  50. data/config/locales/blacklight.en.yml +1 -0
  51. data/docker-compose.yml +1 -0
  52. data/lib/blacklight/configuration.rb +39 -2
  53. data/lib/blacklight/engine.rb +4 -0
  54. data/lib/blacklight/solr/repository.rb +14 -2
  55. data/lib/blacklight/solr/request.rb +2 -0
  56. data/lib/blacklight/solr/search_builder_behavior.rb +2 -1
  57. data/lib/blacklight.rb +1 -1
  58. data/lib/generators/blacklight/assets_generator.rb +1 -1
  59. data/lib/generators/blacklight/install_generator.rb +1 -1
  60. data/lib/generators/blacklight/templates/catalog_controller.rb +4 -0
  61. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +69 -0
  62. data/lib/generators/blacklight/templates/solr_document.rb +1 -1
  63. data/lib/railties/blacklight.rake +4 -4
  64. data/package.json +1 -1
  65. data/spec/components/blacklight/document_component_spec.rb +60 -11
  66. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +3 -2
  67. data/spec/components/blacklight/header_component_spec.rb +20 -0
  68. data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
  69. data/spec/controllers/blacklight/base_spec.rb +1 -1
  70. data/spec/features/advanced_search_spec.rb +56 -0
  71. data/spec/features/axe_spec.rb +5 -0
  72. data/spec/features/sitelinks_search_box_spec.rb +13 -0
  73. data/spec/helpers/blacklight/search_history_constraints_helper_behavior_spec.rb +8 -15
  74. data/spec/models/blacklight/configuration_spec.rb +22 -0
  75. data/spec/models/blacklight/solr/repository_spec.rb +27 -0
  76. data/spec/models/blacklight/solr/search_builder_spec.rb +16 -0
  77. data/spec/models/solr_document_spec.rb +21 -3
  78. data/spec/presenters/blacklight/show_presenter_spec.rb +4 -10
  79. data/spec/spec_helper.rb +4 -5
  80. data/spec/support/view_component_test_helpers.rb +35 -0
  81. data/spec/views/catalog/_show_tools.html.erb_spec.rb +24 -10
  82. metadata +24 -23
  83. data/spec/features/sitelinks_search_box.rb +0 -13
  84. data/spec/support/view_component_capybara_test_helpers.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd9f780cd93deb22275984f9441e19bbffba7c3b07ba1173bd092786cd68bcef
4
- data.tar.gz: 320dc37ac26ba35cbb9d4916babb45187f1a93203561cc1bcb214d6e1ebb181e
3
+ metadata.gz: 65ccb9085e62a93389eab98519e5cb673b61d8fc3c6e973a2810e4ac66a87cf1
4
+ data.tar.gz: 56e423a036a4e82382f6bda36084b79758c966ccc8757dfe004deb26963ee400
5
5
  SHA512:
6
- metadata.gz: 11ab615553f94bbdb382865dc4cd9dc757b9895de17976a8a8e9294987e25ef54d8b1e5d3f744690984508d5f6375cb823b21b78411f9b87c0ab5fe90dde6bec
7
- data.tar.gz: afab5ae2f8e18deaf6935abb4160a326849cc4234bc9ac9cd21f757395493b7d698c908541f960ee8a17a3beb4c5e48b71f675c578426736f6055e57659c9709
6
+ metadata.gz: 49ebde9d47e594d7ddeaaf893f2a9a99c4162592065800d8c4d5b3f84b7e08d2c95a57f47f20a079b0ba8bfc36e6c83fc31e96aa4587695db913a40194999a42
7
+ data.tar.gz: 94a1cfe6e885d009a1117a7bede81a4db4f8215cd8b3f37b2d38fa89da17e239478556809f2265fb9a47761644da5c0ef6487042276655151b9372b0919664f8
data/.env CHANGED
@@ -1,5 +1,6 @@
1
1
  ALPINE_RUBY_VERSION=2.7.5
2
2
  RAILS_VERSION=5.2.6
3
+ VIEW_COMPONENT_VERSION=2.6.6
3
4
  SOLR_PORT=8983
4
5
  SOLR_URL=http://solr:8983/solr/blacklight-core
5
6
  SOLR_VERSION=latest
@@ -32,7 +32,7 @@ jobs:
32
32
  runs-on: ubuntu-latest
33
33
  strategy:
34
34
  matrix:
35
- ruby: [2.7, '3.0', 3.1]
35
+ ruby: [2.7, '3.0', 3.1, 3.2]
36
36
  steps:
37
37
  - uses: actions/checkout@v2
38
38
  - name: Set up Ruby
@@ -129,6 +129,26 @@ jobs:
129
129
  env:
130
130
  RAILS_VERSION: 6.1.6.1
131
131
  ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-keeps --skip-action-cable --skip-test'
132
+ test_vc3:
133
+ runs-on: ubuntu-latest
134
+ strategy:
135
+ matrix:
136
+ ruby: ['3.2']
137
+ env:
138
+ VIEW_COMPONENT_VERSION: ${{ matrix.view_component_version }}
139
+ steps:
140
+ - uses: actions/checkout@v2
141
+ - name: Set up Ruby
142
+ uses: ruby/setup-ruby@v1
143
+ with:
144
+ ruby-version: ${{ matrix.ruby }}
145
+ bundler: 'latest'
146
+ - name: Install dependencies
147
+ run: bundle install
148
+ - name: Run tests
149
+ run: bundle exec rake ci
150
+ env:
151
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
132
152
  api_test:
133
153
  runs-on: ubuntu-latest
134
154
  strategy:
data/.rubocop.yml CHANGED
@@ -63,6 +63,8 @@ Naming/MethodParameterName:
63
63
  - id
64
64
  - q
65
65
  - as
66
+ - of
67
+ - by
66
68
 
67
69
  Naming/PredicateName:
68
70
  ForbiddenPrefixes:
data/Gemfile CHANGED
@@ -33,6 +33,10 @@ else
33
33
  end
34
34
  end
35
35
 
36
+ unless ENV['VIEW_COMPONENT_VERSION'].to_s == ""
37
+ gem 'view_component', ENV.fetch('VIEW_COMPONENT_VERSION')
38
+ end
39
+
36
40
  case ENV['RAILS_VERSION']
37
41
  when /^6.0/
38
42
  gem 'sass-rails', '>= 6'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.33.1
1
+ 7.34.0
@@ -40,7 +40,7 @@
40
40
 
41
41
  <% if sort_fields_select %>
42
42
  <div class="form-group row mb-4">
43
- <%= content_tag :h2, t('blacklight.advanced_search.form.sort_label'), class: 'col-md-3 col-form-label text-md-right' %>
43
+ <%= content_tag :h2, t('blacklight.advanced_search.form.sort_label'), id: 'advanced-search-sort-label', class: 'col-md-3 col-form-label text-md-right' %>
44
44
  <div class="col">
45
45
  <%= sort_fields_select %>
46
46
  </div>
@@ -26,21 +26,21 @@ module Blacklight
26
26
 
27
27
  def default_operator_menu
28
28
  options_with_labels = [:must, :should].index_by { |op| t(op, scope: 'blacklight.advanced_search.op') }
29
- select_tag(:op, options_for_select(options_with_labels, params[:op]), class: 'input-small')
29
+ label_tag(:op, t('blacklight.advanced_search.op.label'), class: 'sr-only visually-hidden') + select_tag(:op, options_for_select(options_with_labels, params[:op]), class: 'input-small')
30
30
  end
31
31
 
32
32
  def sort_fields_select
33
33
  options = sort_fields.values.map { |field_config| [helpers.sort_field_label(field_config.key), field_config.key] }
34
34
  return unless options.any?
35
35
 
36
- select_tag(:sort, options_for_select(options, params[:sort]), class: "form-control sort-select w-auto")
36
+ select_tag(:sort, options_for_select(options, params[:sort]), class: "form-control sort-select w-auto", aria: { labelledby: 'advanced-search-sort-label' })
37
37
  end
38
38
 
39
39
  private
40
40
 
41
41
  def initialize_search_field_controls
42
42
  search_fields.values.each.with_index do |field, i|
43
- search_field_control do
43
+ with_search_field_control do
44
44
  fields_for('clause[]', i, include_id: false) do |f|
45
45
  content_tag(:div, class: 'form-group advanced-search-field row') do
46
46
  f.label(:query, field.display_label('search'), class: "col-sm-3 col-form-label text-md-right") +
@@ -59,7 +59,7 @@ module Blacklight
59
59
 
60
60
  fields.each do |_k, config|
61
61
  display_facet = @response.aggregations[config.field]
62
- search_filter_control(config: config, display_facet: display_facet)
62
+ with_search_filter_control(config: config, display_facet: display_facet)
63
63
  end
64
64
  end
65
65
 
@@ -72,7 +72,7 @@ module Blacklight
72
72
 
73
73
  return if constraints_text.blank?
74
74
 
75
- constraint do
75
+ with_constraint do
76
76
  constraints_text
77
77
  end
78
78
  end
@@ -7,7 +7,7 @@ module Blacklight
7
7
  def with(slot_name, *args, **kwargs, &block)
8
8
  Deprecation.warn(Blacklight::ContentAreasShim,
9
9
  'ViewComponents deprecated `with` and it will be removed in ViewComponents 3.0. content_areas. Use slots (https://viewcomponent.org/guide/slots.html) instead.')
10
- public_send(slot_name, *args, **kwargs, &block)
10
+ public_send("with_#{slot_name}", *args, **kwargs, &block)
11
11
  end
12
12
  end
13
13
  end
@@ -1,9 +1,2 @@
1
- <% if using_default_document_action? %>
2
- <%= link_to label,
3
- url,
4
- id: @id,
5
- class: @link_classes,
6
- data: {}.merge(({ blacklight_modal: "trigger", turbo: false } if @action.modal != false) || {}) %>
7
- <% else %>
8
- <%= helpers.render(partial: @action.partial || @action.name.to_s, locals: { document: @document, document_action_config: @action }.merge(@options)) %>
9
- <% end %>
1
+ <%# We keep this template around so that downstream applications can override the template if desired %>
2
+ <%= render_control %>
@@ -16,6 +16,12 @@ module Blacklight
16
16
  @link_classes = link_classes
17
17
  end
18
18
 
19
+ def render_control
20
+ return link_to_modal_control if using_default_document_action?
21
+
22
+ render_partial
23
+ end
24
+
19
25
  def using_default_document_action?
20
26
  return true if @action.component
21
27
  return false unless @action.partial == 'document_action'
@@ -23,6 +29,18 @@ module Blacklight
23
29
  helpers.partial_from_blacklight?(@action.partial)
24
30
  end
25
31
 
32
+ def link_to_modal_control
33
+ link_to label,
34
+ url,
35
+ id: @id,
36
+ class: @link_classes,
37
+ data: {}.merge(({ blacklight_modal: "trigger", turbo: false } if @action.modal != false) || {})
38
+ end
39
+
40
+ def render_partial
41
+ helpers.render(partial: @action.partial || @action.name.to_s, locals: { document: @document, document_action_config: @action }.merge(@options))
42
+ end
43
+
26
44
  def label
27
45
  Deprecation.silence(Blacklight::ComponentHelperBehavior) do
28
46
  helpers.document_action_label(@action.name, @action)
@@ -28,7 +28,7 @@ module Blacklight
28
28
  return if actions.present?
29
29
 
30
30
  @actions.each do |a|
31
- action(component: a.component, action: a)
31
+ with_action(component: a.component, action: a)
32
32
  end
33
33
  end
34
34
 
@@ -1,9 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'view_component/version'
4
+
3
5
  module Blacklight
6
+ ##
7
+ # A component for rendering a single document
8
+ #
9
+ # @note when subclassing this component, if you override the initializer,
10
+ # you must explicitly specify the counter variable `document_counter` even if you don't use it.
11
+ # Otherwise view_component will not provide the count value when calling the component.
12
+ #
13
+ # @see https://viewcomponent.org/guide/collections.html#collection-counter
14
+ #
15
+ # @example
16
+ # class MyDocumentComponent < Blacklight::DocumentComponent
17
+ # def initialize(document_counter: nil, **kwargs)
18
+ # super
19
+ # ... custom code ...
20
+ # end
21
+ # end
4
22
  class DocumentComponent < Blacklight::Component
5
23
  include Blacklight::ContentAreasShim
6
24
 
25
+ with_collection_parameter :document
26
+
27
+ # ViewComponent 3 changes iteration counters to begin at 0 rather than 1
28
+ COLLECTION_INDEX_OFFSET = ViewComponent::VERSION::MAJOR < 3 ? 0 : 1
29
+
7
30
  # Content appearing before the document
8
31
  renders_one :header
9
32
 
@@ -16,7 +39,7 @@ module Blacklight
16
39
 
17
40
  # The document title with some reasonable default behavior
18
41
  renders_one :title, (lambda do |*args, component: nil, **kwargs|
19
- component ||= Blacklight::DocumentTitleComponent
42
+ component ||= @presenter&.view_config&.title_component || Blacklight::DocumentTitleComponent
20
43
 
21
44
  component.new(*args, counter: @counter, document: @document, presenter: @presenter, as: @title_component, link_to_document: !@show, document_component: self, **kwargs)
22
45
  end)
@@ -36,7 +59,7 @@ module Blacklight
36
59
 
37
60
  Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if !fields && @presenter.nil?
38
61
 
39
- component ||= Blacklight::DocumentMetadataComponent
62
+ component ||= presenter&.view_config&.metadata_component || Blacklight::DocumentMetadataComponent
40
63
 
41
64
  component.new(*args, fields: fields || @presenter&.field_presenters || [], **kwargs)
42
65
  end)
@@ -47,7 +70,7 @@ module Blacklight
47
70
  renders_one :thumbnail, (lambda do |image_options_or_static_content = {}, *args, component: nil, **kwargs|
48
71
  next image_options_or_static_content if image_options_or_static_content.is_a? String
49
72
 
50
- component ||= @presenter&.view_config&.thumbnail_component || Blacklight::Document::ThumbnailComponent
73
+ component ||= presenter&.view_config&.thumbnail_component || Blacklight::Document::ThumbnailComponent
51
74
  Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if !component && @presenter.nil?
52
75
 
53
76
  component.new(*args, document: @document, presenter: @presenter, counter: @counter, image_options: image_options_or_static_content, **kwargs)
@@ -79,12 +102,12 @@ module Blacklight
79
102
  embed_component: nil,
80
103
  thumbnail_component: nil,
81
104
  counter: nil, document_counter: nil, counter_offset: 0,
82
- show: false)
105
+ show: false, **args)
83
106
  if presenter.nil? && document.nil?
84
107
  raise ArgumentError, 'missing keyword: :document or :presenter'
85
108
  end
86
109
 
87
- @document = document || presenter&.document
110
+ @document = document || presenter&.document || args[self.class.collection_parameter]
88
111
  @presenter = presenter
89
112
 
90
113
  @component = component
@@ -96,14 +119,14 @@ module Blacklight
96
119
  @embed_component = embed_component
97
120
 
98
121
  Deprecation.warn(Blacklight::DocumentComponent, 'Passing metadata_component is deprecated') if @metadata_component.present?
99
- @metadata_component = metadata_component || Blacklight::DocumentMetadataComponent
122
+ @metadata_component = metadata_component
100
123
 
101
124
  Deprecation.warn(Blacklight::DocumentComponent, 'Passing thumbnail_component is deprecated') if @thumbnail_component.present?
102
- @thumbnail_component = thumbnail_component || Blacklight::Document::ThumbnailComponent
125
+ @thumbnail_component = thumbnail_component
103
126
 
104
- @document_counter = document_counter
105
127
  @counter = counter
106
- @counter ||= document_counter + 1 + counter_offset if document_counter.present?
128
+ @document_counter = document_counter || args.fetch(self.class.collection_counter_parameter, nil)
129
+ @counter ||= @document_counter + COLLECTION_INDEX_OFFSET + counter_offset if @document_counter.present?
107
130
 
108
131
  @show = show
109
132
  end
@@ -122,7 +145,7 @@ module Blacklight
122
145
  def before_render
123
146
  set_slot(:title, nil) unless title
124
147
  set_slot(:thumbnail, nil, component: @thumbnail_component || presenter.view_config&.thumbnail_component) unless thumbnail || show?
125
- set_slot(:metadata, nil, component: @metadata_component, fields: presenter.field_presenters) unless metadata
148
+ set_slot(:metadata, nil, component: @metadata_component || presenter&.view_config&.metadata_component, fields: presenter.field_presenters) unless metadata
126
149
  set_slot(:embed, nil, component: @embed_component || presenter.view_config&.embed_component) unless embed
127
150
  end
128
151
 
@@ -1,5 +1,7 @@
1
- <dl class="document-metadata dl-invert row">
1
+ <% content = capture do %>
2
2
  <% fields.each do |field| -%>
3
3
  <%= field %>
4
4
  <% end -%>
5
- </dl>
5
+ <% end %>
6
+
7
+ <%= @tag.nil? ? content : tag.public_send(@tag, content, class: @classes, **@component_args) %>
@@ -8,16 +8,20 @@ module Blacklight
8
8
  with_collection_parameter :fields
9
9
 
10
10
  # @param fields [Enumerable<Blacklight::FieldPresenter>] Document field presenters
11
- def initialize(fields: [], show: false)
11
+ def initialize(fields: [], tag: 'dl', classes: %w[document-metadata dl-invert row], show: false, field_layout: nil, **component_args)
12
12
  @fields = fields
13
+ @tag = tag
14
+ @classes = classes
13
15
  @show = show
16
+ @field_layout = field_layout
17
+ @component_args = component_args
14
18
  end
15
19
 
16
20
  def before_render
17
21
  return unless fields
18
22
 
19
23
  @fields.each do |field|
20
- field(component: field_component(field), field: field, show: @show)
24
+ with_field(component: field_component(field), field: field, show: @show, layout: @field_layout)
21
25
  end
22
26
  end
23
27
 
@@ -1,9 +1,9 @@
1
1
  <%= render(@layout.new(facet_field: @facet_field)) do |component| %>
2
- <% component.label do %>
2
+ <% component.with_label do %>
3
3
  <%= @facet_field.label %>
4
4
  <% end %>
5
5
 
6
- <% component.body do %>
6
+ <% component.with_body do %>
7
7
  <ul class="facet-values list-unstyled blacklight-facet-checkboxes">
8
8
  <% presenters.each_with_index do |presenter, idx| -%>
9
9
  <li>
@@ -1,8 +1,8 @@
1
1
  <%= render(@layout.new(facet_field: @facet_field)) do |component| %>
2
- <% component.label do %>
2
+ <% component.with_label do %>
3
3
  <%= @facet_field.label %>
4
4
  <% end %>
5
- <% component.body do %>
5
+ <% component.with_body do %>
6
6
  <%= helpers.render(Blacklight::FacetFieldInclusiveConstraintComponent.new(facet_field: @facet_field)) %>
7
7
  <ul class="facet-values list-unstyled">
8
8
  <%= render_facet_limit_list @facet_field.paginator, @facet_field.key %>
@@ -0,0 +1,2 @@
1
+ <%= top_bar %>
2
+ <%= search_bar %>
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class HeaderComponent < Blacklight::Component
5
+ renders_one :top_bar, lambda { |component: Blacklight::TopNavbarComponent|
6
+ component.new(blacklight_config: blacklight_config)
7
+ }
8
+
9
+ renders_one :search_bar, lambda { |component: Blacklight::SearchNavbarComponent|
10
+ component.new(blacklight_config: blacklight_config)
11
+ }
12
+
13
+ def initialize(blacklight_config:)
14
+ @blacklight_config = blacklight_config
15
+ end
16
+
17
+ attr_reader :blacklight_config
18
+
19
+ # Hack so that the default lambdas are triggered
20
+ # so that we don't have to do c.top_bar() in the call.
21
+ def before_render
22
+ set_slot(:top_bar, nil) unless top_bar
23
+ set_slot(:search_bar, nil) unless search_bar
24
+ end
25
+ end
26
+ end
@@ -1,8 +1,8 @@
1
1
  <%= render(@layout.new(field: @field)) do |component| %>
2
- <% component.label do %>
2
+ <% component.with_label do %>
3
3
  <%= label %>
4
4
  <% end %>
5
- <% component.value do %>
5
+ <% component.with_value do %>
6
6
  <%= @field.render %>
7
7
  <% end %>
8
8
  <% end %>
@@ -7,18 +7,21 @@ module Blacklight
7
7
  with_collection_parameter :field
8
8
  renders_one :label
9
9
  renders_many :values, (lambda do |value: nil, &block|
10
- if block
11
- content_tag :dd, class: "#{@value_class} blacklight-#{@key}", &block
10
+ if @value_tag.nil?
11
+ block&.call || value
12
+ elsif block
13
+ content_tag @value_tag, class: "#{@value_class} blacklight-#{@key}", &block
12
14
  else
13
- content_tag :dd, value, class: "#{@value_class} blacklight-#{@key}"
15
+ content_tag @value_tag, value, class: "#{@value_class} blacklight-#{@key}"
14
16
  end
15
17
  end)
16
18
 
17
19
  # @param field [Blacklight::FieldPresenter]
18
- def initialize(field:, label_class: 'col-md-3', value_class: 'col-md-9')
20
+ def initialize(field:, value_tag: 'dd', label_class: 'col-md-3', value_class: 'col-md-9')
19
21
  @field = field
20
22
  @key = @field.key.parameterize
21
23
  @label_class = label_class
24
+ @value_tag = value_tag
22
25
  @value_class = value_class
23
26
  end
24
27
 
@@ -1,3 +1,3 @@
1
- <%= content_tag :section, class: 'pagination', **@html_attr do %>
1
+ <%= content_tag :section, class: 'pagination', **html_attr do %>
2
2
  <%= pagination %>
3
3
  <% end %>
@@ -8,10 +8,14 @@ module Blacklight
8
8
  # @param [Hash] html html options for the pagination container
9
9
  def initialize(response:, html: {}, **pagination_args)
10
10
  @response = response
11
- @html_attr = { aria: { label: t('views.pagination.aria.container_label') } }.merge(html)
11
+ @html = html
12
12
  @pagination_args = pagination_args
13
13
  end
14
14
 
15
+ def html_attr
16
+ { aria: { label: t('views.pagination.aria.container_label') } }.merge(@html)
17
+ end
18
+
15
19
  def pagination
16
20
  helpers.paginate @response, **Blacklight::Engine.config.blacklight.default_pagination_options, **@pagination_args
17
21
  end
@@ -18,7 +18,7 @@ module Blacklight
18
18
  return if views.any?
19
19
 
20
20
  @views.each do |key, config|
21
- view(key: key, view: config, selected: @selected == key, search_state: @search_state)
21
+ with_view(key: key, view: config, selected: @selected == key, search_state: @search_state)
22
22
  end
23
23
  end
24
24
 
@@ -0,0 +1,5 @@
1
+ <%= tag.div class: 'navbar-search navbar navbar-light bg-light', role: 'navigation', aria: { label: t('blacklight.search.header') } do %>
2
+ <div class="<%= container_classes %>">
3
+ <%= search_bar %>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class SearchNavbarComponent < Blacklight::Component
5
+ def initialize(blacklight_config:)
6
+ @blacklight_config = blacklight_config
7
+ end
8
+
9
+ attr_reader :blacklight_config
10
+
11
+ delegate :container_classes, to: :helpers
12
+
13
+ def search_bar
14
+ render search_bar_component
15
+ end
16
+
17
+ def search_bar_component
18
+ search_bar_component_class.new(
19
+ url: helpers.search_action_url,
20
+ advanced_search_url: helpers.search_action_url(action: 'advanced_search'),
21
+ params: helpers.search_state.params_for_search.except(:qt),
22
+ autocomplete_path: suggest_index_catalog_path
23
+ )
24
+ end
25
+
26
+ def search_bar_component_class
27
+ view_config&.search_bar_component || Blacklight::SearchBarComponent
28
+ end
29
+
30
+ def view_config
31
+ blacklight_config&.view_config(helpers.document_index_view_type)
32
+ end
33
+ end
34
+ end
@@ -29,11 +29,11 @@ module Blacklight
29
29
  end
30
30
 
31
31
  def before_render
32
- button(classes: 'btn btn-outline-secondary dropdown-toggle', label: button_label) unless button
32
+ with_button(classes: 'btn btn-outline-secondary dropdown-toggle', label: button_label) unless button
33
33
 
34
34
  return if options.any?
35
35
 
36
- options(@choices.map do |option|
36
+ with_options(@choices.map do |option|
37
37
  text, value = option_text_and_value(option)
38
38
  { text: text, url: helpers.url_for(@search_state.params_for_search(@param => value)), selected: @selected == value }
39
39
  end)
@@ -13,7 +13,7 @@ module Blacklight
13
13
  end
14
14
 
15
15
  def before_render
16
- message { @message } if @message
16
+ with_message { @message } if @message
17
17
  end
18
18
 
19
19
  def alert_class(type)
@@ -0,0 +1,12 @@
1
+ <nav class="navbar navbar-expand-md navbar-dark bg-dark topbar" role="navigation">
2
+ <div class="<%= container_classes %>">
3
+ <%= logo_link %>
4
+ <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-bs-toggle="collapse" data-target="#user-util-collapse" data-bs-target="#user-util-collapse" aria-controls="user-util-collapse" aria-expanded="false" aria-label="Toggle navigation">
5
+ <span class="navbar-toggler-icon"></span>
6
+ </button>
7
+
8
+ <div class="collapse navbar-collapse justify-content-md-end" id="user-util-collapse">
9
+ <%= render 'shared/user_util_links' %>
10
+ </div>
11
+ </div>
12
+ </nav>
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class TopNavbarComponent < Blacklight::Component
5
+ def initialize(blacklight_config:)
6
+ @blacklight_config = blacklight_config
7
+ end
8
+
9
+ attr_reader :blacklight_config
10
+
11
+ delegate :application_name, :container_classes, to: :helpers
12
+
13
+ def logo_link(title: application_name)
14
+ link_to title, blacklight_config.logo_link, class: 'mb-0 navbar-brand navbar-logo'
15
+ end
16
+ end
17
+ end
@@ -4,4 +4,9 @@ module Blacklight::Base
4
4
 
5
5
  include Blacklight::Configurable
6
6
  include Blacklight::SearchContext
7
+
8
+ def self.included(mod)
9
+ Deprecation.warn(Blacklight::Base, "Blacklight::Base is deprecated and will be removed in Blacklight 8.0.0.
10
+ Include Blacklight::Configurable and Blacklight::SearchContext as needed (included in #{mod}).")
11
+ end
7
12
  end
@@ -5,7 +5,10 @@ module Blacklight::Catalog
5
5
  # MimeResponds is part of ActionController::Base, but not ActionController::API
6
6
  include ActionController::MimeResponds
7
7
 
8
- include Blacklight::Base
8
+ Deprecation.silence(Blacklight::Base) do
9
+ include Blacklight::Base
10
+ end
11
+
9
12
  include Blacklight::Facet
10
13
  include Blacklight::Searchable
11
14
 
@@ -25,7 +25,7 @@ module Blacklight::Controller
25
25
  helper_method :blacklight_config, :blacklight_configuration_context # move to Catalog
26
26
  helper_method :search_action_url, :search_action_path
27
27
  helper_method :search_facet_path # move to catalog? deprecate?
28
- helper_method :search_state # move to catalog?
28
+ helper_method :search_state
29
29
  end
30
30
 
31
31
  # Which class to use for the search state. You can subclass SearchState if you
@@ -64,8 +64,9 @@ module Blacklight::Controller
64
64
  has_user_authentication_provider? && current_or_guest_user.present?
65
65
  end
66
66
 
67
+ # This must be on every controller that uses the layout, because it is used in
68
+ # the header to draw Blacklight::SearchNavbarComponent (via the shared/header_navbar template)
67
69
  # @return [Blacklight::SearchState] a memoized instance of the parameter state.
68
- # TODO: move to catalog?
69
70
  def search_state
70
71
  @search_state ||= search_state_class.new(params, blacklight_config, self)
71
72
  end
@@ -270,9 +270,9 @@ module Blacklight::BlacklightHelperBehavior
270
270
  #
271
271
  # @param [Hash] query_params the query parameters to check
272
272
  # @return [Symbol]
273
- def document_index_view_type query_params = params
273
+ def document_index_view_type query_params = params || {}
274
274
  view_param = query_params[:view]
275
- view_param ||= session[:preferred_view]
275
+ view_param ||= session[:preferred_view] if respond_to?(:session)
276
276
  if view_param && document_index_views.key?(view_param.to_sym)
277
277
  view_param.to_sym
278
278
  else
@@ -69,6 +69,7 @@ module Blacklight::RenderPartialsHelperBehavior
69
69
  if template
70
70
  template.render(self, locals.merge(document: doc))
71
71
  else
72
+ logger.warn("No template was found for base_name: '#{base_name}', view_type: '#{view_type}' in render_document_partial")
72
73
  ''
73
74
  end
74
75
  end