blacklight 5.1.1 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|