blacklight 5.1.1 → 5.2.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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/search_context.js +38 -24
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +49 -70
- data/app/helpers/blacklight/catalog_helper_behavior.rb +1 -8
- data/app/helpers/blacklight/configuration_helper_behavior.rb +10 -2
- data/app/helpers/blacklight/facets_helper_behavior.rb +4 -1
- data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +2 -2
- data/app/helpers/blacklight/url_helper_behavior.rb +41 -7
- data/app/views/catalog/_facet_layout.html.erb +2 -2
- data/app/views/catalog/_per_page_widget.html.erb +4 -4
- data/app/views/catalog/_previous_next_doc.html.erb +1 -1
- data/app/views/catalog/_show_tools.html.erb +1 -1
- data/app/views/catalog/show.html.erb +1 -1
- data/app/views/layouts/blacklight.html.erb +1 -1
- data/blacklight.gemspec +1 -1
- data/config/jetty.yml +3 -0
- data/config/locales/blacklight.es.yml +220 -0
- data/gemfiles/rails4.1.gemfile +10 -0
- data/lib/blacklight/base.rb +1 -1
- data/lib/blacklight/catalog/search_context.rb +15 -15
- data/lib/blacklight/catalog.rb +19 -6
- data/lib/blacklight/configuration.rb +126 -31
- data/lib/blacklight/document_presenter.rb +168 -0
- data/lib/blacklight/request_builders.rb +288 -0
- data/lib/blacklight/routes.rb +6 -2
- data/lib/blacklight/solr/request.rb +1 -1
- data/lib/blacklight/solr_helper.rb +50 -323
- data/lib/blacklight/solr_response/facets.rb +7 -3
- data/lib/blacklight/utils.rb +39 -7
- data/lib/blacklight.rb +5 -3
- data/lib/generators/blacklight/install_generator.rb +17 -5
- data/lib/generators/blacklight/models_generator.rb +0 -1
- data/lib/generators/blacklight/templates/catalog_controller.rb +6 -0
- data/lib/generators/blacklight/templates/config/jetty.yml +8 -4
- data/lib/generators/blacklight/templates/config/solr.yml +2 -0
- data/spec/controllers/catalog_controller_spec.rb +41 -22
- data/spec/features/alternate_controller_spec.rb +1 -1
- data/spec/features/search_filters_spec.rb +24 -24
- data/spec/features/search_results_spec.rb +9 -4
- data/spec/features/search_sort_spec.rb +1 -1
- data/spec/helpers/blacklight_helper_spec.rb +87 -0
- data/spec/helpers/catalog_helper_spec.rb +5 -10
- data/spec/helpers/configuration_helper_spec.rb +22 -1
- data/spec/helpers/facets_helper_spec.rb +6 -0
- data/spec/helpers/render_constraints_helper_spec.rb +1 -2
- data/spec/helpers/url_helper_spec.rb +45 -2
- data/spec/lib/blacklight/routes_spec.rb +4 -4
- data/spec/lib/blacklight/solr_helper_spec.rb +364 -253
- data/spec/lib/blacklight/solr_response/facets_spec.rb +82 -0
- data/spec/lib/blacklight/solr_response_spec.rb +3 -1
- data/spec/lib/document_presenter_spec.rb +216 -0
- data/spec/lib/utils_spec.rb +8 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
- data/spec/views/catalog/index.html.erb_spec.rb +29 -21
- data/spec/views/catalog/show.html.erb_spec.rb +11 -7
- data/template.demo.rb +20 -0
- metadata +12 -4
- data/lib/generators/blacklight/jetty_generator.rb +0 -70
@@ -48,26 +48,15 @@ module Blacklight::SolrHelper
|
|
48
48
|
extend ActiveSupport::Concern
|
49
49
|
include Blacklight::SearchFields
|
50
50
|
include Blacklight::Facet
|
51
|
+
include ActiveSupport::Benchmarkable
|
51
52
|
|
52
53
|
included do
|
53
54
|
if self.respond_to?(:helper_method)
|
54
55
|
helper_method(:facet_limit_for)
|
55
56
|
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
# similar design. Since we're a module, we have to add it in here.
|
60
|
-
# There are too many different semantic choices in ruby 'class variables',
|
61
|
-
# we choose this one for now, supplied by Rails.
|
62
|
-
class_attribute :solr_search_params_logic
|
63
|
-
|
64
|
-
# Set defaults. Each symbol identifies a _method_ that must be in
|
65
|
-
# this class, taking two parameters (solr_parameters, user_parameters)
|
66
|
-
# Can be changed in local apps or by plugins, eg:
|
67
|
-
# CatalogController.include ModuleDefiningNewMethod
|
68
|
-
# CatalogController.solr_search_params_logic += [:new_method]
|
69
|
-
# CatalogController.solr_search_params_logic.delete(:we_dont_want)
|
70
|
-
self.solr_search_params_logic = [:default_solr_parameters , :add_query_to_solr, :add_facet_fq_to_solr, :add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr, :add_sorting_to_solr, :add_group_config_to_solr ]
|
58
|
+
include Blacklight::RequestBuilders
|
59
|
+
|
71
60
|
end
|
72
61
|
|
73
62
|
def force_to_utf8(value)
|
@@ -82,10 +71,32 @@ module Blacklight::SolrHelper
|
|
82
71
|
value
|
83
72
|
end
|
84
73
|
|
74
|
+
##
|
75
|
+
# Execute a solr query
|
76
|
+
# @see [RSolr::Client#send_and_receive]
|
77
|
+
# @overload find(solr_path, params)
|
78
|
+
# Execute a solr query at the given path with the parameters
|
79
|
+
# @param [String] solr path (defaults to blacklight_config.solr_path)
|
80
|
+
# @param [Hash] parameters for RSolr::Client#send_and_receive
|
81
|
+
# @overload find(params)
|
82
|
+
# @param [Hash] parameters for RSolr::Client#send_and_receive
|
85
83
|
def find(*args)
|
86
|
-
|
87
|
-
|
88
|
-
|
84
|
+
# In later versions of Rails, the #benchmark method can do timing
|
85
|
+
# better for us.
|
86
|
+
benchmark("Solr fetch", level: :debug) do
|
87
|
+
solr_params = args.extract_options!
|
88
|
+
path = args.first || blacklight_config.solr_path
|
89
|
+
solr_params[:qt] ||= blacklight_config.qt
|
90
|
+
# delete these parameters, otherwise rsolr will pass them through.
|
91
|
+
key = blacklight_config.http_method == :post ? :data : :params
|
92
|
+
res = blacklight_solr.send_and_receive(path, {key=>solr_params.to_hash, method:blacklight_config.http_method})
|
93
|
+
|
94
|
+
solr_response = Blacklight::SolrResponse.new(force_to_utf8(res), solr_params)
|
95
|
+
|
96
|
+
Rails.logger.debug("Solr query: #{solr_params.inspect}")
|
97
|
+
Rails.logger.debug("Solr response: #{solr_response.inspect}") if defined?(::BLACKLIGHT_VERBOSE_LOGGING) and ::BLACKLIGHT_VERBOSE_LOGGING
|
98
|
+
solr_response
|
99
|
+
end
|
89
100
|
rescue Errno::ECONNREFUSED => e
|
90
101
|
raise Blacklight::Exceptions::ECONNREFUSED.new("Unable to connect to Solr instance using #{blacklight_solr.inspect}")
|
91
102
|
end
|
@@ -105,281 +116,6 @@ module Blacklight::SolrHelper
|
|
105
116
|
return val
|
106
117
|
end
|
107
118
|
|
108
|
-
|
109
|
-
# returns a params hash for searching solr.
|
110
|
-
# The CatalogController #index action uses this.
|
111
|
-
# Solr parameters can come from a number of places. From lowest
|
112
|
-
# precedence to highest:
|
113
|
-
# 1. General defaults in blacklight config (are trumped by)
|
114
|
-
# 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
|
115
|
-
# 3. certain parameters directly on input HTTP query params
|
116
|
-
# * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
|
117
|
-
# * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
|
118
|
-
# 4. extra parameters passed in as argument.
|
119
|
-
#
|
120
|
-
# spellcheck.q will be supplied with the [:q] value unless specifically
|
121
|
-
# specified otherwise.
|
122
|
-
#
|
123
|
-
# Incoming parameter :f is mapped to :fq solr parameter.
|
124
|
-
def solr_search_params(user_params = params || {})
|
125
|
-
solr_parameters = Blacklight::Solr::Request.new
|
126
|
-
solr_search_params_logic.each do |method_name|
|
127
|
-
send(method_name, solr_parameters, user_params)
|
128
|
-
end
|
129
|
-
|
130
|
-
return solr_parameters
|
131
|
-
end
|
132
|
-
|
133
|
-
|
134
|
-
####
|
135
|
-
# Start with general defaults from BL config. Need to use custom
|
136
|
-
# merge to dup values, to avoid later mutating the original by mistake.
|
137
|
-
def default_solr_parameters(solr_parameters, user_params)
|
138
|
-
blacklight_config.default_solr_params.each do |key, value|
|
139
|
-
solr_parameters[key] = value.dup rescue value
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
###
|
144
|
-
# copy paging params from BL app over to solr, changing
|
145
|
-
# app level per_page and page to Solr rows and start.
|
146
|
-
def add_paging_to_solr(solr_params, user_params)
|
147
|
-
|
148
|
-
# Now any over-rides from current URL?
|
149
|
-
solr_params[:rows] = user_params[:rows].to_i unless user_params[:rows].blank?
|
150
|
-
solr_params[:rows] = user_params[:per_page].to_i unless user_params[:per_page].blank?
|
151
|
-
|
152
|
-
# Do we need to translate :page to Solr :start?
|
153
|
-
unless user_params[:page].blank?
|
154
|
-
# already set solr_params["rows"] might not be the one we just set,
|
155
|
-
# could have been from app defaults too. But we need one.
|
156
|
-
# raising is consistent with prior RSolr magic keys behavior.
|
157
|
-
# We could change this to default to 10, or to raise on startup
|
158
|
-
# from config instead of at runtime.
|
159
|
-
if solr_params[:rows].blank?
|
160
|
-
raise Exception.new("To use pagination when no :per_page is supplied in the URL, :rows must be configured in blacklight_config default_solr_params")
|
161
|
-
end
|
162
|
-
solr_params[:start] = solr_params[:rows].to_i * (user_params[:page].to_i - 1)
|
163
|
-
solr_params[:start] = 0 if solr_params[:start].to_i < 0
|
164
|
-
end
|
165
|
-
|
166
|
-
solr_params[:rows] ||= blacklight_config.per_page.first unless blacklight_config.per_page.blank?
|
167
|
-
|
168
|
-
solr_params[:rows] = blacklight_config.max_per_page if solr_params[:rows].to_i > blacklight_config.max_per_page
|
169
|
-
end
|
170
|
-
|
171
|
-
###
|
172
|
-
# copy sorting params from BL app over to solr
|
173
|
-
def add_sorting_to_solr(solr_parameters, user_params)
|
174
|
-
if user_params[:sort].blank? and sort_field = blacklight_config.default_sort_field
|
175
|
-
# no sort param provided, use default
|
176
|
-
solr_parameters[:sort] = sort_field.sort unless sort_field.sort.blank?
|
177
|
-
elsif sort_field = blacklight_config.sort_fields[user_params[:sort]]
|
178
|
-
# check for sort field key
|
179
|
-
solr_parameters[:sort] = sort_field.sort unless sort_field.sort.blank?
|
180
|
-
else
|
181
|
-
# just pass the key through
|
182
|
-
solr_parameters[:sort] = user_params[:sort]
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
##
|
187
|
-
# Take the user-entered query, and put it in the solr params,
|
188
|
-
# including config's "search field" params for current search field.
|
189
|
-
# also include setting spellcheck.q.
|
190
|
-
def add_query_to_solr(solr_parameters, user_parameters)
|
191
|
-
###
|
192
|
-
# Merge in search field configured values, if present, over-writing general
|
193
|
-
# defaults
|
194
|
-
###
|
195
|
-
# legacy behavior of user param :qt is passed through, but over-ridden
|
196
|
-
# by actual search field config if present. We might want to remove
|
197
|
-
# this legacy behavior at some point. It does not seem to be currently
|
198
|
-
# rspec'd.
|
199
|
-
solr_parameters[:qt] = user_parameters[:qt] if user_parameters[:qt]
|
200
|
-
|
201
|
-
search_field_def = search_field_def_for_key(user_parameters[:search_field])
|
202
|
-
if (search_field_def)
|
203
|
-
solr_parameters[:qt] = search_field_def.qt
|
204
|
-
solr_parameters.merge!( search_field_def.solr_parameters) if search_field_def.solr_parameters
|
205
|
-
end
|
206
|
-
|
207
|
-
##
|
208
|
-
# Create Solr 'q' including the user-entered q, prefixed by any
|
209
|
-
# solr LocalParams in config, using solr LocalParams syntax.
|
210
|
-
# http://wiki.apache.org/solr/LocalParams
|
211
|
-
##
|
212
|
-
if (search_field_def && hash = search_field_def.solr_local_parameters)
|
213
|
-
local_params = hash.collect do |key, val|
|
214
|
-
key.to_s + "=" + solr_param_quote(val, :quote => "'")
|
215
|
-
end.join(" ")
|
216
|
-
solr_parameters[:q] = "{!#{local_params}}#{user_parameters[:q]}"
|
217
|
-
else
|
218
|
-
solr_parameters[:q] = user_parameters[:q] if user_parameters[:q]
|
219
|
-
end
|
220
|
-
|
221
|
-
|
222
|
-
##
|
223
|
-
# Set Solr spellcheck.q to be original user-entered query, without
|
224
|
-
# our local params, otherwise it'll try and spellcheck the local
|
225
|
-
# params! Unless spellcheck.q has already been set by someone,
|
226
|
-
# respect that.
|
227
|
-
#
|
228
|
-
# TODO: Change calling code to expect this as a symbol instead of
|
229
|
-
# a string, for consistency? :'spellcheck.q' is a symbol. Right now
|
230
|
-
# rspec tests for a string, and can't tell if other code may
|
231
|
-
# insist on a string.
|
232
|
-
solr_parameters["spellcheck.q"] = user_parameters[:q] unless solr_parameters["spellcheck.q"]
|
233
|
-
end
|
234
|
-
|
235
|
-
##
|
236
|
-
# Add any existing facet limits, stored in app-level HTTP query
|
237
|
-
# as :f, to solr as appropriate :fq query.
|
238
|
-
def add_facet_fq_to_solr(solr_parameters, user_params)
|
239
|
-
|
240
|
-
# convert a String value into an Array
|
241
|
-
if solr_parameters[:fq].is_a? String
|
242
|
-
solr_parameters[:fq] = [solr_parameters[:fq]]
|
243
|
-
end
|
244
|
-
|
245
|
-
# :fq, map from :f.
|
246
|
-
if ( user_params[:f])
|
247
|
-
f_request_params = user_params[:f]
|
248
|
-
|
249
|
-
f_request_params.each_pair do |facet_field, value_list|
|
250
|
-
Array(value_list).each do |value|
|
251
|
-
solr_parameters.append_filter_query facet_value_to_fq_string(facet_field, value)
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
##
|
258
|
-
# Convert a facet/value pair into a solr fq parameter
|
259
|
-
def facet_value_to_fq_string(facet_field, value)
|
260
|
-
facet_config = blacklight_config.facet_fields[facet_field]
|
261
|
-
|
262
|
-
local_params = []
|
263
|
-
local_params << "tag=#{facet_config.tag}" if facet_config and facet_config.tag
|
264
|
-
|
265
|
-
prefix = ""
|
266
|
-
prefix = "{!#{local_params.join(" ")}}" unless local_params.empty?
|
267
|
-
|
268
|
-
fq = case
|
269
|
-
when (facet_config and facet_config.query)
|
270
|
-
facet_config.query[value][:fq]
|
271
|
-
when (facet_config and facet_config.date),
|
272
|
-
(value.is_a?(TrueClass) or value.is_a?(FalseClass) or value == 'true' or value == 'false'),
|
273
|
-
(value.is_a?(Integer) or (value.to_i.to_s == value if value.respond_to? :to_i)),
|
274
|
-
(value.is_a?(Float) or (value.to_f.to_s == value if value.respond_to? :to_f))
|
275
|
-
(value.is_a?(DateTime) or value.is_a?(Date) or value.is_a?(Time))
|
276
|
-
"#{prefix}#{facet_field}:#{value}"
|
277
|
-
when value.is_a?(Range)
|
278
|
-
"#{prefix}#{facet_field}:[#{value.first} TO #{value.last}]"
|
279
|
-
else
|
280
|
-
"{!raw f=#{facet_field}#{(" " + local_params.join(" ")) unless local_params.empty?}}#{value}"
|
281
|
-
end
|
282
|
-
|
283
|
-
|
284
|
-
end
|
285
|
-
|
286
|
-
##
|
287
|
-
# Add appropriate Solr facetting directives in, including
|
288
|
-
# taking account of our facet paging/'more'. This is not
|
289
|
-
# about solr 'fq', this is about solr facet.* params.
|
290
|
-
def add_facetting_to_solr(solr_parameters, user_params)
|
291
|
-
# While not used by BL core behavior, legacy behavior seemed to be
|
292
|
-
# to accept incoming params as "facet.field" or "facets", and add them
|
293
|
-
# on to any existing facet.field sent to Solr. Legacy behavior seemed
|
294
|
-
# to be accepting these incoming params as arrays (in Rails URL with []
|
295
|
-
# on end), or single values. At least one of these is used by
|
296
|
-
# Stanford for "faux hieararchial facets".
|
297
|
-
if user_params.has_key?("facet.field") || user_params.has_key?("facets")
|
298
|
-
solr_parameters[:"facet.field"].concat( [user_params["facet.field"], user_params["facets"]].flatten.compact ).uniq!
|
299
|
-
end
|
300
|
-
|
301
|
-
|
302
|
-
if blacklight_config.add_facet_fields_to_solr_request
|
303
|
-
solr_parameters[:facet] = true
|
304
|
-
solr_parameters.append_facet_fields blacklight_config.facet_fields_to_add_to_solr
|
305
|
-
end
|
306
|
-
|
307
|
-
blacklight_config.facet_fields.each do |field_name, facet|
|
308
|
-
|
309
|
-
if blacklight_config.add_facet_fields_to_solr_request
|
310
|
-
case
|
311
|
-
when facet.pivot
|
312
|
-
solr_parameters.append_facet_pivot with_ex_local_param(facet.ex, facet.pivot.join(","))
|
313
|
-
when facet.query
|
314
|
-
solr_parameters.append_facet_query facet.query.map { |k, x| with_ex_local_param(facet.ex, x[:fq]) }
|
315
|
-
|
316
|
-
when facet.ex
|
317
|
-
if idx = solr_parameters[:'facet.field'].index(facet.field)
|
318
|
-
solr_parameters[:'facet.field'][idx] = with_ex_local_param(facet.ex, solr_parameters[:'facet.field'][idx])
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
if facet.sort
|
323
|
-
solr_parameters[:"f.#{facet.field}.facet.sort"] = facet.sort
|
324
|
-
end
|
325
|
-
|
326
|
-
if facet.solr_params
|
327
|
-
facet.solr_params.each do |k, v|
|
328
|
-
solr_parameters[:"f.#{facet.field}.#{k}"] = v
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
end
|
333
|
-
|
334
|
-
# Support facet paging and 'more'
|
335
|
-
# links, by sending a facet.limit one more than what we
|
336
|
-
# want to page at, according to configured facet limits.
|
337
|
-
solr_parameters[:"f.#{facet.field}.facet.limit"] = (facet_limit_for(field_name) + 1) if facet_limit_for(field_name)
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
def with_ex_local_param(ex, value)
|
342
|
-
if ex
|
343
|
-
"{!ex=#{ex}}#{value}"
|
344
|
-
else
|
345
|
-
value
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
def add_solr_fields_to_query solr_parameters, user_parameters
|
350
|
-
return unless blacklight_config.add_field_configuration_to_solr_request
|
351
|
-
|
352
|
-
blacklight_config.show_fields.each do |field_name, field|
|
353
|
-
if field.solr_params
|
354
|
-
field.solr_params.each do |k, v|
|
355
|
-
solr_parameters[:"f.#{field.field}.#{k}"] = v
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
blacklight_config.index_fields.each do |field_name, field|
|
361
|
-
if field.highlight
|
362
|
-
solr_parameters[:hl] = true
|
363
|
-
solr_parameters.append_highlight_field field.field
|
364
|
-
end
|
365
|
-
|
366
|
-
if field.solr_params
|
367
|
-
field.solr_params.each do |k, v|
|
368
|
-
solr_parameters[:"f.#{field.field}.#{k}"] = v
|
369
|
-
end
|
370
|
-
end
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
# Remove the group parameter if we've faceted on the group field (e.g. for the full results for a group)
|
375
|
-
def add_group_config_to_solr solr_parameters, user_parameters
|
376
|
-
if user_parameters[:f] and user_parameters[:f][grouped_key_for_results]
|
377
|
-
solr_parameters[:group] = false
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
|
382
|
-
|
383
119
|
# a solr query method
|
384
120
|
# given a user query, return a solr response containing both result docs and facets
|
385
121
|
# - mixes in the Blacklight::Solr::SpellingSuggestions module
|
@@ -405,25 +141,9 @@ module Blacklight::SolrHelper
|
|
405
141
|
# given a user query,
|
406
142
|
# Returns a solr response object
|
407
143
|
def query_solr(user_params = params || {}, extra_controller_params = {})
|
408
|
-
# In later versions of Rails, the #benchmark method can do timing
|
409
|
-
# better for us.
|
410
|
-
bench_start = Time.now
|
411
144
|
solr_params = self.solr_search_params(user_params).merge(extra_controller_params)
|
412
|
-
solr_params[:qt] ||= blacklight_config.qt
|
413
|
-
path = blacklight_config.solr_path
|
414
145
|
|
415
|
-
|
416
|
-
key = blacklight_config.http_method == :post ? :data : :params
|
417
|
-
res = blacklight_solr.send_and_receive(path, {key=>solr_params.to_hash, method:blacklight_config.http_method})
|
418
|
-
|
419
|
-
solr_response = Blacklight::SolrResponse.new(force_to_utf8(res), solr_params)
|
420
|
-
|
421
|
-
Rails.logger.debug("Solr query: #{solr_params.inspect}")
|
422
|
-
Rails.logger.debug("Solr response: #{solr_response.inspect}") if defined?(::BLACKLIGHT_VERBOSE_LOGGING) and ::BLACKLIGHT_VERBOSE_LOGGING
|
423
|
-
Rails.logger.debug("Solr fetch: #{self.class}#query_solr (#{'%.1f' % ((Time.now.to_f - bench_start.to_f)*1000)}ms)")
|
424
|
-
|
425
|
-
|
426
|
-
solr_response
|
146
|
+
find(solr_params)
|
427
147
|
end
|
428
148
|
|
429
149
|
# returns a params hash for finding a single solr document (CatalogController #show action)
|
@@ -432,11 +152,15 @@ module Blacklight::SolrHelper
|
|
432
152
|
def solr_doc_params(id=nil)
|
433
153
|
id ||= params[:id]
|
434
154
|
|
155
|
+
# add our document id to the document_unique_id_param query parameter
|
435
156
|
p = blacklight_config.default_document_solr_params.merge({
|
436
|
-
|
157
|
+
# this assumes the request handler will map the unique id param
|
158
|
+
# to the unique key field using either solr local params, the
|
159
|
+
# real-time get handler, etc.
|
160
|
+
blacklight_config.document_unique_id_param => id
|
437
161
|
})
|
438
162
|
|
439
|
-
p[:qt] ||=
|
163
|
+
p[:qt] ||= blacklight_config.document_solr_request_handler
|
440
164
|
|
441
165
|
p
|
442
166
|
end
|
@@ -445,7 +169,7 @@ module Blacklight::SolrHelper
|
|
445
169
|
# retrieve a solr document, given the doc id
|
446
170
|
def get_solr_response_for_doc_id(id=nil, extra_controller_params={})
|
447
171
|
solr_params = solr_doc_params(id).merge(extra_controller_params)
|
448
|
-
solr_response = find(
|
172
|
+
solr_response = find(blacklight_config.document_solr_path, solr_params)
|
449
173
|
raise Blacklight::Exceptions::InvalidSolrID.new if solr_response.docs.empty?
|
450
174
|
document = SolrDocument.new(solr_response.docs.first, solr_response)
|
451
175
|
[solr_response, document]
|
@@ -474,7 +198,7 @@ module Blacklight::SolrHelper
|
|
474
198
|
:spellcheck => 'false'
|
475
199
|
}.merge(extra_solr_params)
|
476
200
|
|
477
|
-
solr_response = find(
|
201
|
+
solr_response = find(self.solr_search_params().merge(solr_params) )
|
478
202
|
document_list = solr_response.docs.collect{|doc| SolrDocument.new(doc, solr_response) }
|
479
203
|
[solr_response,document_list]
|
480
204
|
end
|
@@ -496,7 +220,6 @@ module Blacklight::SolrHelper
|
|
496
220
|
# Now override with our specific things for fetching facet values
|
497
221
|
solr_params[:"facet.field"] = with_ex_local_param((facet_config.ex if facet_config.respond_to?(:ex)), facet_field)
|
498
222
|
|
499
|
-
|
500
223
|
limit =
|
501
224
|
if respond_to?(:facet_list_limit)
|
502
225
|
facet_list_limit.to_s.to_i
|
@@ -521,7 +244,7 @@ module Blacklight::SolrHelper
|
|
521
244
|
def get_facet_field_response(facet_field, user_params = params || {}, extra_controller_params = {})
|
522
245
|
solr_params = solr_facet_params(facet_field, user_params, extra_controller_params)
|
523
246
|
# Make the solr call
|
524
|
-
find(
|
247
|
+
find(solr_params)
|
525
248
|
end
|
526
249
|
|
527
250
|
# a solr query method
|
@@ -555,7 +278,7 @@ module Blacklight::SolrHelper
|
|
555
278
|
solr_params[:start] = (index - 1) # start at 0 to get 1st doc, 1 to get 2nd.
|
556
279
|
solr_params[:rows] = 1
|
557
280
|
solr_params[:fl] = '*'
|
558
|
-
solr_response = find(
|
281
|
+
solr_response = find(solr_params)
|
559
282
|
SolrDocument.new(solr_response.docs.first, solr_response) unless solr_response.docs.empty?
|
560
283
|
end
|
561
284
|
|
@@ -574,7 +297,7 @@ module Blacklight::SolrHelper
|
|
574
297
|
|
575
298
|
solr_params[:fl] = '*'
|
576
299
|
solr_params[:facet] = false
|
577
|
-
solr_response = find(
|
300
|
+
solr_response = find(solr_params)
|
578
301
|
|
579
302
|
document_list = solr_response.docs.collect{|doc| SolrDocument.new(doc, solr_response) }
|
580
303
|
|
@@ -603,7 +326,7 @@ module Blacklight::SolrHelper
|
|
603
326
|
# where the field is the "field" argument passed in.
|
604
327
|
def get_opensearch_response(field=nil, extra_controller_params={})
|
605
328
|
solr_params = solr_opensearch_params().merge(extra_controller_params)
|
606
|
-
response = find(
|
329
|
+
response = find(solr_params)
|
607
330
|
a = [solr_params[:q]]
|
608
331
|
a << response.docs.map {|doc| doc[solr_params[:fl]].to_s }
|
609
332
|
end
|
@@ -618,14 +341,12 @@ module Blacklight::SolrHelper
|
|
618
341
|
# a facet paginator with the right limit.
|
619
342
|
def facet_limit_for(facet_field)
|
620
343
|
facet = blacklight_config.facet_fields[facet_field]
|
621
|
-
|
622
344
|
return if facet.blank?
|
623
345
|
|
624
|
-
if facet.limit and @response
|
625
|
-
limit = @response.
|
626
|
-
@response.params["facet.limit"]
|
346
|
+
if facet.limit and @response and @response.facet_by_field_name(facet_field)
|
347
|
+
limit = @response.facet_by_field_name(facet_field).limit
|
627
348
|
|
628
|
-
if limit.
|
349
|
+
if limit.nil? # we didn't get or a set a limit, so infer one.
|
629
350
|
facet.limit if facet.limit != true
|
630
351
|
elsif limit == -1 # limit -1 is solr-speak for unlimited
|
631
352
|
nil
|
@@ -650,4 +371,10 @@ module Blacklight::SolrHelper
|
|
650
371
|
def blacklight_solr_config
|
651
372
|
Blacklight.solr_config
|
652
373
|
end
|
374
|
+
|
375
|
+
private
|
376
|
+
|
377
|
+
def should_add_to_solr field_name, field
|
378
|
+
field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request)
|
379
|
+
end
|
653
380
|
end
|
@@ -60,10 +60,14 @@ module Blacklight::SolrResponse::Facets
|
|
60
60
|
values_and_hits.each_slice(2) do |k,v|
|
61
61
|
items << FacetItem.new(:value => k, :hits => v)
|
62
62
|
end
|
63
|
+
options[:sort] = (params[:"f.#{facet_field_name}.facet.sort"] || params[:'facet.sort'])
|
64
|
+
if params[:"f.#{facet_field_name}.facet.limit"] || params[:"facet.limit"]
|
65
|
+
options[:limit] = (params[:"f.#{facet_field_name}.facet.limit"] || params[:"facet.limit"]).to_i
|
66
|
+
end
|
63
67
|
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
if params[:"f.#{facet_field_name}.facet.offset"] || params[:'facet.offset']
|
69
|
+
options[:offset] = (params[:"f.#{facet_field_name}.facet.offset"] || params[:'facet.offset']).to_i
|
70
|
+
end
|
67
71
|
FacetField.new(facet_field_name, items, options)
|
68
72
|
end
|
69
73
|
end
|
data/lib/blacklight/utils.rb
CHANGED
@@ -1,29 +1,48 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
module Blacklight
|
3
|
+
##
|
4
|
+
# An OpenStruct that responds to common Hash methods
|
3
5
|
class OpenStructWithHashAccess < OpenStruct
|
4
|
-
delegate :keys, :each, :map, :has_key?, :empty?, :delete, :length, :reject!, :select!, :include, :fetch, :to => :to_h
|
6
|
+
delegate :keys, :each, :map, :has_key?, :empty?, :delete, :length, :reject!, :select!, :include, :fetch, :to_json, :as_json, :to => :to_h
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
if ::RUBY_VERSION < '2.0'
|
9
|
+
def []=(key, value)
|
10
|
+
send "#{key}=", value
|
11
|
+
end
|
9
12
|
|
10
|
-
|
11
|
-
|
13
|
+
def [](key)
|
14
|
+
send key
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
18
|
+
##
|
19
|
+
# Expose the internal hash
|
20
|
+
# @return [Hash]
|
14
21
|
def to_h
|
15
22
|
@table
|
16
23
|
end
|
17
24
|
|
25
|
+
##
|
26
|
+
# Merge the values of this OpenStruct with another OpenStruct or Hash
|
27
|
+
# @param [Hash,#to_h]
|
28
|
+
# @return [OpenStructWithHashAccess] a new instance of an OpenStructWithHashAccess
|
18
29
|
def merge other_hash
|
19
30
|
self.class.new to_h.merge((other_hash if other_hash.is_a? Hash) || other_hash.to_h)
|
20
31
|
end
|
21
32
|
|
33
|
+
##
|
34
|
+
# Merge the values of another OpenStruct or Hash into this object
|
35
|
+
# @param [Hash,#to_h]
|
36
|
+
# @return [OpenStructWithHashAccess] a new instance of an OpenStructWithHashAccess
|
22
37
|
def merge! other_hash
|
23
38
|
@table.merge!((other_hash if other_hash.is_a? Hash) || other_hash.to_h)
|
24
39
|
end
|
25
40
|
end
|
26
41
|
|
42
|
+
|
43
|
+
##
|
44
|
+
# An OpenStruct refinement that converts any hash-keys into
|
45
|
+
# additional instances of NestedOpenStructWithHashAccess
|
27
46
|
class NestedOpenStructWithHashAccess < OpenStructWithHashAccess
|
28
47
|
attr_reader :nested_class
|
29
48
|
delegate :default_proc=, :to => :to_h
|
@@ -54,18 +73,28 @@ module Blacklight
|
|
54
73
|
set_default_proc!
|
55
74
|
end
|
56
75
|
|
76
|
+
##
|
77
|
+
# Add an new key to the object, with a default default
|
57
78
|
def << key
|
58
79
|
@table[key]
|
59
80
|
end
|
60
81
|
|
82
|
+
##
|
83
|
+
# Add a new key/value to the object; if it's a Hash, turn it
|
84
|
+
# into another NestedOpenStructWithHashAccess
|
61
85
|
def []=(key, value)
|
62
86
|
if value.is_a? Hash
|
63
87
|
send "#{key}=", nested_class.new(value)
|
64
|
-
|
88
|
+
elsif ::RUBY_VERSION < '2.0'
|
65
89
|
send "#{key}=", value
|
90
|
+
else
|
91
|
+
super
|
66
92
|
end
|
67
93
|
end
|
68
94
|
|
95
|
+
##
|
96
|
+
# Before serializing, we need to reset the default proc
|
97
|
+
# so it can be serialized appropriately
|
69
98
|
def marshal_dump
|
70
99
|
h = to_h.dup
|
71
100
|
h.default = nil
|
@@ -73,6 +102,9 @@ module Blacklight
|
|
73
102
|
[nested_class, h]
|
74
103
|
end
|
75
104
|
|
105
|
+
##
|
106
|
+
# After deserializing, we need to re-add the default proc
|
107
|
+
# to the internal hash
|
76
108
|
def marshal_load x
|
77
109
|
@nested_class = x.first
|
78
110
|
super x.last
|
data/lib/blacklight.rb
CHANGED
@@ -10,14 +10,16 @@ module Blacklight
|
|
10
10
|
autoload :Solr, 'blacklight/solr'
|
11
11
|
|
12
12
|
autoload :SolrHelper, 'blacklight/solr_helper'
|
13
|
+
autoload :RequestBuilders, 'blacklight/request_builders'
|
13
14
|
|
14
15
|
autoload :Exceptions, 'blacklight/exceptions'
|
15
16
|
|
16
17
|
autoload :User, 'blacklight/user'
|
17
18
|
|
18
|
-
autoload :Controller,
|
19
|
-
autoload :Base,
|
20
|
-
autoload :Catalog,
|
19
|
+
autoload :Controller, 'blacklight/controller'
|
20
|
+
autoload :Base, 'blacklight/base'
|
21
|
+
autoload :Catalog, 'blacklight/catalog'
|
22
|
+
autoload :DocumentPresenter, 'blacklight/document_presenter'
|
21
23
|
|
22
24
|
autoload :Routes, 'blacklight/routes'
|
23
25
|
|
@@ -3,9 +3,10 @@ module Blacklight
|
|
3
3
|
|
4
4
|
source_root File.expand_path('../templates', __FILE__)
|
5
5
|
|
6
|
-
argument :model_name, :
|
7
|
-
class_option :devise
|
8
|
-
class_option :
|
6
|
+
argument :model_name , type: :string , default: "user"
|
7
|
+
class_option :devise , type: :boolean, default: false, aliases: "-d", desc: "Use Devise as authentication logic."
|
8
|
+
class_option :jettywrapper, type: :boolean, default: false, desc: "Use jettywrapper to download and control Jetty"
|
9
|
+
class_option :marc , type: :boolean, default: false, aliases: "-m", desc: "Generate MARC-based demo ."
|
9
10
|
|
10
11
|
desc """
|
11
12
|
This generator makes the following changes to your application:
|
@@ -17,7 +18,18 @@ module Blacklight
|
|
17
18
|
|
18
19
|
|
19
20
|
Thank you for Installing Blacklight.
|
20
|
-
"""
|
21
|
+
"""
|
22
|
+
|
23
|
+
def install_jettywrapper
|
24
|
+
return unless options[:jettywrapper]
|
25
|
+
gem "jettywrapper", "~> 1.7"
|
26
|
+
|
27
|
+
copy_file "config/jetty.yml"
|
28
|
+
|
29
|
+
append_to_file "Rakefile",
|
30
|
+
"\nZIP_URL = \"https://github.com/projectblacklight/blacklight-jetty/archive/v4.6.0.zip\"\n" +
|
31
|
+
"require 'jettywrapper'\n"
|
32
|
+
end
|
21
33
|
|
22
34
|
def bundle_install
|
23
35
|
Bundler.with_clean_env do
|
@@ -93,4 +105,4 @@ EOF
|
|
93
105
|
copy_file "blacklight.en.yml", "config/locales/blacklight.en.yml"
|
94
106
|
end
|
95
107
|
end
|
96
|
-
end
|
108
|
+
end
|
@@ -57,7 +57,6 @@ This generator makes the following changes to your application:
|
|
57
57
|
# Copy all files in templates/config directory to host config
|
58
58
|
def create_configuration_files
|
59
59
|
copy_file "config/solr.yml", "config/solr.yml"
|
60
|
-
copy_file "config/jetty.yml", "config/jetty.yml"
|
61
60
|
end
|
62
61
|
|
63
62
|
|
@@ -10,6 +10,12 @@ class CatalogController < ApplicationController
|
|
10
10
|
:qt => 'search',
|
11
11
|
:rows => 10
|
12
12
|
}
|
13
|
+
|
14
|
+
# solr path which will be added to solr base url before the other solr params.
|
15
|
+
#config.solr_path = 'select'
|
16
|
+
|
17
|
+
# items to show per page, each number in the array represent another option to choose from.
|
18
|
+
#config.per_page = [10,20,50,100]
|
13
19
|
|
14
20
|
## Default parameters to send on single-document requests to Solr. These settings are the Blackligt defaults (see SolrHelper#solr_doc_params) or
|
15
21
|
## parameters included in the Blacklight-jetty document requestHandler.
|