blacklight 7.12.0 → 7.14.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +109 -0
  3. data/.rubocop.yml +3 -0
  4. data/README.md +1 -1
  5. data/VERSION +1 -1
  6. data/app/assets/javascripts/blacklight/blacklight.js +4 -2
  7. data/app/components/blacklight/constraints_component.rb +14 -6
  8. data/app/components/blacklight/document/thumbnail_component.html.erb +1 -1
  9. data/app/components/blacklight/document/thumbnail_component.rb +1 -1
  10. data/app/components/blacklight/document_component.html.erb +1 -0
  11. data/app/components/blacklight/document_component.rb +14 -1
  12. data/app/components/blacklight/facet_field_component.html.erb +1 -0
  13. data/app/components/blacklight/facet_field_pagination_component.html.erb +4 -4
  14. data/app/components/blacklight/facet_field_pagination_component.rb +0 -4
  15. data/app/components/blacklight/hidden_search_state_component.rb +54 -0
  16. data/app/components/blacklight/search_bar_component.html.erb +10 -8
  17. data/app/components/blacklight/search_bar_component.rb +14 -1
  18. data/app/controllers/concerns/blacklight/catalog.rb +3 -3
  19. data/app/controllers/concerns/blacklight/search_context.rb +2 -2
  20. data/app/controllers/concerns/blacklight/searchable.rb +1 -1
  21. data/app/helpers/blacklight/blacklight_helper_behavior.rb +1 -1
  22. data/app/helpers/blacklight/component_helper_behavior.rb +1 -1
  23. data/app/helpers/blacklight/configuration_helper_behavior.rb +3 -9
  24. data/app/helpers/blacklight/facets_helper_behavior.rb +8 -2
  25. data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +2 -38
  26. data/app/helpers/blacklight/icon_helper_behavior.rb +1 -1
  27. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +7 -5
  28. data/app/helpers/blacklight/render_partials_helper_behavior.rb +2 -2
  29. data/app/javascript/blacklight/button_focus.js +1 -0
  30. data/app/javascript/blacklight/modal.js +10 -4
  31. data/app/presenters/blacklight/document_presenter.rb +4 -0
  32. data/app/presenters/blacklight/facet_item_presenter.rb +7 -3
  33. data/app/presenters/blacklight/index_presenter.rb +2 -2
  34. data/app/presenters/blacklight/rendering/link_to_facet.rb +3 -1
  35. data/app/presenters/blacklight/show_presenter.rb +0 -4
  36. data/app/services/blacklight/search_service.rb +13 -11
  37. data/app/values/blacklight/types.rb +1 -1
  38. data/app/views/bookmarks/_tools.html.erb +1 -1
  39. data/app/views/catalog/_search_form.html.erb +1 -1
  40. data/app/views/catalog/index.json.jbuilder +3 -1
  41. data/blacklight.gemspec +5 -4
  42. data/lib/blacklight/configuration/facet_field.rb +7 -0
  43. data/lib/blacklight/configuration/fields.rb +1 -1
  44. data/lib/blacklight/configuration/search_field.rb +5 -0
  45. data/lib/blacklight/configuration/tool_config.rb +4 -0
  46. data/lib/blacklight/configuration/view_config.rb +12 -0
  47. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  48. data/lib/blacklight/search_builder.rb +13 -23
  49. data/lib/blacklight/search_state.rb +82 -70
  50. data/lib/blacklight/search_state/filter_field.rb +122 -0
  51. data/lib/blacklight/solr/repository.rb +3 -3
  52. data/lib/blacklight/solr/response.rb +1 -1
  53. data/lib/blacklight/solr/search_builder_behavior.rb +71 -51
  54. data/package.json +5 -1
  55. data/spec/components/blacklight/constraint_layout_component_spec.rb +1 -1
  56. data/spec/components/blacklight/document_component_spec.rb +17 -0
  57. data/spec/components/blacklight/hidden_search_state_component_spec.rb +24 -0
  58. data/spec/features/facets_spec.rb +2 -17
  59. data/spec/features/search_filters_spec.rb +0 -20
  60. data/spec/features/search_spec.rb +0 -5
  61. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +1 -2
  62. data/spec/helpers/blacklight/hash_as_hidden_fields_behavior_spec.rb +1 -0
  63. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +1 -0
  64. data/spec/lib/blacklight/configuration/view_config_spec.rb +15 -0
  65. data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +9 -0
  66. data/spec/lib/blacklight/search_state/filter_field_spec.rb +125 -0
  67. data/spec/lib/blacklight/search_state_spec.rb +132 -3
  68. data/spec/models/blacklight/configuration_spec.rb +8 -0
  69. data/spec/models/blacklight/solr/response/facets_spec.rb +1 -1
  70. data/spec/models/blacklight/solr/search_builder_spec.rb +32 -2
  71. data/spec/spec_helper.rb +8 -3
  72. data/spec/test_app_templates/Gemfile.extra +1 -1
  73. data/spec/views/catalog/_document.html.erb_spec.rb +1 -0
  74. data/spec/views/catalog/_thumbnail.html.erb_spec.rb +2 -0
  75. data/tasks/blacklight.rake +3 -3
  76. metadata +50 -29
  77. data/.npmignore +0 -23
  78. data/.travis.yml +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 795afb3fdb4a13aa033d1b37180537e51ebfd53ab8f0ef894d05b6370b1c1238
