blacklight 7.33.1 → 7.35.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) 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/bookmarks.rb +5 -1
  33. data/app/controllers/concerns/blacklight/catalog.rb +14 -3
  34. data/app/controllers/concerns/blacklight/controller.rb +3 -2
  35. data/app/helpers/blacklight/blacklight_helper_behavior.rb +2 -2
  36. data/app/helpers/blacklight/render_partials_helper_behavior.rb +1 -0
  37. data/app/models/concerns/blacklight/document/active_model_shim.rb +10 -0
  38. data/app/models/concerns/blacklight/document/attributes.rb +50 -0
  39. data/app/models/concerns/blacklight/document.rb +12 -20
  40. data/app/models/search.rb +6 -1
  41. data/app/presenters/blacklight/rendering/join.rb +1 -1
  42. data/app/services/blacklight/field_retriever.rb +13 -11
  43. data/app/values/blacklight/types.rb +99 -11
  44. data/app/views/catalog/_document.html.erb +1 -1
  45. data/app/views/catalog/_facet_layout.html.erb +2 -2
  46. data/app/views/catalog/_search_form.html.erb +1 -1
  47. data/app/views/catalog/_show_main_content.html.erb +2 -2
  48. data/app/views/catalog/_show_sidebar.html.erb +1 -1
  49. data/app/views/catalog/_show_tools.html.erb +4 -3
  50. data/app/views/catalog/facet.html.erb +3 -3
  51. data/app/views/layouts/blacklight/base.html.erb +7 -7
  52. data/app/views/shared/_header_navbar.html.erb +1 -22
  53. data/blacklight.gemspec +3 -4
  54. data/config/locales/blacklight.en.yml +1 -0
  55. data/docker-compose.yml +1 -0
  56. data/lib/blacklight/configuration.rb +39 -2
  57. data/lib/blacklight/engine.rb +15 -0
  58. data/lib/blacklight/solr/repository.rb +14 -2
  59. data/lib/blacklight/solr/request.rb +2 -0
  60. data/lib/blacklight/solr/search_builder_behavior.rb +2 -1
  61. data/lib/blacklight.rb +1 -1
  62. data/lib/generators/blacklight/assets_generator.rb +1 -1
  63. data/lib/generators/blacklight/install_generator.rb +1 -1
  64. data/lib/generators/blacklight/templates/catalog_controller.rb +4 -0
  65. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +69 -0
  66. data/lib/generators/blacklight/templates/solr_document.rb +1 -1
  67. data/lib/railties/blacklight.rake +4 -4
  68. data/package.json +1 -1
  69. data/spec/components/blacklight/document_component_spec.rb +60 -11
  70. data/spec/components/blacklight/facet_component_spec.rb +11 -1
  71. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +3 -2
  72. data/spec/components/blacklight/header_component_spec.rb +20 -0
  73. data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
  74. data/spec/controllers/blacklight/base_spec.rb +1 -1
  75. data/spec/features/advanced_search_spec.rb +56 -0
  76. data/spec/features/axe_spec.rb +5 -0
  77. data/spec/features/sitelinks_search_box_spec.rb +13 -0
  78. data/spec/helpers/blacklight/search_history_constraints_helper_behavior_spec.rb +8 -15
  79. data/spec/helpers/blacklight_helper_spec.rb +10 -5
  80. data/spec/models/blacklight/configuration_spec.rb +22 -0
  81. data/spec/models/blacklight/solr/repository_spec.rb +27 -0
  82. data/spec/models/blacklight/solr/search_builder_spec.rb +16 -0
  83. data/spec/models/solr_document_spec.rb +21 -3
  84. data/spec/presenters/blacklight/show_presenter_spec.rb +4 -10
  85. data/spec/services/blacklight/field_retriever_spec.rb +17 -0
  86. data/spec/spec_helper.rb +32 -5
  87. data/spec/support/view_component_test_helpers.rb +35 -0
  88. data/spec/views/catalog/_show_tools.html.erb_spec.rb +24 -10
  89. metadata +30 -27
  90. data/spec/features/sitelinks_search_box.rb +0 -13
  91. 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: 841946108f3216c1dfc66f10787069b43fdcca041e9cc3e114524bf0a5cf6aa1
4
+ data.tar.gz: 621f2d5648013ab85fa3c3c99a001824e49b24be263cd1eda45a7f5ed9e22daa
5
5
  SHA512:
6
- metadata.gz: 11ab615553f94bbdb382865dc4cd9dc757b9895de17976a8a8e9294987e25ef54d8b1e5d3f744690984508d5f6375cb823b21b78411f9b87c0ab5fe90dde6bec
7
- data.tar.gz: afab5ae2f8e18deaf6935abb4160a326849cc4234bc9ac9cd21f757395493b7d698c908541f960ee8a17a3beb4c5e48b71f675c578426736f6055e57659c9709
6
+ metadata.gz: 9ae81c46a04f928701d7e16c227bf33ae9ed0ae214e6ef94bbf96bc0b33aa22ff889e286a1235d6c6a225e11597fe3e832db2c5242cc71a533229ee75dc2b407
7
+ data.tar.gz: 2005c22b35ac7a9f4c3fb065f412a6369bcf903f918bc46770d23999a509bae45d855c83b14a0e167f3acbafd900ae63f6fe4cfe30de98f8d97bb17980a64c49
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.35.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
@@ -42,7 +42,11 @@ module Blacklight::Bookmarks
42
42
  @bookmarks = token_or_current_or_guest_user.bookmarks
43
43
  bookmark_ids = @bookmarks.collect { |b| b.document_id.to_s }
44
44
  @response, deprecated_document_list = search_service.fetch(bookmark_ids)
45
- @document_list = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(deprecated_document_list, "The @document_list instance variable is now deprecated and will be removed in Blacklight 8.0")
45
+ @document_list = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
46
+ deprecated_document_list,
47
+ "The @document_list instance variable is now deprecated",
48
+ ActiveSupport::Deprecation.new("8.0", "blacklight")
49
+ )
46
50
 
47
51
  respond_to do |format|
48
52
  format.html {}
@@ -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
 
@@ -31,7 +34,11 @@ module Blacklight::Catalog
31
34
  def index
32
35
  (@response, deprecated_document_list) = search_service.search_results
33
36
 
34
- @document_list = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(deprecated_document_list, 'The @document_list instance variable is deprecated; use @response.documents instead.')
37
+ @document_list = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
38
+ deprecated_document_list,
39
+ 'The @document_list instance variable is deprecated; use @response.documents instead.',
40
+ ActiveSupport::Deprecation.new("8.0", "blacklight")
41
+ )
35
42
 
36
43
  respond_to do |format|
37
44
  format.html { store_preferred_view }
@@ -50,7 +57,11 @@ module Blacklight::Catalog
50
57
  # to add responses for formats other than html or json see _Blacklight::Document::Export_
51
58
  def show
52
59
  deprecated_response, @document = search_service.fetch(params[:id])
53
- @response = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(deprecated_response, 'The @response instance variable is deprecated; use @document.response instead.')
60
+ @response = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
61
+ deprecated_response,
62
+ 'The @response instance variable is deprecated; use @document.response instead.',
63
+ ActiveSupport::Deprecation.new("8.0", "blacklight")
64
+ )
54
65
 
55
66
  respond_to do |format|
56
67
  format.html { @search_context = setup_next_and_previous_documents }
@@ -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