blacklight 9.0.0.beta1 → 9.0.0.beta2
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.
- checksums.yaml +4 -4
- data/.github/matrix.json +47 -0
- data/.github/workflows/build.yml +16 -0
- data/.github/workflows/lint.yml +25 -0
- data/.github/workflows/main.yml +22 -0
- data/.github/workflows/release_7_x_scheduled.yml +39 -0
- data/.github/workflows/release_8_x_scheduled.yml +39 -0
- data/.github/workflows/test.yml +53 -0
- data/.rubocop.yml +70 -2
- data/.rubocop_todo.yml +43 -67
- data/.solr_wrapper.yml +2 -0
- data/VERSION +1 -1
- data/app/assets/builds/blacklight.css +19 -15
- data/app/assets/javascripts/blacklight/blacklight.esm.js +31 -69
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +31 -69
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +4 -0
- data/app/assets/stylesheets/blacklight/_facets.scss +2 -2
- data/app/assets/stylesheets/blacklight/_header.scss +4 -0
- data/app/assets/stylesheets/blacklight/_modal.scss +9 -8
- data/app/assets/stylesheets/blacklight/_pagination.scss +1 -3
- data/app/assets/stylesheets/blacklight/_search_history.scss +0 -4
- data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +3 -0
- data/app/components/blacklight/advanced_search_form_component.rb +2 -2
- data/app/components/blacklight/constraints_component.rb +2 -2
- data/app/components/blacklight/document/action_component.rb +1 -3
- data/app/components/blacklight/document/bookmark_component.rb +2 -2
- data/app/components/blacklight/document/more_like_this_component.rb +2 -2
- data/app/components/blacklight/document/page_header_component.rb +2 -2
- data/app/components/blacklight/document/thumbnail_component.html.erb +3 -7
- data/app/components/blacklight/document/thumbnail_component.rb +7 -6
- data/app/components/blacklight/document_component.rb +3 -3
- data/app/components/blacklight/document_title_component.rb +3 -10
- data/app/components/blacklight/facet_field_checkboxes_component.rb +2 -20
- data/app/components/blacklight/facet_field_component.rb +2 -17
- data/app/components/blacklight/facet_field_filter_component.rb +2 -21
- data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -25
- data/app/components/blacklight/facet_field_list_component.rb +2 -32
- data/app/components/blacklight/facet_field_no_layout_component.rb +2 -10
- data/app/components/blacklight/facet_field_pagination_component.html.erb +2 -2
- data/app/components/blacklight/facet_item_component.rb +2 -74
- data/app/components/blacklight/facet_item_pivot_component.rb +1 -1
- data/app/components/blacklight/facets/checkboxes_component.rb +26 -0
- data/app/components/blacklight/facets/count_component.rb +23 -0
- data/app/components/blacklight/{facet_field_component.html.erb → facets/field_component.html.erb} +1 -1
- data/app/components/blacklight/facets/field_component.rb +23 -0
- data/app/components/blacklight/facets/filters_component.html.erb +4 -0
- data/app/components/blacklight/facets/filters_component.rb +27 -0
- data/app/components/blacklight/{facet_field_inclusive_constraint_component.html.erb → facets/inclusive_constraint_component.html.erb} +1 -1
- data/app/components/blacklight/facets/inclusive_constraint_component.rb +31 -0
- data/app/components/blacklight/{facet_field_filter_component.html.erb → facets/index_navigation_component.html.erb} +1 -1
- data/app/components/blacklight/facets/index_navigation_component.rb +32 -0
- data/app/components/blacklight/facets/item_component.rb +73 -0
- data/app/components/blacklight/facets/list_component.html.erb +11 -0
- data/app/components/blacklight/facets/list_component.rb +38 -0
- data/app/components/blacklight/facets/no_layout_component.rb +16 -0
- data/app/components/blacklight/facets/selected_value_component.rb +29 -0
- data/app/components/blacklight/facets/suggest_component.html.erb +12 -0
- data/app/components/blacklight/facets/suggest_component.rb +22 -0
- data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
- data/app/components/blacklight/response/facet_group_component.html.erb +1 -1
- data/app/components/blacklight/response/facet_group_component.rb +5 -1
- data/app/components/blacklight/system/dropdown_component.html.erb +1 -1
- data/app/components/blacklight/system/dropdown_component.rb +1 -1
- data/app/components/blacklight/top_navbar_component.html.erb +1 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +3 -3
- data/app/controllers/concerns/blacklight/catalog.rb +10 -25
- data/app/controllers/concerns/blacklight/controller.rb +1 -1
- data/app/controllers/concerns/blacklight/facetable.rb +34 -0
- data/app/controllers/concerns/blacklight/search_context.rb +1 -1
- data/app/controllers/concerns/blacklight/searchable.rb +1 -1
- data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
- data/app/helpers/blacklight/document_helper_behavior.rb +3 -1
- data/app/helpers/blacklight/facets_helper_behavior.rb +9 -0
- data/app/helpers/blacklight/icon_helper_behavior.rb +2 -2
- data/app/javascript/blacklight-frontend/checkbox_submit.js +3 -0
- data/app/javascript/blacklight-frontend/debounce.js +1 -1
- data/app/javascript/blacklight-frontend/facet_suggest.js +23 -3
- data/app/javascript/blacklight-frontend/index.js +0 -2
- data/app/javascript/blacklight-frontend/modal.js +1 -4
- data/app/javascript/blacklight-frontend/search_context.js +3 -2
- data/app/models/facet_search_builder.rb +5 -0
- data/app/presenters/blacklight/facet_field_presenter.rb +1 -1
- data/app/presenters/blacklight/json_presenter.rb +1 -3
- data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
- data/app/presenters/blacklight/rendering/join.rb +2 -2
- data/app/services/blacklight/facet_search_service.rb +44 -0
- data/app/services/blacklight/field_retriever.rb +1 -1
- data/app/services/blacklight/search_service.rb +6 -6
- data/app/values/blacklight/types.rb +2 -2
- data/app/views/catalog/_facet_pivot.html.erb +1 -1
- data/app/views/catalog/_home_text.html.erb +2 -2
- data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
- data/app/views/catalog/facet.html.erb +8 -10
- data/config/locales/blacklight.ar.yml +2 -2
- data/config/locales/blacklight.es.yml +2 -2
- data/config/locales/blacklight.fr.yml +2 -2
- data/config/locales/blacklight.hu.yml +2 -2
- data/config/locales/blacklight.it.yml +2 -2
- data/config/locales/blacklight.nl.yml +1 -1
- data/config/locales/blacklight.pt-BR.yml +2 -2
- data/config/locales/blacklight.sq.yml +2 -2
- data/config/locales/blacklight.zh.yml +2 -2
- data/lib/blacklight/abstract_repository.rb +2 -2
- data/lib/blacklight/abstract_search_builder.rb +154 -0
- data/lib/blacklight/configuration/context.rb +3 -3
- data/lib/blacklight/configuration/facet_field.rb +6 -6
- data/lib/blacklight/configuration/field.rb +4 -4
- data/lib/blacklight/configuration/fields.rb +0 -1
- data/lib/blacklight/configuration/search_field.rb +1 -1
- data/lib/blacklight/configuration/view_config.rb +2 -2
- data/lib/blacklight/configuration.rb +6 -7
- data/lib/blacklight/facet_search_builder.rb +18 -0
- data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
- data/lib/blacklight/open_struct_with_hash_access.rb +2 -2
- data/lib/blacklight/search_builder.rb +1 -159
- data/lib/blacklight/search_state/filter_field.rb +4 -4
- data/lib/blacklight/search_state/pivot_filter_field.rb +4 -4
- data/lib/blacklight/solr/abstract_filter_query_builder.rb +77 -0
- data/lib/blacklight/solr/default_filter_query_builder.rb +20 -0
- data/lib/blacklight/solr/facet_search_builder_behavior.rb +62 -0
- data/lib/blacklight/solr/repository.rb +8 -9
- data/lib/blacklight/solr/response/facets.rb +2 -2
- data/lib/blacklight/solr/response/params.rb +0 -4
- data/lib/blacklight/solr/response.rb +5 -1
- data/lib/blacklight/solr/search_builder_behavior.rb +17 -132
- data/lib/blacklight.rb +1 -1
- data/lib/generators/blacklight/assets/importmap_generator.rb +3 -5
- data/lib/generators/blacklight/assets_generator.rb +1 -1
- data/lib/generators/blacklight/search_builder_generator.rb +1 -1
- data/lib/generators/blacklight/templates/.solr_wrapper.yml +2 -0
- data/lib/generators/blacklight/templates/catalog_controller.rb +3 -1
- data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -4
- data/package.json +3 -3
- data/spec/components/blacklight/advanced_search_form_component_spec.rb +18 -22
- data/spec/components/blacklight/constraint_layout_component_spec.rb +8 -8
- data/spec/components/blacklight/constraints_component_spec.rb +11 -11
- data/spec/components/blacklight/document/action_component_spec.rb +23 -15
- data/spec/components/blacklight/document/group_component_spec.rb +10 -15
- data/spec/components/blacklight/document/page_header_component_spec.rb +35 -28
- data/spec/components/blacklight/document/sidebar_component_spec.rb +5 -11
- data/spec/components/blacklight/document_component_spec.rb +98 -65
- data/spec/components/blacklight/facet_component_spec.rb +12 -8
- data/spec/components/blacklight/facet_item_pivot_component_spec.rb +12 -12
- data/spec/components/blacklight/{facet_field_checkboxes_component_spec.rb → facets/checkboxes_component_spec.rb} +13 -13
- data/spec/components/blacklight/facets/filters_component_spec.rb +36 -0
- data/spec/components/blacklight/facets/index_navigation_component_spec.rb +40 -0
- data/spec/components/blacklight/{facet_item_component_spec.rb → facets/item_component_spec.rb} +10 -10
- data/spec/components/blacklight/{facet_field_list_component_spec.rb → facets/list_component_spec.rb} +23 -23
- data/spec/components/blacklight/facets/suggest_component_spec.rb +68 -0
- data/spec/components/blacklight/header_component_spec.rb +2 -4
- data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -7
- data/spec/components/blacklight/metadata_field_component_spec.rb +17 -15
- data/spec/components/blacklight/response/facet_group_component_spec.rb +37 -0
- data/spec/components/blacklight/response/pagination_component_spec.rb +1 -1
- data/spec/components/blacklight/response/spellcheck_component_spec.rb +1 -1
- data/spec/components/blacklight/search_bar_component_spec.rb +4 -4
- data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +2 -2
- data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +3 -5
- data/spec/components/blacklight/skip_link_component_spec.rb +8 -11
- data/spec/components/blacklight/start_over_button_component_spec.rb +4 -4
- data/spec/components/blacklight/system/dropdown_component_spec.rb +26 -0
- data/spec/components/blacklight/system/flash_message_component_spec.rb +7 -11
- data/spec/controllers/catalog_controller_spec.rb +12 -20
- data/spec/features/facets_spec.rb +70 -7
- data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +10 -0
- data/spec/lib/blacklight/configuration/facet_field_spec.rb +2 -2
- data/spec/lib/blacklight/parameters_spec.rb +12 -1
- data/spec/lib/blacklight/search_state/filter_field_spec.rb +18 -0
- data/spec/models/blacklight/configuration_spec.rb +32 -28
- data/spec/models/blacklight/facet_search_builder_spec.rb +19 -0
- data/spec/models/blacklight/search_builder_spec.rb +1 -11
- data/spec/models/blacklight/solr/default_filter_query_builder_spec.rb +72 -0
- data/spec/models/blacklight/solr/document_spec.rb +0 -4
- data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +929 -0
- data/spec/models/blacklight/solr/repository_spec.rb +31 -29
- data/spec/models/blacklight/solr/response/facets_spec.rb +86 -40
- data/spec/models/blacklight/solr/response/group_response_spec.rb +8 -5
- data/spec/models/blacklight/solr/response/group_spec.rb +9 -5
- data/spec/models/blacklight/solr/response_spec.rb +96 -64
- data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +2 -227
- data/spec/models/solr_document_spec.rb +5 -1
- data/spec/services/blacklight/search_service_spec.rb +6 -27
- data/spec/spec_helper.rb +0 -1
- data/spec/support/view_component_test_helpers.rb +0 -18
- data/spec/views/catalog/facet.html.erb_spec.rb +10 -3
- data/spec/views/catalog/index.atom.builder_spec.rb +6 -3
- data/spec/views/catalog/index.html.erb_spec.rb +3 -1
- metadata +58 -29
- data/.github/workflows/ruby.yml +0 -98
- data/app/components/blacklight/facet_field_list_component.html.erb +0 -19
- data/app/components/blacklight/search/facet_suggest_input.html.erb +0 -9
- data/app/components/blacklight/search/facet_suggest_input.rb +0 -16
- data/app/javascript/blacklight-frontend/modalForm.js +0 -60
- data/app/views/catalog/_facet_index_navigation.html.erb +0 -1
- data/app/views/catalog/_facet_layout.html.erb +0 -8
- data/app/views/catalog/_facet_pagination.html.erb +0 -1
- data/spec/components/blacklight/document_metadata_component_spec.rb +0 -0
- data/spec/components/blacklight/search/facet_suggest_input_spec.rb +0 -33
- data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +0 -43
- data/spec/views/catalog/_facet_layout.html.erb_spec.rb +0 -41
- /data/app/components/blacklight/{facet_field_checkboxes_component.html.erb → facets/checkboxes_component.html.erb} +0 -0
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
##
|
5
|
+
# Blacklight's SearchBuilder converts blacklight request parameters into
|
6
|
+
# query parameters appropriate for search index. It does so by evaluating a
|
7
|
+
# chain of processing methods to populate a result hash (see {#to_hash}).
|
8
|
+
class AbstractSearchBuilder
|
9
|
+
class_attribute :default_processor_chain
|
10
|
+
self.default_processor_chain = []
|
11
|
+
|
12
|
+
attr_reader :processor_chain, :search_state, :blacklight_params
|
13
|
+
|
14
|
+
# @overload initialize(scope)
|
15
|
+
# @param [Object] scope scope the scope where the filter methods reside in.
|
16
|
+
# @overload initialize(processor_chain, scope)
|
17
|
+
# @param [List<Symbol>,TrueClass] processor_chain options a list of filter methods to run or true, to use the default methods
|
18
|
+
# @param [Object] scope the scope where the filter methods reside in.
|
19
|
+
def initialize(*options)
|
20
|
+
case options.size
|
21
|
+
when 1
|
22
|
+
@processor_chain = default_processor_chain.dup
|
23
|
+
@scope = options.first
|
24
|
+
when 2
|
25
|
+
@processor_chain, @scope = options
|
26
|
+
else
|
27
|
+
raise ArgumentError, "wrong number of arguments. (#{options.size} for 1..2)"
|
28
|
+
end
|
29
|
+
|
30
|
+
@blacklight_params = {}
|
31
|
+
search_state_class = @scope.try(:search_state_class) || Blacklight::SearchState
|
32
|
+
@search_state = search_state_class.new(@blacklight_params, @scope&.blacklight_config, @scope)
|
33
|
+
@additional_filters = {}
|
34
|
+
@merged_params = {}
|
35
|
+
@reverse_merged_params = {}
|
36
|
+
end
|
37
|
+
|
38
|
+
delegate :blacklight_config, to: :scope
|
39
|
+
|
40
|
+
##
|
41
|
+
# Set the parameters to pass through the processor chain
|
42
|
+
def with(blacklight_params_or_search_state = {})
|
43
|
+
params_will_change!
|
44
|
+
@search_state = blacklight_params_or_search_state.is_a?(Blacklight::SearchState) ? blacklight_params_or_search_state : @search_state.reset(blacklight_params_or_search_state)
|
45
|
+
@blacklight_params = @search_state.params.dup
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# sets the facet that this query pertains to, for the purpose of facet pagination
|
50
|
+
def facet=(value)
|
51
|
+
params_will_change!
|
52
|
+
@facet = value
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param [Object] value
|
56
|
+
def facet(value = nil)
|
57
|
+
if value
|
58
|
+
self.facet = value
|
59
|
+
return self
|
60
|
+
end
|
61
|
+
@facet
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Merge additional, repository-specific parameters
|
66
|
+
def merge(extra_params, &)
|
67
|
+
if extra_params
|
68
|
+
params_will_change!
|
69
|
+
@merged_params.merge!(extra_params.to_hash, &)
|
70
|
+
end
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# "Reverse merge" additional, repository-specific parameters
|
76
|
+
def reverse_merge(extra_params, &)
|
77
|
+
if extra_params
|
78
|
+
params_will_change!
|
79
|
+
@reverse_merged_params.reverse_merge!(extra_params.to_hash, &)
|
80
|
+
end
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
delegate :[], :key?, to: :to_hash
|
85
|
+
|
86
|
+
# a solr query method
|
87
|
+
# @return [Blacklight::Solr::Response] the solr response object
|
88
|
+
def to_hash
|
89
|
+
return @params unless params_need_update?
|
90
|
+
|
91
|
+
@params = processed_parameters
|
92
|
+
.reverse_merge(@reverse_merged_params)
|
93
|
+
.merge(@merged_params)
|
94
|
+
.tap { clear_changes }
|
95
|
+
end
|
96
|
+
|
97
|
+
alias query to_hash
|
98
|
+
alias to_h to_hash
|
99
|
+
|
100
|
+
delegate :search_field, to: :search_state
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
attr_reader :scope
|
105
|
+
|
106
|
+
def should_add_field_to_request? _field_name, field
|
107
|
+
field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request)
|
108
|
+
end
|
109
|
+
|
110
|
+
def request
|
111
|
+
Blacklight::Solr::Request.new
|
112
|
+
end
|
113
|
+
|
114
|
+
# The CatalogController #index and #facet actions use this.
|
115
|
+
# Solr parameters can come from a number of places. From lowest
|
116
|
+
# precedence to highest:
|
117
|
+
# 1. General defaults in blacklight config (are trumped by)
|
118
|
+
# 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
|
119
|
+
# 3. certain parameters directly on input HTTP query params
|
120
|
+
# * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
|
121
|
+
# * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
|
122
|
+
# 4. extra parameters passed in as argument.
|
123
|
+
#
|
124
|
+
# spellcheck.q will be supplied with the [:q] value unless specifically
|
125
|
+
# specified otherwise.
|
126
|
+
#
|
127
|
+
# Incoming parameter :f is mapped to :fq solr parameter.
|
128
|
+
#
|
129
|
+
# @return a params hash for searching solr.
|
130
|
+
def processed_parameters
|
131
|
+
request.tap do |request_parameters|
|
132
|
+
processor_chain.each do |method_name|
|
133
|
+
send(method_name, request_parameters)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def params_will_change!
|
139
|
+
@dirty = true
|
140
|
+
end
|
141
|
+
|
142
|
+
def params_changed?
|
143
|
+
!!@dirty
|
144
|
+
end
|
145
|
+
|
146
|
+
def clear_changes
|
147
|
+
@dirty = false
|
148
|
+
end
|
149
|
+
|
150
|
+
def params_need_update?
|
151
|
+
params_changed? || @params.nil?
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -24,16 +24,16 @@ module Blacklight
|
|
24
24
|
#
|
25
25
|
# @param [#if,#unless] config an object that responds to if/unless
|
26
26
|
# @return [Boolean]
|
27
|
-
def evaluate_if_unless_configuration(config, *
|
27
|
+
def evaluate_if_unless_configuration(config, *)
|
28
28
|
return config if config == true || config == false
|
29
29
|
|
30
30
|
if_value = !config.respond_to?(:if) ||
|
31
31
|
config.if.nil? ||
|
32
|
-
evaluate_configuration_conditional(config.if, config, *
|
32
|
+
evaluate_configuration_conditional(config.if, config, *)
|
33
33
|
|
34
34
|
unless_value = !config.respond_to?(:unless) ||
|
35
35
|
config.unless.nil? ||
|
36
|
-
!evaluate_configuration_conditional(config.unless, config, *
|
36
|
+
!evaluate_configuration_conditional(config.unless, config, *)
|
37
37
|
|
38
38
|
if_value && unless_value
|
39
39
|
end
|
@@ -59,15 +59,15 @@ module Blacklight
|
|
59
59
|
# @!attribute item_presenter
|
60
60
|
# @return [Blacklight::FacetItemPresenter]
|
61
61
|
# @!attribute component
|
62
|
-
# @return [Blacklight::
|
62
|
+
# @return [Blacklight::Facets::ListComponent]
|
63
63
|
# @!attribute item_component
|
64
|
-
# @return [Blacklight::
|
64
|
+
# @return [Blacklight::Facets::ItemComponent]
|
65
65
|
# @!attribute partial
|
66
66
|
# @return [String] Rails view partial used to render the facet field
|
67
67
|
|
68
68
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
69
69
|
def normalize! blacklight_config = nil
|
70
|
-
query
|
70
|
+
query&.stringify_keys!
|
71
71
|
|
72
72
|
normalize_pivot_config! if pivot
|
73
73
|
self.collapse = true if collapse.nil?
|
@@ -76,9 +76,9 @@ module Blacklight
|
|
76
76
|
self.index_range = 'A'..'Z' if index_range == true
|
77
77
|
self.presenter ||= Blacklight::FacetFieldPresenter
|
78
78
|
self.item_presenter ||= Blacklight::FacetItemPresenter
|
79
|
-
self.component = Blacklight::
|
80
|
-
self.advanced_search_component ||= Blacklight::
|
81
|
-
self.item_component ||= Blacklight::
|
79
|
+
self.component = Blacklight::Facets::ListComponent if component.nil? || component == true
|
80
|
+
self.advanced_search_component ||= Blacklight::Facets::CheckboxesComponent
|
81
|
+
self.item_component ||= Blacklight::Facets::ItemComponent
|
82
82
|
super
|
83
83
|
|
84
84
|
if single && tag.blank? && ex.blank?
|
@@ -33,13 +33,13 @@ module Blacklight
|
|
33
33
|
raise ArgumentError, "Must supply a field name" if self.field.nil?
|
34
34
|
end
|
35
35
|
|
36
|
-
def display_label(context = nil, **
|
36
|
+
def display_label(context = nil, **)
|
37
37
|
field_label(
|
38
38
|
(:"blacklight.search.fields.#{context}.#{key}" if context),
|
39
39
|
:"blacklight.search.fields.#{key}",
|
40
40
|
label,
|
41
41
|
default_label,
|
42
|
-
**
|
42
|
+
**
|
43
43
|
)
|
44
44
|
end
|
45
45
|
|
@@ -65,10 +65,10 @@ module Blacklight
|
|
65
65
|
# before falling back to the label
|
66
66
|
# @param [Symbol] any number of additional keys
|
67
67
|
# @param [Symbol] ...
|
68
|
-
def field_label
|
68
|
+
def field_label(*i18n_keys, **)
|
69
69
|
first, *rest = i18n_keys.compact
|
70
70
|
|
71
|
-
I18n.t(first, default: rest, **
|
71
|
+
I18n.t(first, default: rest, **)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -145,7 +145,6 @@ module Blacklight
|
|
145
145
|
end
|
146
146
|
|
147
147
|
@table[:reflected_fields] ||= Rails.cache.fetch("blacklight_configuration/admin/reflected_fields", expires_in: 1.hour) do
|
148
|
-
repository = repository_class.new(self)
|
149
148
|
repository.reflect_fields
|
150
149
|
rescue => e
|
151
150
|
Blacklight.logger&.warn "Error retrieving field metadata: #{e}"
|
@@ -14,7 +14,7 @@ module Blacklight
|
|
14
14
|
self.if = include_in_simple_select if self.if.nil?
|
15
15
|
|
16
16
|
super
|
17
|
-
self.qt ||= blacklight_config.default_solr_params[:qt] if blacklight_config
|
17
|
+
self.qt ||= blacklight_config.default_solr_params[:qt] if blacklight_config&.default_solr_params
|
18
18
|
|
19
19
|
self
|
20
20
|
end
|
@@ -24,7 +24,7 @@ class Blacklight::Configuration
|
|
24
24
|
# @return [Class] component class used to render the search bar
|
25
25
|
# @!attribute search_header_component
|
26
26
|
# @return [Class] component class used to render the header above the documents
|
27
|
-
def display_label(**
|
27
|
+
def display_label(**)
|
28
28
|
I18n.t(
|
29
29
|
:"blacklight.search.view_title.#{key}",
|
30
30
|
default: [
|
@@ -33,7 +33,7 @@ class Blacklight::Configuration
|
|
33
33
|
title,
|
34
34
|
key.to_s.humanize
|
35
35
|
],
|
36
|
-
**
|
36
|
+
**
|
37
37
|
)
|
38
38
|
end
|
39
39
|
|
@@ -66,9 +66,6 @@ module Blacklight
|
|
66
66
|
|
67
67
|
# === Single document request configuration
|
68
68
|
|
69
|
-
# @!attribute document_solr_request_handler
|
70
|
-
# @return [String] The solr request handler to use when requesting only a single document
|
71
|
-
property :document_solr_request_handler, default: nil
|
72
69
|
# @!attribute document_solr_path
|
73
70
|
# @since v5.2.0
|
74
71
|
# @return [String] The url path (relative to the solr base url) to use when requesting only a single document
|
@@ -99,12 +96,12 @@ module Blacklight
|
|
99
96
|
##
|
100
97
|
# == Response models
|
101
98
|
|
102
|
-
# @!attribute repository_class
|
103
|
-
# @return [Class] Class for sending and receiving requests from a search index
|
104
|
-
property :repository_class, default: Blacklight::Solr::Repository
|
105
99
|
# @!attribute search_builder_class
|
106
100
|
# @return [Class] class for converting Blacklight parameters to request parameters for the repository_class
|
107
101
|
property :search_builder_class, default: ::SearchBuilder
|
102
|
+
# @!attribute search_builder_class
|
103
|
+
# @return [Class] class for converting Blacklight parameters to request parameters for the repository_class
|
104
|
+
property :facet_search_builder_class, default: ::FacetSearchBuilder
|
108
105
|
# @!attribute response_model
|
109
106
|
# model that maps index responses to the blacklight response model
|
110
107
|
# @return [Class]
|
@@ -165,6 +162,8 @@ module Blacklight
|
|
165
162
|
respond_to: OpenStructWithHashAccess.new,
|
166
163
|
# component class used to render the facet grouping
|
167
164
|
facet_group_component: Blacklight::Response::FacetGroupComponent,
|
165
|
+
# component class used to render the facet pagination
|
166
|
+
facet_pagination_component: Blacklight::FacetFieldPaginationComponent,
|
168
167
|
# component class used to render search constraints
|
169
168
|
constraints_component: Blacklight::ConstraintsComponent,
|
170
169
|
# component class used to render the search bar
|
@@ -380,7 +379,7 @@ module Blacklight
|
|
380
379
|
|
381
380
|
# @return [Blacklight::Repository]
|
382
381
|
def repository
|
383
|
-
repository_class.new(self)
|
382
|
+
Blacklight.repository_class.new(self)
|
384
383
|
end
|
385
384
|
|
386
385
|
# @return [String] The destination for the link around the logo in the header
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Blacklight
|
4
|
+
class FacetSearchBuilder < AbstractSearchBuilder
|
5
|
+
def facet_suggestion_query=(value)
|
6
|
+
params_will_change!
|
7
|
+
@facet_suggestion_query = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def facet_suggestion_query(value = nil)
|
11
|
+
if value
|
12
|
+
self.facet_suggestion_query = value
|
13
|
+
return self
|
14
|
+
end
|
15
|
+
@facet_suggestion_query
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -57,7 +57,7 @@ module Blacklight
|
|
57
57
|
self.class.new @table.deep_transform_values(&)
|
58
58
|
end
|
59
59
|
|
60
|
-
def try(method_name = nil,
|
60
|
+
def try(method_name = nil, *, &)
|
61
61
|
if method_name.nil? && block_given?
|
62
62
|
if b.arity.zero?
|
63
63
|
instance_eval(&)
|
@@ -65,7 +65,7 @@ module Blacklight
|
|
65
65
|
yield self
|
66
66
|
end
|
67
67
|
elsif respond_to?(method_name)
|
68
|
-
public_send(method_name,
|
68
|
+
public_send(method_name, *, &b)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -5,45 +5,7 @@ module Blacklight
|
|
5
5
|
# Blacklight's SearchBuilder converts blacklight request parameters into
|
6
6
|
# query parameters appropriate for search index. It does so by evaluating a
|
7
7
|
# chain of processing methods to populate a result hash (see {#to_hash}).
|
8
|
-
class SearchBuilder
|
9
|
-
class_attribute :default_processor_chain
|
10
|
-
self.default_processor_chain = []
|
11
|
-
|
12
|
-
attr_reader :processor_chain, :search_state, :blacklight_params
|
13
|
-
|
14
|
-
# @overload initialize(scope)
|
15
|
-
# @param [Object] scope scope the scope where the filter methods reside in.
|
16
|
-
# @overload initialize(processor_chain, scope)
|
17
|
-
# @param [List<Symbol>,TrueClass] processor_chain options a list of filter methods to run or true, to use the default methods
|
18
|
-
# @param [Object] scope the scope where the filter methods reside in.
|
19
|
-
def initialize(*options)
|
20
|
-
case options.size
|
21
|
-
when 1
|
22
|
-
@processor_chain = default_processor_chain.dup
|
23
|
-
@scope = options.first
|
24
|
-
when 2
|
25
|
-
@processor_chain, @scope = options
|
26
|
-
else
|
27
|
-
raise ArgumentError, "wrong number of arguments. (#{options.size} for 1..2)"
|
28
|
-
end
|
29
|
-
|
30
|
-
@blacklight_params = {}
|
31
|
-
search_state_class = @scope.try(:search_state_class) || Blacklight::SearchState
|
32
|
-
@search_state = search_state_class.new(@blacklight_params, @scope&.blacklight_config, @scope)
|
33
|
-
@additional_filters = {}
|
34
|
-
@merged_params = {}
|
35
|
-
@reverse_merged_params = {}
|
36
|
-
end
|
37
|
-
|
38
|
-
##
|
39
|
-
# Set the parameters to pass through the processor chain
|
40
|
-
def with(blacklight_params_or_search_state = {})
|
41
|
-
params_will_change!
|
42
|
-
@search_state = blacklight_params_or_search_state.is_a?(Blacklight::SearchState) ? blacklight_params_or_search_state : @search_state.reset(blacklight_params_or_search_state)
|
43
|
-
@blacklight_params = @search_state.params.dup
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
8
|
+
class SearchBuilder < AbstractSearchBuilder
|
47
9
|
##
|
48
10
|
# Update the :q (query) parameter
|
49
11
|
# @param [Hash<Symbol,Object>] conditions the field and values to query on
|
@@ -93,68 +55,6 @@ module Blacklight
|
|
93
55
|
builder
|
94
56
|
end
|
95
57
|
|
96
|
-
##
|
97
|
-
# Merge additional, repository-specific parameters
|
98
|
-
def merge(extra_params, &)
|
99
|
-
if extra_params
|
100
|
-
params_will_change!
|
101
|
-
@merged_params.merge!(extra_params.to_hash, &)
|
102
|
-
end
|
103
|
-
self
|
104
|
-
end
|
105
|
-
|
106
|
-
##
|
107
|
-
# "Reverse merge" additional, repository-specific parameters
|
108
|
-
def reverse_merge(extra_params, &)
|
109
|
-
if extra_params
|
110
|
-
params_will_change!
|
111
|
-
@reverse_merged_params.reverse_merge!(extra_params.to_hash, &)
|
112
|
-
end
|
113
|
-
self
|
114
|
-
end
|
115
|
-
|
116
|
-
delegate :[], :key?, to: :to_hash
|
117
|
-
|
118
|
-
# a solr query method
|
119
|
-
# @return [Blacklight::Solr::Response] the solr response object
|
120
|
-
def to_hash
|
121
|
-
return @params unless params_need_update?
|
122
|
-
|
123
|
-
@params = processed_parameters
|
124
|
-
.reverse_merge(@reverse_merged_params)
|
125
|
-
.merge(@merged_params)
|
126
|
-
.tap { clear_changes }
|
127
|
-
end
|
128
|
-
|
129
|
-
alias_method :query, :to_hash
|
130
|
-
alias_method :to_h, :to_hash
|
131
|
-
|
132
|
-
# The CatalogController #index action uses this.
|
133
|
-
# Solr parameters can come from a number of places. From lowest
|
134
|
-
# precedence to highest:
|
135
|
-
# 1. General defaults in blacklight config (are trumped by)
|
136
|
-
# 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
|
137
|
-
# 3. certain parameters directly on input HTTP query params
|
138
|
-
# * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
|
139
|
-
# * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
|
140
|
-
# 4. extra parameters passed in as argument.
|
141
|
-
#
|
142
|
-
# spellcheck.q will be supplied with the [:q] value unless specifically
|
143
|
-
# specified otherwise.
|
144
|
-
#
|
145
|
-
# Incoming parameter :f is mapped to :fq solr parameter.
|
146
|
-
#
|
147
|
-
# @return a params hash for searching solr.
|
148
|
-
def processed_parameters
|
149
|
-
request.tap do |request_parameters|
|
150
|
-
processor_chain.each do |method_name|
|
151
|
-
send(method_name, request_parameters)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
delegate :blacklight_config, to: :scope
|
157
|
-
|
158
58
|
def start=(value)
|
159
59
|
params_will_change!
|
160
60
|
@start = value.to_i
|
@@ -209,34 +109,6 @@ module Blacklight
|
|
209
109
|
|
210
110
|
alias per rows
|
211
111
|
|
212
|
-
# sets the facet that this query pertains to, for the purpose of facet pagination
|
213
|
-
def facet=(value)
|
214
|
-
params_will_change!
|
215
|
-
@facet = value
|
216
|
-
end
|
217
|
-
|
218
|
-
# @param [Object] value
|
219
|
-
def facet(value = nil)
|
220
|
-
if value
|
221
|
-
self.facet = value
|
222
|
-
return self
|
223
|
-
end
|
224
|
-
@facet
|
225
|
-
end
|
226
|
-
|
227
|
-
def facet_suggestion_query=(value)
|
228
|
-
params_will_change!
|
229
|
-
@facet_suggestion_query = value
|
230
|
-
end
|
231
|
-
|
232
|
-
def facet_suggestion_query(value = nil)
|
233
|
-
if value
|
234
|
-
self.facet_suggestion_query = value
|
235
|
-
return self
|
236
|
-
end
|
237
|
-
@facet_suggestion_query
|
238
|
-
end
|
239
|
-
|
240
112
|
# Decode the user provided 'sort' parameter into a sort string that can be
|
241
113
|
# passed to the search. This sanitizes the input by ensuring only
|
242
114
|
# configured search values are passed through to the search.
|
@@ -244,35 +116,5 @@ module Blacklight
|
|
244
116
|
def sort
|
245
117
|
search_state.sort_field&.sort
|
246
118
|
end
|
247
|
-
|
248
|
-
delegate :search_field, to: :search_state
|
249
|
-
|
250
|
-
private
|
251
|
-
|
252
|
-
def request
|
253
|
-
Blacklight::Solr::Request.new
|
254
|
-
end
|
255
|
-
|
256
|
-
def should_add_field_to_request? _field_name, field
|
257
|
-
field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request)
|
258
|
-
end
|
259
|
-
|
260
|
-
attr_reader :scope
|
261
|
-
|
262
|
-
def params_will_change!
|
263
|
-
@dirty = true
|
264
|
-
end
|
265
|
-
|
266
|
-
def params_changed?
|
267
|
-
!!@dirty
|
268
|
-
end
|
269
|
-
|
270
|
-
def params_need_update?
|
271
|
-
params_changed? || @params.nil?
|
272
|
-
end
|
273
|
-
|
274
|
-
def clear_changes
|
275
|
-
@dirty = false
|
276
|
-
end
|
277
119
|
end
|
278
120
|
end
|
@@ -120,8 +120,8 @@ module Blacklight
|
|
120
120
|
delegate :any?, to: :values
|
121
121
|
|
122
122
|
# Appease rubocop rules by implementing #each_value
|
123
|
-
def each_value(except: [], &
|
124
|
-
values(except: except).each(&
|
123
|
+
def each_value(except: [], &)
|
124
|
+
values(except: except).each(&)
|
125
125
|
end
|
126
126
|
|
127
127
|
# @param [String,#value] item a filter to remove from the url
|
@@ -145,8 +145,8 @@ module Blacklight
|
|
145
145
|
def permitted_params
|
146
146
|
if config.pivot
|
147
147
|
{
|
148
|
-
filters_key => config.pivot.each_with_object({}) { |key, filter| filter.merge(key => [], "-#{key}" => []) },
|
149
|
-
inclusive_filters_key => config.pivot.each_with_object({}) { |key, filter| filter.merge(key => []) }
|
148
|
+
filters_key => config.pivot.each_with_object({}) { |key, filter| filter.merge!(key => [], "-#{key}" => []) },
|
149
|
+
inclusive_filters_key => config.pivot.each_with_object({}) { |key, filter| filter.merge!(key => []) }
|
150
150
|
}
|
151
151
|
else
|
152
152
|
{
|
@@ -89,16 +89,16 @@ module Blacklight
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
class QueryBuilder
|
92
|
+
class QueryBuilder < Solr::AbstractFilterQueryBuilder
|
93
93
|
# @return [Array] filter_query, subqueries
|
94
|
-
def
|
94
|
+
def call(filter, solr_parameters)
|
95
95
|
existing = solr_parameters['fq']&.dup || []
|
96
96
|
queries = []
|
97
97
|
filter.values.compact_blank.each do |value|
|
98
|
-
queries <<
|
98
|
+
queries << facet_value_to_fq_string(filter.pivot.first, value.value)
|
99
99
|
value.fq.each do |entry|
|
100
100
|
k, v = entry
|
101
|
-
queries <<
|
101
|
+
queries << facet_value_to_fq_string(k, v) if v
|
102
102
|
end
|
103
103
|
queries.uniq!
|
104
104
|
end
|