4
- data.tar.gz: 003ccd0c42c44636d463df31c141a7b9b6ab1276bab6d771d1637d2eb7ff17fc
3
+ metadata.gz: 125e5713e43315d9fdbae35677048bb1a1bb9830970f8ff43101ecaed9979385
4
+ data.tar.gz: 34d83a1474edd010642bc2ddf9f72a5409dd66f80bd28f3e6576fafdaa119475
5
5
  SHA512:
6
- metadata.gz: 1e9cdd317ae4535217bc98930c09095ca8aaebe01124863b6a507a2c9bfbd4851a18d72f139bbb6c2f152094e1cb3cf3462eea26747f3212dc484c24603f6ec4
7
- data.tar.gz: a7f142dbaaabff9a9477d116ccd283ab67b2e72fb6d5f0c0482b495ed57f69486aa73f3ef6f67b31f0d00316d1dfb0b61fffaae08ebd1208aebae18a495c9746
6
+ metadata.gz: ab411c9cd2690a01b3d61fa1c8f602b910686b920e26ac638eddfb08e4b43af86d6beca036509056f510a2d56041059dadcfa0ee92cccedcbe238bfe5d7abc4b
7
+ data.tar.gz: ed2cea2667023dbe7720c4939f4dc4b3cd98d26be0e7a1bc89dba416d0b077bf3792b810fe9e479ef5890f2cad3b3003154822778722b5528051df106f570e51
@@ -0,0 +1,109 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: CI
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ lint:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Set up Ruby
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: 2.7
25
+ - name: Install dependencies
26
+ run: bundle install
27
+ - name: Run linter
28
+ run: bundle exec rake rubocop
29
+ test:
30
+ runs-on: ubuntu-latest
31
+ strategy:
32
+ matrix:
33
+ ruby: [2.7, 3.0]
34
+ steps:
35
+ - uses: actions/checkout@v2
36
+ - name: Set up Ruby
37
+ uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby }}
40
+ - name: Install dependencies
41
+ run: bundle install
42
+ - name: Run tests
43
+ run: bundle exec rake ci
44
+ env:
45
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
46
+ test_rails6_0:
47
+ runs-on: ubuntu-latest
48
+ strategy:
49
+ matrix:
50
+ ruby: [2.6]
51
+ steps:
52
+ - uses: actions/checkout@v2
53
+ - name: Set up Ruby
54
+ uses: ruby/setup-ruby@v1
55
+ with:
56
+ ruby-version: ${{ matrix.ruby }}
57
+ - name: Install dependencies
58
+ run: bundle install
59
+ env:
60
+ RAILS_VERSION: 6.0.3.4
61
+ - name: Run tests
62
+ run: bundle exec rake ci
63
+ env:
64
+ RAILS_VERSION: 6.0.3.4
65
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
66
+ test_rails5_2:
67
+ runs-on: ubuntu-latest
68
+ strategy:
69
+ matrix:
70
+ ruby: [2.5]
71
+ steps:
72
+ - uses: actions/checkout@v2
73
+ - name: Set up Ruby
74
+ uses: ruby/setup-ruby@v1
75
+ with:
76
+ ruby-version: ${{ matrix.ruby }}
77
+ - name: Install dependencies
78
+ run: bundle install
79
+ env:
80
+ RAILS_VERSION: 5.2.4.2
81
+ - name: Run tests
82
+ run: bundle exec rake ci
83
+ env:
84
+ RAILS_VERSION: 5.2.4.2
85
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
86
+ api_test:
87
+ runs-on: ubuntu-latest
88
+ strategy:
89
+ matrix:
90
+ ruby: [2.7]
91
+ steps:
92
+ - uses: actions/checkout@v2
93
+ - name: Set up Ruby
94
+ uses: ruby/setup-ruby@v1
95
+ with:
96
+ ruby-version: ${{ matrix.ruby }}
97
+ - name: Install dependencies
98
+ run: bundle install
99
+ - name: Run tests
100
+ run: bundle exec rake ci
101
+ env:
102
+ BLACKLIGHT_API_TEST: true
103
+ ENGINE_CART_RAILS_OPTIONS: '--api --skip-git --skip-bundle --skip-listen --skip-spring --skip-yarn --skip-keeps --skip-action-cable --skip-coffee --skip-test'
104
+ docker_build:
105
+ runs-on: ubuntu-latest
106
+ steps:
107
+ - uses: actions/checkout@v2
108
+ - name: Build docker image
109
+ run: docker-compose build app
@@ -37,6 +37,8 @@ Metrics/BlockLength:
37
37
  Metrics/ClassLength:
