blacklight 9.0.0.beta7 → 9.0.0.beta8
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/.docker/app/Dockerfile +2 -1
- data/.github/matrix.json +14 -3
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/blacklight.esm.js +7 -4
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +7 -4
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/components/blacklight/advanced_search_form_component.rb +2 -1
- data/app/components/blacklight/document_component.rb +10 -13
- data/app/components/blacklight/facets/filters_component.rb +1 -1
- data/app/components/blacklight/facets/suggest_component.rb +2 -3
- data/app/components/blacklight/metadata_field_component.html.erb +2 -2
- data/app/components/blacklight/metadata_field_component.rb +2 -1
- data/app/components/blacklight/metadata_field_layout_component.rb +9 -4
- data/app/components/blacklight/search_bar_component.html.erb +1 -1
- data/app/javascript/blacklight-frontend/modal.js +7 -4
- data/app/presenters/blacklight/document_presenter.rb +6 -5
- data/app/presenters/blacklight/facet_field_presenter.rb +10 -3
- data/app/presenters/blacklight/field_presenter.rb +4 -2
- data/app/presenters/blacklight/rendering/abstract_step.rb +7 -1
- data/app/presenters/blacklight/rendering/join.rb +9 -5
- data/app/presenters/blacklight/rendering/terminator.rb +1 -1
- data/app/views/catalog/_show_main_content.html.erb +9 -5
- data/app/views/catalog/index.html.erb +0 -1
- data/app/views/catalog/show.html.erb +2 -2
- data/config/locales/blacklight.en.yml +1 -1
- data/lib/blacklight/component.rb +2 -0
- data/lib/blacklight/configuration/facet_field.rb +2 -0
- data/lib/blacklight/configuration/view_config.rb +30 -16
- data/lib/blacklight/configuration.rb +56 -5
- data/lib/blacklight/search_state/pivot_filter_field.rb +1 -1
- data/lib/blacklight/solr/field_reflection_search_builder.rb +11 -0
- data/lib/blacklight/solr/repository.rb +5 -5
- data/lib/blacklight/solr/search_builder_behavior.rb +19 -2
- data/lib/blacklight/solr/single_doc_search_builder.rb +25 -0
- data/lib/generators/blacklight/templates/catalog_controller.rb +26 -4
- data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -67
- data/package.json +1 -1
- data/spec/components/blacklight/document_component_spec.rb +0 -7
- data/spec/components/blacklight/facets/filters_component_spec.rb +2 -2
- data/spec/components/blacklight/facets/suggest_component_spec.rb +13 -0
- data/spec/components/blacklight/search_bar_component_spec.rb +24 -1
- data/spec/controllers/blacklight/catalog_spec.rb +1 -1
- data/spec/features/advanced_search_spec.rb +39 -20
- data/spec/models/blacklight/configuration_spec.rb +126 -0
- data/spec/models/blacklight/solr/repository_spec.rb +6 -0
- data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +52 -6
- data/spec/presenters/blacklight/document_presenter_spec.rb +3 -3
- data/spec/presenters/blacklight/field_presenter_spec.rb +103 -22
- data/spec/presenters/blacklight/rendering/pipeline_spec.rb +130 -14
- metadata +4 -5
- data/app/views/shared/_sitelinks_search_box.html.erb +0 -12
- data/spec/features/sitelinks_search_box_spec.rb +0 -13
|
@@ -160,11 +160,14 @@ const Modal = (() => {
|
|
|
160
160
|
|
|
161
161
|
// Make sure user-agent dismissal of html 'dialog', etc `esc` key, triggers
|
|
162
162
|
// our hide logic, including events and scroll restoration.
|
|
163
|
-
modal.target()
|
|
164
|
-
|
|
163
|
+
const modalDom = modal.target();
|
|
164
|
+
if (modalDom) {
|
|
165
|
+
modal.target().addEventListener('cancel', (e) => {
|
|
166
|
+
e.preventDefault(); // 'hide' will close the modal unless cancelled
|
|
165
167
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
+
modal.hide();
|
|
169
|
+
});
|
|
170
|
+
}
|
|
168
171
|
};
|
|
169
172
|
|
|
170
173
|
modal.hide = function (el) {
|
|
@@ -44,11 +44,11 @@ module Blacklight
|
|
|
44
44
|
#
|
|
45
45
|
# @return [String]
|
|
46
46
|
def heading
|
|
47
|
-
return field_value(view_config.title_field) if view_config.title_field.is_a? Blacklight::Configuration::Field
|
|
47
|
+
return field_value(view_config.title_field, join: true).first if view_config.title_field.is_a? Blacklight::Configuration::Field
|
|
48
48
|
|
|
49
49
|
fields = Array.wrap(view_config.title_field) + [configuration.document_model.unique_key]
|
|
50
50
|
f = fields.lazy.map { |field| field_config(field) }.detect { |field_config| field_presenter(field_config).any? }
|
|
51
|
-
f ? field_value(f, except_operations: [Rendering::HelperMethod]) : ""
|
|
51
|
+
f ? field_value(f, except_operations: [Rendering::HelperMethod], join: true).first : ""
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
##
|
|
@@ -58,12 +58,12 @@ module Blacklight
|
|
|
58
58
|
# @see #document_heading
|
|
59
59
|
# @return [String]
|
|
60
60
|
def html_title
|
|
61
|
-
return field_value(view_config.html_title_field) if view_config.html_title_field.is_a? Blacklight::Configuration::Field
|
|
61
|
+
return field_value(view_config.html_title_field, join: true).first if view_config.html_title_field.is_a? Blacklight::Configuration::Field
|
|
62
62
|
|
|
63
63
|
if view_config.html_title_field
|
|
64
64
|
fields = Array.wrap(view_config.html_title_field) + [configuration.document_model.unique_key]
|
|
65
65
|
f = fields.lazy.map { |field| field_config(field) }.detect { |field_config| field_presenter(field_config).any? }
|
|
66
|
-
field_value(f)
|
|
66
|
+
field_value(f, join: true).first
|
|
67
67
|
else
|
|
68
68
|
heading
|
|
69
69
|
end
|
|
@@ -93,8 +93,9 @@ module Blacklight
|
|
|
93
93
|
# @param [Configuration::Field] field_config
|
|
94
94
|
# @param [Hash] options
|
|
95
95
|
# @option options [String] :value
|
|
96
|
+
# @return [Array]
|
|
96
97
|
def field_value field_config, options = {}
|
|
97
|
-
field_presenter(field_config, options).render
|
|
98
|
+
Array.wrap(field_presenter(field_config, options).render)
|
|
98
99
|
end
|
|
99
100
|
|
|
100
101
|
def thumbnail_presenter_class
|
|
@@ -4,18 +4,18 @@ module Blacklight
|
|
|
4
4
|
class FacetFieldPresenter
|
|
5
5
|
attr_reader :facet_field, :display_facet, :view_context, :search_state
|
|
6
6
|
|
|
7
|
-
delegate :key,
|
|
7
|
+
delegate :key, to: :facet_field
|
|
8
8
|
delegate :field_name, to: :display_facet
|
|
9
9
|
|
|
10
10
|
# @param [Blacklight::Configuration::FacetField] facet_field
|
|
11
11
|
# @param [Blacklight::Solr::Response::Facets::FacetField] display_facet
|
|
12
12
|
# @param [#search_action_path,#facet_field_presenter] view_context
|
|
13
13
|
# @param [Blacklight::SearchState] search_state
|
|
14
|
-
def initialize(facet_field, display_facet, view_context, search_state =
|
|
14
|
+
def initialize(facet_field, display_facet, view_context, search_state = nil)
|
|
15
15
|
@facet_field = facet_field
|
|
16
16
|
@display_facet = display_facet
|
|
17
17
|
@view_context = view_context
|
|
18
|
-
@search_state = search_state
|
|
18
|
+
@search_state = search_state || view_context&.search_state
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# @param [Blacklight::Solr::Response::Facets::FacetItem, String] facet_item
|
|
@@ -23,6 +23,13 @@ module Blacklight
|
|
|
23
23
|
facet_field.item_presenter.new(facet_item, facet_field, view_context, key, search_state)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# Is facet suggest feature configured on for this facet, or by global default.
|
|
27
|
+
#
|
|
28
|
+
# @return [Boolean]
|
|
29
|
+
def suggest?
|
|
30
|
+
!!(facet_field.suggest.nil? ? blacklight_config.default_facet_suggest : facet_field.suggest)
|
|
31
|
+
end
|
|
32
|
+
|
|
26
33
|
def collapsed?
|
|
27
34
|
!active? && facet_field.collapse
|
|
28
35
|
end
|
|
@@ -33,9 +33,11 @@ module Blacklight
|
|
|
33
33
|
|
|
34
34
|
delegate :key, :component, to: :field_config
|
|
35
35
|
|
|
36
|
-
# @return [String]
|
|
36
|
+
# @return [Array<String>]
|
|
37
37
|
def render
|
|
38
|
-
|
|
38
|
+
Array.wrap(
|
|
39
|
+
Rendering::Pipeline.new(values, field_config, document, view_context, pipeline_steps, options).render
|
|
40
|
+
)
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
# @return [Enumerable]
|
|
@@ -22,7 +22,13 @@ module Blacklight
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def html?
|
|
25
|
-
|
|
25
|
+
format.nil? || format.to_s == 'html'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def format
|
|
29
|
+
return options[:format] unless context.respond_to?(:search_state)
|
|
30
|
+
|
|
31
|
+
options[:format] || context.search_state&.params&.dig(:format)
|
|
26
32
|
end
|
|
27
33
|
end
|
|
28
34
|
end
|
|
@@ -5,12 +5,11 @@ module Blacklight
|
|
|
5
5
|
class Join < AbstractStep
|
|
6
6
|
def render
|
|
7
7
|
options = config.separator_options || {}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
elsif !html?
|
|
11
|
-
next_step(values.to_sentence(options))
|
|
12
|
-
else
|
|
8
|
+
|
|
9
|
+
if join? && html? && values.many?
|
|
13
10
|
next_step(values.map { |x| x.html_safe? ? x : html_escape(x) }.to_sentence(options).html_safe)
|
|
11
|
+
else
|
|
12
|
+
next_step(values)
|
|
14
13
|
end
|
|
15
14
|
end
|
|
16
15
|
|
|
@@ -19,6 +18,11 @@ module Blacklight
|
|
|
19
18
|
def html_escape(*)
|
|
20
19
|
ERB::Util.html_escape(*)
|
|
21
20
|
end
|
|
21
|
+
|
|
22
|
+
# @return [Boolean]
|
|
23
|
+
def join?
|
|
24
|
+
options[:join] || config.join || config.separator_options
|
|
25
|
+
end
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
<%
|
|
1
|
+
<%# locals: (presenter: nil) %>
|
|
2
|
+
<% presenter ||= document_presenter(@document) %>
|
|
3
|
+
|
|
4
|
+
<% @page_title = t('blacklight.search.show.title', document_title: presenter.html_title, application_name: application_name).html_safe %>
|
|
3
5
|
<% content_for(:head) { render_link_rel_alternates } %>
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
<%= render presenter.view_config.document_header_component.new(document: @document, search_context: @search_context, search_session: search_session) %>
|
|
8
|
+
|
|
9
|
+
<% document_component = presenter.view_config.document_component -%>
|
|
10
|
+
<%= render document_component.new(id: 'document', document: presenter, component: :div, show: true, partials: presenter.view_config.partials) do |component| %>
|
|
7
11
|
<% component.with_title(as: 'h1', classes: '', link_to_document: false, actions: false) %>
|
|
8
12
|
<% component.with_footer do %>
|
|
9
13
|
<% if @document.respond_to?(:export_as_openurl_ctx_kev) %>
|
|
10
14
|
<!-- COinS, for Zotero among others. -->
|
|
11
|
-
<span class="Z3988" title="<%= @document.export_as_openurl_ctx_kev(
|
|
15
|
+
<span class="Z3988" title="<%= @document.export_as_openurl_ctx_kev(presenter.display_type) %>"></span>
|
|
12
16
|
<% end %>
|
|
13
17
|
<% end %>
|
|
14
18
|
<% end %>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
<% presenter = document_presenter(@document) %>
|
|
2
|
+
<%= render 'show_main_content', presenter: presenter %>
|
|
2
3
|
|
|
3
4
|
<% content_for(:sidebar) do %>
|
|
4
|
-
<% presenter = document_presenter(@document) %>
|
|
5
5
|
<%= render presenter.view_config.sidebar_component.new(presenter: presenter) %>
|
|
6
6
|
<% end %>
|
data/lib/blacklight/component.rb
CHANGED
|
@@ -16,6 +16,8 @@ module Blacklight
|
|
|
16
16
|
# @return [Boolean] whether to show the facet to the user or not (very similar to the more generic if/unless)
|
|
17
17
|
# @!attribute index_range
|
|
18
18
|
# @return [Enumerable] a list of facet prefixes (default: A-Z) to allow users to 'jump' to particular values
|
|
19
|
+
# @!attribute suggest
|
|
20
|
+
# @return [Boolean] whether to display a suggest/autocomplete on the detailed facet view that allows users to filter facet values
|
|
19
21
|
# @!attribute date
|
|
20
22
|
# @return [Symbol|Hash] the i18n localization option for a date or time value; used as the second parameter for the I18n.l method
|
|
21
23
|
# @!attribute link_to_facet
|
|
@@ -8,6 +8,14 @@ class Blacklight::Configuration
|
|
|
8
8
|
# @return [Class] document presenter class used by helpers and views
|
|
9
9
|
# @!attribute document_component
|
|
10
10
|
# @return [Class] component class used to render a document; defaults to Blacklight::DocumentComponent
|
|
11
|
+
# @!attribute document_title_component
|
|
12
|
+
# @return [Class] component class used to render a document title
|
|
13
|
+
# @!attribute document_metadata_component
|
|
14
|
+
# @return [Class] component class used to render the document metadata
|
|
15
|
+
# @!attribute document_thumbnail_component
|
|
16
|
+
# @return [Class] component class used to render a document thumbnail
|
|
17
|
+
# @!attribute document_embed_component
|
|
18
|
+
# @return [Class] component class used to render a document embed
|
|
11
19
|
# @!attribute title_field
|
|
12
20
|
# @return [String, Symbol] solr field to use to render a document title
|
|
13
21
|
# @!attribute display_type_field
|
|
@@ -46,19 +54,33 @@ class Blacklight::Configuration
|
|
|
46
54
|
end
|
|
47
55
|
end
|
|
48
56
|
|
|
57
|
+
# Provide backwards compatibility with the configuration keys without the document_ prefix
|
|
58
|
+
def title_component(*) = document_title_component(*)
|
|
59
|
+
def metadata_component(*) = document_metadata_component(*)
|
|
60
|
+
def thumbnail_component(*) = document_thumbnail_component(*)
|
|
61
|
+
def embed_component(*) = document_embed_component(*)
|
|
62
|
+
|
|
63
|
+
def title_component=(value)
|
|
64
|
+
self.document_title_component = value
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def metadata_component=(value)
|
|
68
|
+
self.document_metadata_component = value
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def thumbnail_component=(value)
|
|
72
|
+
self.document_thumbnail_component = value
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def embed_component=(value)
|
|
76
|
+
self.document_embed_component = value
|
|
77
|
+
end
|
|
78
|
+
|
|
49
79
|
class Show < ViewConfig
|
|
50
80
|
# @!attribute route
|
|
51
81
|
# @return [Hash] Default route parameters for 'show' requests.
|
|
52
82
|
# Set this to a hash with additional arguments to merge into the route,
|
|
53
83
|
# or set `controller: :current` to route to the current controller.
|
|
54
|
-
|
|
55
|
-
def document_presenter_class
|
|
56
|
-
super || Blacklight::ShowPresenter
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def to_h
|
|
60
|
-
super.merge(document_presenter_class: document_presenter_class)
|
|
61
|
-
end
|
|
62
84
|
end
|
|
63
85
|
|
|
64
86
|
class Index < ViewConfig
|
|
@@ -69,14 +91,6 @@ class Blacklight::Configuration
|
|
|
69
91
|
# see Blacklight::Catalog#additional_response_formats for information about the OpenStruct data
|
|
70
92
|
# @!attribute collection_actions
|
|
71
93
|
# @return [String, Symbol]
|
|
72
|
-
|
|
73
|
-
def document_presenter_class
|
|
74
|
-
super || Blacklight::IndexPresenter
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def to_h
|
|
78
|
-
super.merge(document_presenter_class: document_presenter_class)
|
|
79
|
-
end
|
|
80
94
|
end
|
|
81
95
|
end
|
|
82
96
|
end
|
|
@@ -73,7 +73,8 @@ module Blacklight
|
|
|
73
73
|
# @!attribute json_solr_path
|
|
74
74
|
# @since v7.34.0
|
|
75
75
|
# @return [String] The url path (relative to the solr base url) to use when using Solr's JSON Query DSL (as with the advanced search)
|
|
76
|
-
|
|
76
|
+
# @note You can configure a separate custom 'advanced' requestHandler in solrconfig.xml if desired, but it isn't necessary; the default 'select' handler will work.
|
|
77
|
+
property :json_solr_path, default: 'select'
|
|
77
78
|
# @!attribute document_unique_id_param
|
|
78
79
|
# @since v5.2.0
|
|
79
80
|
# @return [Symbol] The solr query parameter used for sending the unique identifiers for one or more documents
|
|
@@ -147,11 +148,15 @@ module Blacklight
|
|
|
147
148
|
# @return [Blacklight::Configuration::ViewConfig::Index]
|
|
148
149
|
property :index, default: ViewConfig::Index.new(
|
|
149
150
|
# document presenter class used by helpers and views
|
|
150
|
-
document_presenter_class:
|
|
151
|
+
document_presenter_class: Blacklight::IndexPresenter,
|
|
151
152
|
# document presenter used for json responses
|
|
152
153
|
json_presenter_class: Blacklight::JsonPresenter,
|
|
153
154
|
# component class used to render a document
|
|
154
155
|
document_component: Blacklight::DocumentComponent,
|
|
156
|
+
document_embed_component: nil,
|
|
157
|
+
document_metadata_component: Blacklight::DocumentMetadataComponent,
|
|
158
|
+
document_thumbnail_component: Blacklight::Document::ThumbnailComponent,
|
|
159
|
+
document_title_component: Blacklight::DocumentTitleComponent,
|
|
155
160
|
sidebar_component: Blacklight::Search::SidebarComponent,
|
|
156
161
|
dropdown_component: Blacklight::System::DropdownComponent,
|
|
157
162
|
# solr field to use to render a document title
|
|
@@ -187,8 +192,9 @@ module Blacklight
|
|
|
187
192
|
# @return [Blacklight::Configuration::ViewConfig::Show]
|
|
188
193
|
property :show, default: ViewConfig::Show.new(
|
|
189
194
|
# document presenter class used by helpers and views
|
|
190
|
-
document_presenter_class:
|
|
195
|
+
document_presenter_class: Blacklight::ShowPresenter,
|
|
191
196
|
document_component: Blacklight::DocumentComponent,
|
|
197
|
+
document_thumbnail_component: nil,
|
|
192
198
|
show_tools_component: Blacklight::Document::ShowToolsComponent,
|
|
193
199
|
show_header_tools_component: nil,
|
|
194
200
|
document_header_component: Blacklight::Document::PageHeaderComponent,
|
|
@@ -269,6 +275,10 @@ module Blacklight
|
|
|
269
275
|
# @since v5.10.0
|
|
270
276
|
# @return [Integer]
|
|
271
277
|
property :default_facet_limit, default: 10
|
|
278
|
+
# @!attribute default_facet_suggest
|
|
279
|
+
# @since v9.0.0
|
|
280
|
+
# @return [Boolean]
|
|
281
|
+
property :default_facet_suggest, default: true
|
|
272
282
|
# @!attribute default_more_limit
|
|
273
283
|
# @since v7.0.0
|
|
274
284
|
# @return [Integer]
|
|
@@ -299,8 +309,13 @@ module Blacklight
|
|
|
299
309
|
|
|
300
310
|
# @!attribute advanced_search
|
|
301
311
|
# @since v7.15.0
|
|
302
|
-
# @return [
|
|
303
|
-
|
|
312
|
+
# @return [OpenStructWithHashAccess] Configuration for advanced search, including:
|
|
313
|
+
# enabled: (Boolean) whether advanced search is enabled
|
|
314
|
+
# form_solr_parameters: (Hash) optional parameters to send to Solr for the advanced search
|
|
315
|
+
# form; can override values that are set automatically via the
|
|
316
|
+
# #copy_facet_field_config_to_advanced! method
|
|
317
|
+
property :advanced_search, default: OpenStructWithHashAccess.new(enabled: true,
|
|
318
|
+
form_solr_parameters: {})
|
|
304
319
|
|
|
305
320
|
# @!attribute enable_search_bar_autofocus
|
|
306
321
|
# @since v7.2.0
|
|
@@ -457,6 +472,42 @@ module Blacklight
|
|
|
457
472
|
facet_fields.map { |_facet, opts| opts[:group] }.uniq
|
|
458
473
|
end
|
|
459
474
|
|
|
475
|
+
# Use existing search field configs to automatically prepare fields for use
|
|
476
|
+
# by the advanced search form.
|
|
477
|
+
def copy_search_field_config_to_advanced!
|
|
478
|
+
search_fields.each_value do |field|
|
|
479
|
+
next if field.include_in_advanced_search == false
|
|
480
|
+
next if field.clause_params
|
|
481
|
+
|
|
482
|
+
field.clause_params = {}
|
|
483
|
+
field.clause_params[:edismax] = field.solr_parameters.dup || {}
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
# Use existing facet field configs to automatically prepare fields for use
|
|
488
|
+
# by the advanced search form. If more specific config is needed, e.g., to
|
|
489
|
+
# set the facet limit for one field to a value other than -1, it can be
|
|
490
|
+
# expressed in the configuration in advanced_search.form_solr_parameters
|
|
491
|
+
def copy_facet_field_config_to_advanced!
|
|
492
|
+
advanced_search.form_solr_parameters ||= {}
|
|
493
|
+
advanced_search.form_solr_parameters['facet.sort'] ||= 'count'
|
|
494
|
+
advanced_search.form_solr_parameters['facet.field'] ||= []
|
|
495
|
+
|
|
496
|
+
facet_fields.each_value do |field|
|
|
497
|
+
next if field.include_in_advanced_search == false
|
|
498
|
+
# Skip query-type and pivot facets that can't be requested via facet.field
|
|
499
|
+
next if field.query || field.pivot || field.range
|
|
500
|
+
|
|
501
|
+
# Add the facet field to the advanced search configuration
|
|
502
|
+
advanced_search.form_solr_parameters['facet.field'] << field.field unless
|
|
503
|
+
advanced_search.form_solr_parameters['facet.field'].include?(field.field)
|
|
504
|
+
|
|
505
|
+
# Set the facet field's limit to -1 to show ALL values in advanced search
|
|
506
|
+
advanced_search.form_solr_parameters["f.#{field.field}.facet.limit"] = -1 unless
|
|
507
|
+
advanced_search.form_solr_parameters["f.#{field.field}.facet.limit"]
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
460
511
|
# Add any configured facet fields to the default solr parameters hash
|
|
461
512
|
# @overload add_facet_fields_to_solr_request!
|
|
462
513
|
# add all facet fields to the solr request
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Blacklight::Solr
|
|
4
|
+
class FieldReflectionSearchBuilder < SearchBuilder
|
|
5
|
+
self.default_processor_chain = [:add_params]
|
|
6
|
+
|
|
7
|
+
def add_params(request)
|
|
8
|
+
request.reverse_merge!({ fl: '*', 'json.nl' => 'map' })
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -7,8 +7,7 @@ module Blacklight::Solr
|
|
|
7
7
|
# @param [String] id document's unique key value
|
|
8
8
|
# @param [Hash] params additional solr query parameters
|
|
9
9
|
def find id, params = {}
|
|
10
|
-
doc_params =
|
|
11
|
-
.merge(blacklight_config.document_unique_id_param => id)
|
|
10
|
+
doc_params = SingleDocSearchBuilder.new(self, id, params)
|
|
12
11
|
|
|
13
12
|
solr_response = send_and_receive blacklight_config.document_solr_path || blacklight_config.solr_path, doc_params
|
|
14
13
|
raise Blacklight::Exceptions::RecordNotFound if solr_response.documents.empty?
|
|
@@ -24,14 +23,14 @@ module Blacklight::Solr
|
|
|
24
23
|
|
|
25
24
|
##
|
|
26
25
|
# Execute a search query against solr
|
|
27
|
-
# @param [Hash] params solr query parameters
|
|
26
|
+
# @param [Hash,Blacklight::SearchBuilder] params solr query parameters
|
|
28
27
|
# @param [String] path solr request handler path
|
|
29
28
|
def search pos_params = nil, path: nil, params: nil, **kwargs
|
|
30
29
|
if pos_params
|
|
31
30
|
Blacklight.deprecation.warn("Passing positional arguments to search() is deprecated. Use the params kwarg instead.")
|
|
32
31
|
end
|
|
33
32
|
|
|
34
|
-
request_params = (params || pos_params).reverse_merge(kwargs).reverse_merge({ qt: blacklight_config.qt })
|
|
33
|
+
request_params = (params || pos_params || {}).reverse_merge(kwargs).reverse_merge({ qt: blacklight_config.qt })
|
|
35
34
|
|
|
36
35
|
send_and_receive(path || default_search_path(request_params), request_params)
|
|
37
36
|
end
|
|
@@ -47,7 +46,8 @@ module Blacklight::Solr
|
|
|
47
46
|
# Gets a list of available fields
|
|
48
47
|
# @return [Hash]
|
|
49
48
|
def reflect_fields
|
|
50
|
-
|
|
49
|
+
doc_params = FieldReflectionSearchBuilder.new(self)
|
|
50
|
+
send_and_receive('admin/luke', doc_params)['fields']
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
##
|
|
@@ -10,7 +10,7 @@ module Blacklight::Solr
|
|
|
10
10
|
:add_query_to_solr, :add_facet_fq_to_solr,
|
|
11
11
|
:add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr,
|
|
12
12
|
:add_sorting_to_solr, :add_group_config_to_solr,
|
|
13
|
-
:add_adv_search_clauses,
|
|
13
|
+
:add_adv_search_clauses, :add_facets_for_advanced_search_form,
|
|
14
14
|
:add_additional_filters
|
|
15
15
|
]
|
|
16
16
|
end
|
|
@@ -95,6 +95,13 @@ module Blacklight::Solr
|
|
|
95
95
|
def add_adv_search_clauses(solr_parameters)
|
|
96
96
|
return if search_state.clause_params.blank?
|
|
97
97
|
|
|
98
|
+
# We need to specify lucene as the top-level defType when using JSON Query DSL in Solr versions
|
|
99
|
+
# between 7.2.0 & 9.4.0. After 9.4.0 this is no longer necessary, but also not harmful to include.
|
|
100
|
+
solr_parameters[:defType] = 'lucene'
|
|
101
|
+
|
|
102
|
+
# Disable spellcheck, which doesn't work when using JSON Query DSL
|
|
103
|
+
solr_parameters[:spellcheck] = 'false'
|
|
104
|
+
|
|
98
105
|
defaults = { must: [], must_not: [], should: [] }
|
|
99
106
|
default_op = blacklight_params[:op]&.to_sym || :must
|
|
100
107
|
solr_parameters[:mm] = 1 if default_op == :should && search_state.clause_params.values.any? { |clause| }
|
|
@@ -117,6 +124,16 @@ module Blacklight::Solr
|
|
|
117
124
|
[op, field.clause_params.transform_values { |v| v.merge(query: clause[:query]) }]
|
|
118
125
|
end
|
|
119
126
|
|
|
127
|
+
# Merge the advanced search form parameters into the solr parameters
|
|
128
|
+
# @param [Hash] solr_parameters the current solr parameters
|
|
129
|
+
# @return [Hash] the solr parameters with the additional advanced search form parameters
|
|
130
|
+
def add_facets_for_advanced_search_form(solr_parameters)
|
|
131
|
+
return unless search_state.controller&.action_name == 'advanced_search' &&
|
|
132
|
+
blacklight_config.advanced_search[:form_solr_parameters]
|
|
133
|
+
|
|
134
|
+
solr_parameters.merge!(blacklight_config.advanced_search[:form_solr_parameters])
|
|
135
|
+
end
|
|
136
|
+
|
|
120
137
|
##
|
|
121
138
|
# Add any existing facet limits, stored in app-level HTTP query
|
|
122
139
|
# as :f, to solr as appropriate :fq query.
|
|
@@ -243,7 +260,7 @@ module Blacklight::Solr
|
|
|
243
260
|
|
|
244
261
|
# Look up facet limit for given facet_field. Will look at config, and
|
|
245
262
|
# if config is 'true' will look up from Solr @response if available. If
|
|
246
|
-
# no limit is
|
|
263
|
+
# no limit is available, returns nil. Used from #add_facetting_to_solr
|
|
247
264
|
# to supply f.fieldname.facet.limit values in solr request (no @response
|
|
248
265
|
# available), and used in display (with @response available) to create
|
|
249
266
|
# a facet paginator with the right limit.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Blacklight::Solr
|
|
4
|
+
class SingleDocSearchBuilder < SearchBuilder
|
|
5
|
+
self.default_processor_chain = [:add_defaults, :add_qt, :add_unique_id]
|
|
6
|
+
|
|
7
|
+
def initialize(scope, id, other_params)
|
|
8
|
+
@other_params = other_params
|
|
9
|
+
@id = id
|
|
10
|
+
super(scope)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add_defaults(request)
|
|
14
|
+
request.reverse_merge!(blacklight_config.default_document_solr_params).reverse_merge!(@other_params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_qt(request)
|
|
18
|
+
request[:qt] ||= blacklight_config.document_solr_request_handler if blacklight_config.document_solr_request_handler
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def add_unique_id(request)
|
|
22
|
+
request[blacklight_config.document_unique_id_param] = @id
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -29,6 +29,13 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
29
29
|
#
|
|
30
30
|
## Should the raw solr document endpoint (e.g. /catalog/:id/raw) be enabled
|
|
31
31
|
# config.raw_endpoint.enabled = false
|
|
32
|
+
#
|
|
33
|
+
## Should advanced search be enabled
|
|
34
|
+
# config.advanced_search.enabled = true
|
|
35
|
+
#
|
|
36
|
+
## Optional fine-tuning for advanced search, e.g., set different limits for
|
|
37
|
+
## different facets.
|
|
38
|
+
# config.advanced_search.form_solr_parameters = {}
|
|
32
39
|
|
|
33
40
|
## Default parameters to send to solr for all search-like requests. See also SearchBuilder#processed_parameters
|
|
34
41
|
config.default_solr_params = {
|
|
@@ -38,7 +45,7 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
38
45
|
# solr path which will be added to solr base url before the other solr params.
|
|
39
46
|
#config.solr_path = 'select'
|
|
40
47
|
#config.document_solr_path = 'get'
|
|
41
|
-
#config.json_solr_path = '
|
|
48
|
+
#config.json_solr_path = 'select'
|
|
42
49
|
|
|
43
50
|
# items to show per page, each number in the array represent another option to choose from.
|
|
44
51
|
#config.per_page = [10,20,50,100]
|
|
@@ -105,6 +112,12 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
105
112
|
# :show may be set to false if you don't want the facet to be drawn in the
|
|
106
113
|
# facet bar
|
|
107
114
|
#
|
|
115
|
+
# Set :include_in_advanced_search to false for any search field or facet field
|
|
116
|
+
# that you want to exclude from appearing in the advanced search page.
|
|
117
|
+
#
|
|
118
|
+
# Set :include_in_simple_select to false for any search field you want to render
|
|
119
|
+
# in the Advanced Search page but exclude from the main search box scope selector.
|
|
120
|
+
#
|
|
108
121
|
# Set :index_range to true if you want the facet pagination view to have facet prefix-based navigation.
|
|
109
122
|
# (useful when user clicks "more" on a large facet and wants to navigate alphabetically across a large set of results)
|
|
110
123
|
# :index_range can be an array or range of prefixes that will be used to create the navigation (note: It is case sensitive when searching values)
|
|
@@ -121,7 +134,9 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
121
134
|
|
|
122
135
|
config.add_facet_field 'example_pivot_field',
|
|
123
136
|
label: 'Pivot Field',
|
|
124
|
-
pivot: ['language_ssim', 'subject_geo_ssim', 'subject_ssim'],
|
|
137
|
+
pivot: ['language_ssim', 'subject_geo_ssim', 'subject_ssim'],
|
|
138
|
+
collapsing: true,
|
|
139
|
+
include_in_advanced_search: false
|
|
125
140
|
|
|
126
141
|
config.add_facet_field 'example_query_facet_field', label: 'Publish Date', :query => {
|
|
127
142
|
:years_5 => { label: 'within 5 Years', fq: "pub_date_ssim:[#{Time.zone.now.year - 5 } TO *]" },
|
|
@@ -165,7 +180,7 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
165
180
|
config.add_show_field 'isbn_ssim', label: 'ISBN'
|
|
166
181
|
|
|
167
182
|
# "fielded" search configuration. Used by pulldown among other places.
|
|
168
|
-
# For supported keys in hash, see rdoc for Blacklight::
|
|
183
|
+
# For supported keys in hash, see rdoc for Blacklight::Configuration::SearchField
|
|
169
184
|
#
|
|
170
185
|
# Search fields will inherit the :qt solr request handler from
|
|
171
186
|
# config[:default_solr_parameters], OR can specify a different one
|
|
@@ -208,7 +223,7 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
208
223
|
|
|
209
224
|
# Specifying a :qt only to show it's possible, and so our internal automated
|
|
210
225
|
# tests can test it. In this case it's the same as
|
|
211
|
-
# config[:default_solr_parameters][:qt], so isn't actually
|
|
226
|
+
# config[:default_solr_parameters][:qt], so isn't actually necessary.
|
|
212
227
|
config.add_search_field('subject') do |field|
|
|
213
228
|
field.qt = 'search'
|
|
214
229
|
field.solr_parameters = {
|
|
@@ -218,6 +233,13 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
218
233
|
}
|
|
219
234
|
end
|
|
220
235
|
|
|
236
|
+
# Set up a default advanced search configuration by using the current
|
|
237
|
+
# search_fields and facet_fields configs.
|
|
238
|
+
if config.advanced_search.enabled
|
|
239
|
+
config.copy_search_field_config_to_advanced!
|
|
240
|
+
config.copy_facet_field_config_to_advanced!
|
|
241
|
+
end
|
|
242
|
+
|
|
221
243
|
# "sort results by" select (pulldown)
|
|
222
244
|
# label in pulldown is followed by the name of the Solr field to sort by and
|
|
223
245
|
# whether the sort is ascending or descending (it must be asc or desc
|