38
38
  Exclude:
39
39
  - "lib/blacklight/configuration.rb"
40
+ - "lib/blacklight/search_builder.rb"
41
+ - "lib/blacklight/search_state.rb"
40
42
 
41
43
  Layout/LineLength:
42
44
  Max: 200
@@ -46,6 +48,7 @@ Layout/LineLength:
46
48
  Metrics/ModuleLength:
47
49
  Exclude:
48
50
  - 'app/controllers/concerns/blacklight/catalog.rb'
51
+ - 'lib/blacklight/solr/search_builder_behavior.rb'
49
52
 
50
53
  Naming/HeredocDelimiterNaming:
51
54
  Enabled: false
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Blacklight
2
2
 
3
- [![Build Status](https://travis-ci.org/projectblacklight/blacklight.png?branch=master)](https://travis-ci.org/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Test Coverage](https://api.codeclimate.com/v1/badges/83fd270492c136594e59/test_coverage)](https://codeclimate.com/github/projectblacklight/blacklight/test_coverage)
3
+ [![Build Status](https://travis-ci.com/projectblacklight/blacklight.png?branch=master)](https://travis-ci.com/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Test Coverage](https://api.codeclimate.com/v1/badges/83fd270492c136594e59/test_coverage)](https://codeclimate.com/github/projectblacklight/blacklight/test_coverage)
4
4
 
5
5
  Blacklight is an open source Solr user interface discovery platform.
6
6
  You can use Blacklight to enable searching and browsing of your collections.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.12.0
1
+ 7.14.0
@@ -99,6 +99,7 @@ Blacklight.onLoad(function () {
99
99
  Blacklight.onLoad(function () {
100
100
  // Button clicks should change focus. As of 10/3/19, Firefox for Mac and
101
101
  // Safari both do not set focus to a button on button click.
102
+ // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
102
103
  document.querySelectorAll('button.collapse-toggle').forEach(button => {
103
104
  button.addEventListener('click', () => {
104
105
  event.target.focus();
@@ -349,8 +350,9 @@ Blacklight.modal.modalCloseSelector = '[data-blacklight-modal~=close]'; // Calle
349
350
  // to show to user in modal. Right now called only for extreme
350
351
  // network errors.
351
352
 
352
- Blacklight.modal.onFailure = function (data) {
353
- var contents = '<div class="modal-header">' + '<div class="modal-title">Network Error</div>' + '<button type="button" class="blacklight-modal-close close" data-dismiss="modal" aria-label="Close">' + ' <span aria-hidden="true">&times;</span>' + '</button>';
353
+ Blacklight.modal.onFailure = function (jqXHR, textStatus, errorThrown) {
354
+ console.error('Server error:', this.url, jqXHR.status, errorThrown);
355
+ var contents = '<div class="modal-header">' + '<div class="modal-title">There was a problem with your request.</div>' + '<button type="button" class="blacklight-modal-close close" data-dismiss="modal" aria-label="Close">' + ' <span aria-hidden="true">&times;</span>' + '</button></div>' + ' <div class="modal-body"><p>Expected a successful response from the server, but got an error</p>' + '<pre>' + this.type + ' ' + this.url + "\n" + jqXHR.status + ': ' + errorThrown + '</pre></div>';
354
356
  $(Blacklight.modal.modalSelector).find('.modal-content').html(contents);
355
357
  $(Blacklight.modal.modalSelector).modal('show');
356
358
  };
@@ -22,7 +22,7 @@ module Blacklight
22
22
  @query_constraint_component.new(
23
23
  search_state: @search_state,
24
24
  value: @search_state.query_param,
25
- label: @view_context.constraint_query_label(@search_state.params),
25
+ label: label,
26
26
  remove_path: @view_context.remove_constraint_url(@search_state),
27
27
  classes: 'query'
28
28
  )
@@ -46,14 +46,22 @@ module Blacklight
46
46
 
47
47
  private
48
48
 
49
+ def label
50
+ Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
51
+ @view_context.constraint_query_label(@search_state.params)
52
+ end
53
+ end
54
+
49
55
  def facet_item_presenters
50
- @search_state.filter_params.each_pair.flat_map do |facet, values|
51
- facet_config = @view_context.facet_configuration_for_field(facet)
56
+ Deprecation.silence(Blacklight::SearchState) do
57
+ @search_state.filter_params.each_pair.flat_map do |facet, values|
58
+ facet_config = @view_context.facet_configuration_for_field(facet)
52
59
 
53
- Array(values).map do |val|
54
- next if val.blank? # skip empty string
60
+ Array(values).map do |val|
61
+ next if val.blank? # skip empty string
55
62
 
56
- facet_item_presenter(facet_config, val, facet)
63
+ facet_item_presenter(facet_config, val, facet)
64
+ end
57
65
  end
58
66
  end
59
67
  end
@@ -6,7 +6,7 @@
6
6
  <% warn_about_deprecated_behavior %>
7
7
  <%= value %>
8
8
  <% else %>
9
- <%= @view_context.link_to_document(@presenter.document, value, 'aria-hidden': true, tabindex: -1, counter: @counter) %>
9
+ <%= helpers.link_to_document(@presenter.document, value, 'aria-hidden': true, tabindex: -1, counter: @counter) %>
10
10
  <% end %>
11
11
  </div>
12
12
  <% end %>
@@ -10,7 +10,7 @@ module Blacklight
10
10
  def initialize(presenter:, counter:)
11
11
  @presenter = presenter
12
12
  @counter = counter
13
- @use_thumbnail_tag = @presenter.thumbnail != Blacklight::ThumbnailPresenter
13
+ @use_thumbnail_tag = !@presenter.thumbnail.instance_of?(Blacklight::ThumbnailPresenter)
14
14
  end
15
15
 
16
16
  def render?
@@ -19,6 +19,7 @@
19
19
  <%= actions %>
20
20
  </header>
21
21
 
22
+ <%= embed %>
22
23
  <%= content %>
23
24
  <%= metadata %>
24
25
  </div>
@@ -6,7 +6,7 @@ module Blacklight
6
6
  # the accessors below.
7
7
  with_content_areas :header, :body, :footer,
8
8
  :before_title, :title, :after_title,
9
- :actions, :metadata, :thumbnail,
9
+ :actions, :embed, :metadata, :thumbnail,
10
10
  :partials
11
11
  with_collection_parameter :document
12
12
 
@@ -25,6 +25,7 @@ module Blacklight
25
25
  def initialize(document: nil, presenter: nil,
26
26
  id: nil, classes: [], component: :article, title_component: :h4,
27
27
  metadata_component: Blacklight::DocumentMetadataComponent,
28
+ embed_component: nil,
28
29
  counter: nil, document_counter: nil, counter_offset: 0,
29
30
  show: false)
30
31
  if presenter.nil? && document.nil?
@@ -39,8 +40,10 @@ module Blacklight
39
40
  @id = id || ('document' if show)
40
41
  @classes = classes
41
42
 
43
+ @embed_component = embed_component
42
44
  @metadata_component = metadata_component
43
45
 
46
+ @document_counter = document_counter
44
47
  @counter = counter
45
48
  @counter ||= document_counter + 1 + counter_offset if document_counter.present?
46
49
 
@@ -101,6 +104,16 @@ module Blacklight
101
104
  @before_title || counter
102
105
  end
103
106
 
107
+ def embed
108
+ return @embed if @embed
109
+
110
+ component = @embed_component || presenter.view_config.embed_component
111
+
112
+ return unless component
113
+
114
+ @view_context.render(component.new(document: @document, presenter: presenter, document_counter: @document_counter))
115
+ end
116
+
104
117
  private
105
118
 
106
119
  def counter
@@ -1,6 +1,7 @@
1
1
  <div class="card facet-limit blacklight-<%= @facet_field.key %> <%= 'facet-limit-active' if @facet_field.active? %>">
2
2
  <h3 class="card-header p-0 facet-field-heading" id="<%= @facet_field.html_id %>-header">
3
3
  <button
4
+ type="button"
4
5
  class="btn btn-block p-2 text-left collapse-toggle <%= "collapsed" if @facet_field.collapsed? %>"
5
6
  data-toggle="collapse"
6
7
  data-target="#<%= @facet_field.html_id %>"
@@ -1,9 +1,9 @@
1
1
  <div class="prev_next_links btn-group">
2
- <%= link_to_previous_page @facet_field.paginator, raw(t('views.pagination.previous')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
2
+ <%= @view_context.link_to_previous_page @facet_field.paginator, raw(t('views.pagination.previous')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
3
3
  <%= content_tag :span, raw(t('views.pagination.previous')), class: 'disabled btn' %>
4
4
  <% end %>
5
5
 
6
- <%= link_to_next_page @facet_field.paginator, raw(t('views.pagination.next')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
6
+ <%= @view_context.link_to_next_page @facet_field.paginator, raw(t('views.pagination.next')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
7
7
  <%= content_tag :span, raw(t('views.pagination.next')), class: 'disabled btn' %>
8
8
  <% end %>
9
9
  </div>
@@ -11,9 +11,9 @@
11
11
  <div class="sort-options btn-group">
12
12
  <% if @facet_field.paginator.sort == 'index' -%>
13
13
  <span class="active az btn btn-outline-secondary"><%= t('blacklight.search.facets.sort.index') %></span>
14
- <%= link_to(t('blacklight.search.facets.sort.count'), sort_facet_url('count'), class: "sort_change numeric btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
14
+ <%= @view_context.link_to(t('blacklight.search.facets.sort.count'), sort_facet_url('count'), class: "sort_change numeric btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
15
15
  <% elsif @facet_field.paginator.sort == 'count' -%>
16
- <%= link_to(t('blacklight.search.facets.sort.index'), sort_facet_url('index'), class: "sort_change az btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
16
+ <%= @view_context.link_to(t('blacklight.search.facets.sort.index'), sort_facet_url('index'), class: "sort_change az btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
17
17
  <span class="active numeric btn btn-outline-secondary"><%= t('blacklight.search.facets.sort.count') %></span>
18
18
  <% end -%>
19
19
  </div>
@@ -6,10 +6,6 @@ module Blacklight
6
6
  @facet_field = facet_field
7
7
  end
8
8
 
9
- def render?
10
- @facet_field.facet_field.index_range&.any?
11
- end
12
-
13
9
  def sort_facet_url(sort)
14
10
  @facet_field.paginator.params_for_resort_url(sort, @facet_fieldsearch_state.to_h)
15
11
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ # Writes out zero or more <input type="hidden"> elements, completely
5
+ # representing a hash passed in using Rails-style request parameters
6
+ # for hashes nested with arrays and other hashes.
7
+ class HiddenSearchStateComponent < ::ViewComponent::Base
8
+ # @param [Hash] hash
9
+ def initialize(params:)
10
+ Deprecation.warn(self, "Passing page as a parameter to HiddenSearchStateComponent is deprecated and will not be supported in Blacklight 8") if params.key?(:page)
11
+ @params = params.except(:utf8)
12
+ end
13
+
14
+ def call
15
+ hidden_fields = []
16
+ flatten_hash(@params).each do |name, value|
17
+ value = Array.wrap(value)
18
+ value.each do |v|
19
+ hidden_fields << hidden_field_tag(name, v.to_s, id: nil)
20
+ end
21
+ end
22
+
23
+ safe_join(hidden_fields, "\n")
24
+ end
25
+
26
+ private
27
+
28
+ def flatten_hash(hash = params, ancestor_names = [])
29
+ flat_hash = {}
30
+ hash.each do |k, v|
31
+ names = Array.new(ancestor_names)
32
+ names << k
33
+ if v.is_a?(Hash)
34
+ flat_hash.merge!(flatten_hash(v, names))
35
+ else
36
+ key = flat_hash_key(names)
37
+ key += "[]" if v.is_a?(Array)
38
+ flat_hash[key] = v
39
+ end
40
+ end
41
+
42
+ flat_hash
43
+ end
44
+
45
+ def flat_hash_key(names)
46
+ names = Array.new(names)
47
+ name = names.shift.to_s.dup
48
+ names.each do |n|
49
+ name << "[#{n}]"
50
+ end
51
+ name
52
+ end
53
+ end
54
+ end
@@ -1,27 +1,29 @@
1
- <%= form_tag @url, method: @method, class: @classes.join(' '), role: 'search', 'aria-label' => t('blacklight.search.form.submit') do %>
1
+ <%= form_tag @url, method: @method, class: @classes.join(' '), role: 'search', 'aria-label' => scoped_t('submit') do %>
2
2
  <%= render_hash_as_hidden_fields(@params) %>
3
3
  <% if @search_fields.length > 1 %>
4
- <label for="search_field" class="sr-only"><%= t('blacklight.search.form.search_field.label') %></label>
4
+ <label for="search_field" class="sr-only"><%= scoped_t('search_field.label') %></label>
5
5
  <% end %>
6
6
  <div class="input-group">
7
+ <%= prepend %>
8
+
7
9
  <% if @search_fields.length > 1 %>
8
10
  <%= select_tag(:search_field,
9
11
  options_for_select(@search_fields, h(@search_field)),
10
- title: t('blacklight.search.form.search_field.title'),
12
+ title: scoped_t('search_field.title'),
11
13
  id: "#{@prefix}search_field",
12
14
  class: "custom-select search-field") %>
13
15
  <% elsif @search_fields.length == 1 %>
14
16
  <%= hidden_field_tag :search_field, @search_fields.first.last %>
15
17
  <% end %>
16
18
 
17
- <label for="<%= @prefix %>q" class="sr-only"><%= t('blacklight.search.form.search.label') %></label>
18
- <%= text_field_tag :q, @q, placeholder: t('blacklight.search.form.search.placeholder'), class: "search-q q form-control rounded-#{@search_fields.length > 1 ? '0' : 'left'}", id: "#{@prefix}q", autocomplete: autocomplete_path.present? ? "off" : "", autofocus: @autofocus, data: { autocomplete_enabled: autocomplete_path.present?, autocomplete_path: autocomplete_path } %>
19
-
20
- <%= content %>
19
+ <label for="<%= @prefix %><%= @query_param %>" class="sr-only"><%= scoped_t('search.label') %></label>
20
+ <%= text_field_tag @query_param, @q, placeholder: scoped_t('search.placeholder'), class: "search-q q form-control rounded-#{@search_fields.length > 1 ? '0' : 'left'}", id: "#{@prefix}q", autocomplete: autocomplete_path.present? ? "off" : "", autofocus: @autofocus, data: { autocomplete_enabled: autocomplete_path.present?, autocomplete_path: autocomplete_path } %>
21
21
 
22
22
  <span class="input-group-append">
23
+ <%= append %>
24
+
23
25
  <button type="submit" class="btn btn-primary search-btn" id="<%= @prefix %>search">
24
- <span class="submit-search-text"><%= t('blacklight.search.form.submit') %></span>
26
+ <span class="submit-search-text"><%= scoped_t('submit') %></span>
25
27
  <%= blacklight_icon :search, aria_hidden: true %>
26
28
  </button>
27
29
  </span>
@@ -2,10 +2,18 @@
2
2
 
3
3
  module Blacklight
4
4
  class SearchBarComponent < ::ViewComponent::Base
5
+ with_content_areas :append, :prepend
6
+
5
7
  # rubocop:disable Metrics/ParameterLists
6
- def initialize(url:, params:, classes: ['search-query-form'], presenter: nil, prefix: '', method: 'GET', q: nil, search_field: nil, search_fields: [], autocomplete_path: nil, autofocus: nil)
8
+ def initialize(
9
+ url:, params:, classes: ['search-query-form'], presenter: nil,
10
+ prefix: '', method: 'GET', q: nil, query_param: :q,
11
+ search_field: nil, search_fields: [], autocomplete_path: nil,
12
+ autofocus: nil, i18n: { scope: 'blacklight.search.form' }
13
+ )
7
14
  @url = url
8
15
  @q = q || params[:q]
16
+ @query_param = query_param
9
17
  @search_field = search_field || params[:search_field]
10
18
  @params = params.except(:q, :search_field, :utf8, :page)
11
19
  @prefix = prefix
@@ -15,6 +23,7 @@ module Blacklight
15
23
  @autocomplete_path = autocomplete_path
16
24
  @autofocus = autofocus
17
25
  @search_fields = search_fields
26
+ @i18n = i18n
18
27
  end
19
28
  # rubocop:enable Metrics/ParameterLists
20
29
 
@@ -47,5 +56,9 @@ module Blacklight
47
56
  @view_context.render_hash_as_hidden_fields(*args)
48
57
  end
49
58
  end
59
+
60
+ def scoped_t(key, **args)
61
+ t(key, default: t(key, scope: 'blacklight.search.form'), **@i18n, **args)
62
+ end
50
63
  end
51
64
  end