blacklight 4.0.0.pre7 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/.gitignore +1 -1
  2. data/VERSION +1 -1
  3. data/app/assets/stylesheets/blacklight/_catalog.css.scss +3 -3
  4. data/app/assets/stylesheets/blacklight/_dropdown.css.scss +0 -1
  5. data/app/assets/stylesheets/blacklight/_facets.css.scss +48 -43
  6. data/app/helpers/blacklight/blacklight_helper_behavior.rb +13 -11
  7. data/app/helpers/blacklight/catalog_helper_behavior.rb +45 -29
  8. data/app/helpers/blacklight/facets_helper_behavior.rb +74 -14
  9. data/app/views/_user_util_links.html.erb +1 -1
  10. data/app/views/catalog/_facet_pivot.html.erb +16 -0
  11. data/app/views/catalog/_per_page_widget.html.erb +5 -3
  12. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  13. data/app/views/catalog/_sort_widget.html.erb +3 -1
  14. data/app/views/catalog/index.html.erb +3 -4
  15. data/config/locales/blacklight.en.yml +3 -3
  16. data/lib/blacklight.rb +1 -0
  17. data/lib/blacklight/catalog.rb +1 -1
  18. data/lib/blacklight/configuration.rb +5 -4
  19. data/lib/blacklight/controller.rb +16 -72
  20. data/lib/blacklight/legacy_controller_methods.rb +69 -0
  21. data/lib/blacklight/solr_helper.rb +14 -8
  22. data/lib/blacklight/solr_response/facets.rb +24 -5
  23. data/lib/generators/blacklight/blacklight_generator.rb +2 -1
  24. data/lib/generators/blacklight/templates/catalog_controller.rb +1 -0
  25. data/test_support/spec/helpers/blacklight_helper_spec.rb +18 -1
  26. data/test_support/spec/helpers/facets_helper_spec.rb +63 -0
  27. data/test_support/spec/lib/blacklight_solr_response_spec.rb +35 -0
  28. data/test_support/spec/views/catalog/_facets.html.erb_spec.rb +2 -2
  29. metadata +5 -3
data/.gitignore CHANGED
@@ -18,4 +18,4 @@ Gemfile.lock
18
18
  tmp/test_app
19
19
  .rvmrc
20
20
  pkg/*
21
- *.swp
21
+ *.sw[pon]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.0.0.pre7
1
+ 4.0.0.rc1
@@ -10,7 +10,7 @@
10
10
  .label
11
11
  {
12
12
  position: absolute !important;
13
- height: 1px; width: 1px;
13
+ height: 1px; width: 1px;
14
14
  overflow: hidden;
15
15
  clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
16
16
  clip: rect(1px, 1px, 1px, 1px);
@@ -120,7 +120,7 @@ li.pill-with-label {
120
120
  }
121
121
  }
122
122
 
123
- .show-document-title
123
+ .show-document-title
124
124
  {
125
125
  padding-top: 0.5em;
126
126
 
@@ -178,7 +178,7 @@ li.pill-with-label {
178
178
 
179
179
  .document
180
180
  {
181
- border-bottom:1px dotted $dotted_border_color;
181
+ border-bottom:1px dotted $dotted_border_color;
182
182
  clear:both;
183
183
  padding-bottom: 1em;
184
184
 
@@ -19,7 +19,6 @@
19
19
  }
20
20
  }
21
21
  a:hover {
22
- display: block;
23
22
  text-decoration: none;
24
23
  }
25
24
  }
@@ -15,7 +15,7 @@
15
15
  padding-bottom:0.3em;
16
16
  padding-right: 50px;
17
17
  clear: right;
18
-
18
+
19
19
  a.remove
20
20
  {
21
21
  color:#666;
@@ -54,8 +54,8 @@
54
54
 
55
55
  .facet_extended_list
56
56
  {
57
- .sort_options
58
- {
57
+ .sort_options
58
+ {
59
59
  text-align:right;
60
60
  }
61
61
 
@@ -84,7 +84,7 @@ ul.facet_extended_list
84
84
  }
85
85
 
86
86
 
87
- /* Sidenav
87
+ /* Sidenav
88
88
  -------------------------------------------------- */
89
89
 
90
90
  .sidenav {
@@ -98,7 +98,7 @@ ul.facet_extended_list
98
98
  -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.065);
99
99
  -moz-box-shadow: 0 1px 4px rgba(0,0,0,.065);
100
100
  box-shadow: 0 1px 4px rgba(0,0,0,.065);
101
-
101
+
102
102
  h5, h4 {
103
103
  display: block;
104
104
  *width: 190px;
@@ -106,52 +106,18 @@ ul.facet_extended_list
106
106
  padding: 8px 14px;
107
107
  }
108
108
  h5 {
109
- cursor: pointer;
110
109
  border-top: 1px solid $navbarBorder;
111
-
112
110
  }
113
-
111
+
114
112
  .facet_limit:last-child > h5 {
115
113
 
116
114
  &.twiddle-open {
117
- @include border-bottom-radius(0px);
115
+ @include border-bottom-radius(0px);
118
116
  }
119
-
120
- @include border-bottom-radius(6px);
117
+
118
+ @include border-bottom-radius(6px);
121
119
  }
122
- /* Chevrons */
123
- .icon-chevron {
124
- float: right;
125
- margin-top: 2px;
126
- margin-right: -6px;
127
- opacity: .25;
128
- }
129
-
130
- .facet_limit h5:hover {
131
- background-color: darken($bodyBackground, 10%);
132
- }
133
-
134
- .icon-chevron {
135
- @extend .icon-chevron-right;
136
- opacity: .5;
137
- }
138
-
139
- .twiddle-open .icon-chevron {
140
- @extend .icon-chevron-down;
141
- opacity: 1;
142
- padding-right:2px;
143
- }
144
-
145
- /* hide the chevron when js isn't supported */
146
- .no-js & .icon-chevron {
147
- @extend .icon-chevron-down;
148
- padding-right:2px;
149
- }
150
120
 
151
- h5:hover .icon-chevron,
152
- .twiddle-open .icon-chevron {
153
- opacity: 1;
154
- }
155
121
  }
156
122
 
157
123
 
@@ -179,6 +145,45 @@ ul.facet_extended_list
179
145
 
180
146
  }
181
147
 
148
+ .facets-collapse {
149
+ h5 {
150
+ cursor: pointer;
151
+ }
152
+ /* Chevrons */
153
+ .icon-chevron {
154
+ float: right;
155
+ margin-top: 2px;
156
+ margin-right: -6px;
157
+ opacity: .25;
158
+ }
159
+
160
+ .facet_limit h5:hover {
161
+ background-color: darken($bodyBackground, 10%);
162
+ }
163
+
164
+ .icon-chevron {
165
+ @extend .icon-chevron-right;
166
+ opacity: .5;
167
+ }
168
+
169
+ .twiddle-open .icon-chevron {
170
+ @extend .icon-chevron-down;
171
+ opacity: 1;
172
+ padding-right:2px;
173
+ }
174
+
175
+ /* hide the chevron when js isn't supported */
176
+ .no-js & .icon-chevron {
177
+ @extend .icon-chevron-down;
178
+ padding-right:2px;
179
+ }
180
+
181
+ h5:hover .icon-chevron,
182
+ .twiddle-open .icon-chevron {
183
+ opacity: 1;
184
+ }
185
+ }
186
+
182
187
  .facet_pagination {
183
188
  @extend .clearfix;
184
189
  }
@@ -151,13 +151,14 @@ module Blacklight::BlacklightHelperBehavior
151
151
  def document_heading
152
152
  @document[blacklight_config.show.heading] || @document.id
153
153
  end
154
+
154
155
  def render_document_heading
155
- content_tag(:h4, document_heading, :class => "show-document-title")
156
+ content_tag(:h4, render_field_value(document_heading), :class => "show-document-title")
156
157
  end
157
158
 
158
159
  # Used in the show view for setting the main html document title
159
160
  def document_show_html_title
160
- @document[blacklight_config.show.html_title]
161
+ render_field_value(@document[blacklight_config.show.html_title])
161
162
  end
162
163
 
163
164
  # Used in citation view for displaying the title
@@ -225,7 +226,11 @@ module Blacklight::BlacklightHelperBehavior
225
226
  end
226
227
 
227
228
  def document_index_view_type
228
- params.fetch(:view, 'list')
229
+ if blacklight_config.document_index_view_types.include? params[:view]
230
+ params[:view]
231
+ else
232
+ blacklight_config.document_index_view_types.first
233
+ end
229
234
  end
230
235
 
231
236
  def render_document_index documents = nil, locals = {}
@@ -235,7 +240,7 @@ module Blacklight::BlacklightHelperBehavior
235
240
  # XXX rather than handling this logic through exceptions, maybe there's a Rails internals method
236
241
  # for determining if a partial template exists..
237
242
  begin
238
- return render(:partial => (str % [document_index_view_type]), :locals => { :documents => documents })
243
+ return render(:partial => (str % { :index_view_type => document_index_view_type }), :locals => { :documents => documents })
239
244
  rescue ActionView::MissingTemplate
240
245
  nil
241
246
  end
@@ -249,7 +254,7 @@ module Blacklight::BlacklightHelperBehavior
249
254
  # first, the legacy template names for backwards compatbility
250
255
  # followed by the new, inheritable style
251
256
  # finally, a controller-specific path for non-catalog subclasses
252
- @document_index_path_templates ||= ["document_%s", "catalog/document_%s", "catalog/document_list"]
257
+ @document_index_path_templates ||= ["document_%{index_view_type}", "catalog/document_%{index_view_type}", "catalog/document_list"]
253
258
  end
254
259
 
255
260
  # Return a normalized partial name that can be used to contruct view partial path
@@ -276,7 +281,7 @@ module Blacklight::BlacklightHelperBehavior
276
281
  # XXX rather than handling this logic through exceptions, maybe there's a Rails internals method
277
282
  # for determining if a partial template exists..
278
283
  begin
279
- return render :partial => (str % [action_name, format]), :locals=>locals.merge({:document=>doc})
284
+ return render :partial => (str % { :action_name => action_name, :format => format, :index_view_type => document_index_view_type }), :locals=>locals.merge({:document=>doc})
280
285
  rescue ActionView::MissingTemplate
281
286
  nil
282
287
  end
@@ -286,14 +291,11 @@ module Blacklight::BlacklightHelperBehavior
286
291
  end
287
292
 
288
293
  # a list of document partial templates to try to render for #render_document_partial
289
- #
290
- # (NOTE: I suspect #document_partial_name, #render_document_partial and #document_partial_path_templates
291
- # should be more succinctly refactored in the future)
292
294
  def document_partial_path_templates
293
295
  # first, the legacy template names for backwards compatbility
294
296
  # followed by the new, inheritable style
295
297
  # finally, a controller-specific path for non-catalog subclasses
296
- @partial_path_templates ||= ["catalog/_%s_partials/%s", "catalog/_%s_partials/default", "%s_%s", "%s_default", "catalog/%s_%s", "catalog/%s_default"]
298
+ @partial_path_templates ||= ["%{action_name}_%{index_view_type}_%{format}", "%{action_name}_%{index_view_type}_default", "%{action_name}_%{format}", "%{action_name}_default", "catalog/%{action_name}_%{format}", "catalog/_%{action_name}_partials/%{format}", "catalog/_%{action_name}_partials/default"]
297
299
  end
298
300
 
299
301
 
@@ -335,7 +337,7 @@ module Blacklight::BlacklightHelperBehavior
335
337
  # catalog_path accepts a HashWithIndifferentAccess object. The solr query params are stored in the session,
336
338
  # so we only need the +counter+ param here. We also need to know if we are viewing to document as part of search results.
337
339
  def link_to_document(doc, opts={:label=>nil, :counter => nil, :results_view => true})
338
- label ||= blacklight_config.index.show_link.to_sym
340
+ opts[:label] ||= blacklight_config.index.show_link.to_sym
339
341
  label = render_document_index_label doc, opts
340
342
  link_to label, doc, { :'data-counter' => opts[:counter] }.merge(opts.reject { |k,v| [:label, :counter, :results_view].include? k })
341
343
  end
@@ -1,28 +1,42 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Blacklight::CatalogHelperBehavior
3
3
 
4
- # Pass in an RSolr::Response (or duck-typed similar) object,
4
+ # Pass in an RSolr::Response (or duck-typed similar) object,
5
5
  # it translates to a Kaminari-paginatable
6
- # object, with the keys Kaminari views expect.
6
+ # object, with the keys Kaminari views expect.
7
7
  def paginate_params(response)
8
+
8
9
  per_page = response.rows
9
10
  per_page = 1 if per_page < 1
11
+
10
12
  current_page = (response.start / per_page).ceil + 1
11
13
  num_pages = (response.total / per_page.to_f).ceil
12
14
 
13
- Struct.new(:current_page, :num_pages, :limit_value, :total_count, :first_page?, :last_page?).new(current_page, num_pages, per_page, response.total, current_page > 1, current_page < num_pages)
15
+ total_count = response.total
16
+
17
+ start_num = response.start + 1
18
+ end_num = start_num + response.docs.length - 1
19
+
20
+ OpenStruct.new(:start => start_num,
21
+ :end => end_num,
22
+ :per_page => per_page,
23
+ :current_page => current_page,
24
+ :num_pages => num_pages,
25
+ :limit_value => per_page, # backwards compatibility
26
+ :total_count => total_count,
27
+ :first_page? => current_page > 1,
28
+ :last_page? => current_page < num_pages
29
+ )
14
30
  end
15
31
 
16
- # Equivalent to kaminari "paginate", but takes an RSolr::Response as first argument.
32
+ # Equivalent to kaminari "paginate", but takes an RSolr::Response as first argument.
17
33
  # Will convert it to something kaminari can deal with (using #paginate_params), and
18
34
  # then call kaminari paginate with that. Other arguments (options and block) same as
19
- # kaminari paginate, passed on through.
20
- # will output HTML pagination controls.
35
+ # kaminari paginate, passed on through.
36
+ # will output HTML pagination controls.
21
37
  def paginate_rsolr_response(response, options = {}, &block)
22
- per_page = response.rows
23
- per_page = 1 if per_page < 1
24
- current_page = (response.start / per_page).ceil + 1
25
- paginate Kaminari.paginate_array(response.docs, :total_count => response.total).page(current_page).per(per_page), options, &block
38
+ pagination_info = paginate_params(response)
39
+ paginate Kaminari.paginate_array(response.docs, :total_count => pagination_info.total_count).page(pagination_info.current_page).per(pagination_info.per_page), options, &block
26
40
  end
27
41
 
28
42
  #
@@ -31,55 +45,51 @@ module Blacklight::CatalogHelperBehavior
31
45
  def format_num(num); number_with_delimiter(num) end
32
46
 
33
47
  #
34
- # Pass in an RSolr::Response. Displays the "showing X through Y of N" message.
48
+ # Pass in an RSolr::Response. Displays the "showing X through Y of N" message.
35
49
  def render_pagination_info(response, options = {})
36
- start = response.start + 1
37
- per_page = response.rows
38
- current_page = (response.start / per_page).ceil + 1
39
- num_pages = (response.total / per_page.to_f).ceil
40
- total_hits = response.total
41
-
42
- start_num = format_num(start)
43
- end_num = format_num(start + response.docs.length - 1)
44
- total_num = format_num(total_hits)
50
+ pagination_info = paginate_params(response)
45
51
 
46
52
  # TODO: i18n the entry_name
47
- entry_name = options[:entry_name]
53
+ entry_name = options[:entry_name]
48
54
  entry_name ||= response.docs.first.class.name.underscore.sub('_', ' ') unless response.docs.empty?
49
55
  entry_name ||= t('blacklight.entry_name.default')
50
56
 
51
57
 
52
- case response.total
58
+ case pagination_info.total_count
53
59
  when 0; t('blacklight.search.pagination_info.no_items_found', :entry_name => entry_name.pluralize ).html_safe
54
60
  when 1; t('blacklight.search.pagination_info.single_item_found', :entry_name => entry_name).html_safe
55
- else; t('blacklight.search.pagination_info.pages', :entry_name => entry_name.pluralize, :current_page => current_page, :num_pages => num_pages, :start_num => start_num, :end_num => end_num, :total_num => total_num, :count => num_pages).html_safe
61
+ else; t('blacklight.search.pagination_info.pages', :entry_name => entry_name.pluralize, :current_page => pagination_info.current_page, :num_pages => pagination_info.num_pages, :start_num => format_num(pagination_info.start), :end_num => format_num(pagination_info.end), :total_num => pagination_info.total_count, :count => pagination_info.num_pages).html_safe
56
62
  end
57
63
  end
58
64
 
59
65
  # Like #render_pagination_info above, but for an individual
60
66
  # item show page. Displays "showing X of Y items" message. Actually takes
61
- # data from session though (not a great design).
67
+ # data from session though (not a great design).
62
68
  # Code should call this method rather than interrogating session directly,
63
- # because implementation of where this data is stored/retrieved may change.
69
+ # because implementation of where this data is stored/retrieved may change.
64
70
  def item_page_entry_info
65
71
  t('blacklight.search.entry_pagination_info.other', :current => format_num(session[:search][:counter]), :total => format_num(session[:search][:total]), :count => session[:search][:total].to_i).html_safe
66
72
  end
67
-
73
+
68
74
  # Look up search field user-displayable label
69
75
  # based on params[:qt] and blacklight_configuration.
70
76
  def search_field_label(params)
71
77
  h( label_for_search_field(params[:search_field]) )
72
78
  end
73
-
79
+
74
80
  def current_sort_field
75
81
  blacklight_config.sort_fields[params[:sort]] || (blacklight_config.sort_fields.first ? blacklight_config.sort_fields.first.last : nil )
76
82
  end
77
83
 
84
+ def current_per_page
85
+ (@response.rows if @response and @response.rows > 0) || params.fetch(:per_page, (blacklight_config.per_page.first unless blacklight_config.per_page.blank?)).to_i
86
+ end
87
+
78
88
  # Export to Refworks URL, called in _show_tools
79
89
  def refworks_export_url(document = @document)
80
- "http://www.refworks.com/express/expressimport.asp?vendor=#{CGI.escape(application_name)}&filter=MARC%20Format&encoding=65001&url=#{CGI.escape(polymorphic_path(document, :format => 'refworks_marc_txt', :only_path => false))}"
90
+ "http://www.refworks.com/express/expressimport.asp?vendor=#{CGI.escape(application_name)}&filter=MARC%20Format&encoding=65001&url=#{CGI.escape(polymorphic_path(document, :format => 'refworks_marc_txt', :only_path => false))}"
81
91
  end
82
-
92
+
83
93
  def render_document_class(document = @document)
84
94
  'blacklight-' + document.get(blacklight_config.index.record_display_type).parameterize rescue nil
85
95
  end
@@ -91,4 +101,10 @@ module Blacklight::CatalogHelperBehavior
91
101
  def has_search_parameters?
92
102
  !params[:q].blank? or !params[:f].blank? or !params[:search_field].blank?
93
103
  end
104
+
105
+ def show_sort_and_per_page? response = nil
106
+ response ||= @response
107
+ response.response['numFound'] > 1
108
+ end
109
+
94
110
  end
@@ -86,7 +86,9 @@ module Blacklight::FacetsHelperBehavior
86
86
  # the name of the partial to use to render a facet field. Can be over-ridden for custom
87
87
  # display on a per-facet basis.
88
88
  def facet_partial_name(display_facet = nil)
89
- name = facet_configuration_for_field(display_facet.name).try(:partial)
89
+ config = facet_configuration_for_field(display_facet.name)
90
+ name = config.try(:partial)
91
+ name ||= "facet_pivot" if config.pivot
90
92
  name ||= "facet_limit"
91
93
  end
92
94
 
@@ -101,7 +103,7 @@ module Blacklight::FacetsHelperBehavior
101
103
  # options consist of:
102
104
  # :suppress_link => true # do not make it a link, used for an already selected value for instance
103
105
  def render_facet_value(facet_solr_field, item, options ={})
104
- (link_to_unless(options[:suppress_link], ((item.label if item.respond_to?(:label)) || item.value), add_facet_params_and_redirect(facet_solr_field, item.value), :class=>"facet_select") + " " + render_facet_count(item.hits)).html_safe
106
+ (link_to_unless(options[:suppress_link], item.label, add_facet_params_and_redirect(facet_solr_field, item), :class=>"facet_select") + " " + render_facet_count(item.hits)).html_safe
105
107
  end
106
108
 
107
109
  # Standard display of a SELECTED facet value, no link, special span
@@ -109,7 +111,7 @@ module Blacklight::FacetsHelperBehavior
109
111
  def render_selected_facet_value(facet_solr_field, item)
110
112
  #Updated class for Bootstrap Blacklight
111
113
  content_tag(:span, render_facet_value(facet_solr_field, item, :suppress_link => true), :class => "selected") +
112
- link_to(content_tag(:i, '', :class => "icon-remove") + content_tag(:span, '[remove]', :class => 'hide-text'), remove_facet_params(facet_solr_field, item.value, params), :class=>"remove")
114
+ link_to(content_tag(:i, '', :class => "icon-remove") + content_tag(:span, '[remove]', :class => 'hide-text'), remove_facet_params(facet_solr_field, item, params), :class=>"remove")
113
115
  end
114
116
 
115
117
  # Renders a count value for facet limits. Can be over-ridden locally
@@ -122,12 +124,17 @@ module Blacklight::FacetsHelperBehavior
122
124
  # Does NOT remove request keys and otherwise ensure that the hash
123
125
  # is suitable for a redirect. See
124
126
  # add_facet_params_and_redirect
125
- def add_facet_params(field, value)
127
+ def add_facet_params(field, item, source_params = params)
128
+
129
+ if item.respond_to? :field
130
+ field = item.field
131
+ end
132
+
126
133
  facet_config = facet_configuration_for_field(field)
127
134
 
128
-
135
+ value = facet_value_for_facet_item(item)
129
136
 
130
- p = params.dup
137
+ p = source_params.dup
131
138
  p[:f] = (p[:f] || {}).dup # the command above is not deep in rails3, !@#$!@#$
132
139
  p[:f][field] = (p[:f][field] || []).dup
133
140
 
@@ -136,6 +143,13 @@ module Blacklight::FacetsHelperBehavior
136
143
  end
137
144
 
138
145
  p[:f][field].push(value)
146
+
147
+ if item and item.respond_to?(:fq) and item.fq
148
+ item.fq.each do |f,v|
149
+ p = add_facet_params(f, v, p)
150
+ end
151
+ end
152
+
139
153
  p
140
154
  end
141
155
 
@@ -146,8 +160,8 @@ module Blacklight::FacetsHelperBehavior
146
160
  # for a 'fresh' display.
147
161
  # Change the action to 'index' to send them back to
148
162
  # catalog/index with their new facet choice.
149
- def add_facet_params_and_redirect(field, value)
150
- new_params = add_facet_params(field, value)
163
+ def add_facet_params_and_redirect(field, item)
164
+ new_params = add_facet_params(field, item)
151
165
 
152
166
  # Delete page, if needed.
153
167
  new_params.delete(:page)
@@ -167,7 +181,13 @@ module Blacklight::FacetsHelperBehavior
167
181
  # removes the field value from params[:f]
168
182
  # removes the field if there are no more values in params[:f][field]
169
183
  # removes additional params (page, id, etc..)
170
- def remove_facet_params(field, value, source_params=params)
184
+ def remove_facet_params(field, item, source_params=params)
185
+ if item.respond_to? :field
186
+ field = item.field
187
+ end
188
+
189
+ value = facet_value_for_facet_item(item)
190
+
171
191
  p = source_params.dup
172
192
  # need to dup the facet values too,
173
193
  # if the values aren't dup'd, then the values
@@ -184,11 +204,19 @@ module Blacklight::FacetsHelperBehavior
184
204
  end
185
205
 
186
206
  # true or false, depending on whether the field and value is in params[:f]
187
- def facet_in_params?(field, value)
207
+ def facet_in_params?(field, item)
208
+ if item and item.respond_to? :field
209
+ field = item.field
210
+ end
211
+
212
+ value = facet_value_for_facet_item(item)
213
+
188
214
  params[:f] and params[:f][field] and params[:f][field].include?(value)
189
215
  end
190
216
 
191
- def facet_display_value field, value
217
+ def facet_display_value field, item
218
+
219
+ value = facet_value_for_facet_item(item)
192
220
 
193
221
  facet_config = facet_configuration_for_field(field)
194
222
 
@@ -209,12 +237,22 @@ module Blacklight::FacetsHelperBehavior
209
237
 
210
238
  private
211
239
 
240
+ def facet_value_for_facet_item item
241
+ if item.respond_to? :value
242
+ value = item.value
243
+ else
244
+ value = item
245
+ end
246
+ end
247
+
212
248
  # Get the solr response for the solr field :field
213
249
  def extract_solr_facet_by_field_name facet_name
214
250
  facet_field = facet_configuration_for_field(facet_name)
215
251
  case
216
- when facet_field.query
217
- create_rsolr_facet_field_response_for_query_facet_field facet_name, facet_field
252
+ when (facet_field.respond_to?(:query) and facet_field.query)
253
+ create_rsolr_facet_field_response_for_query_facet_field facet_name, facet_field
254
+ when (facet_field.respond_to?(:pivot) and facet_field.pivot)
255
+ create_rsolr_facet_field_response_for_pivot_facet_field facet_name, facet_field
218
256
  else
219
257
  @response.facet_by_field_name(facet_name)
220
258
  end
@@ -226,9 +264,31 @@ module Blacklight::FacetsHelperBehavior
226
264
  @response.facet_queries.select { |k,v| salient_facet_queries.include?(k) }.reject { |value, hits| hits == 0 }.map do |value,hits|
227
265
  salient_fields = facet_field.query.select { |key, val| val[:fq] == value }
228
266
  key = ((salient_fields.keys if salient_fields.respond_to? :keys) || salient_fields.first).first
229
- items << OpenStruct.new(:value => key, :hits => hits, :label => facet_field.query[key][:label])
267
+ items << Blacklight::SolrResponse::Facets::FacetItem.new(:value => key, :hits => hits, :label => facet_field.query[key][:label])
268
+ end
269
+
270
+ Blacklight::SolrResponse::Facets::FacetField.new facet_name, items
271
+ end
272
+
273
+
274
+ def create_rsolr_facet_field_response_for_pivot_facet_field facet_name, facet_field
275
+ items = []
276
+ (@response.facet_pivot[facet_field.pivot.join(",")] || []).map do |lst|
277
+ items << construct_pivot_field(lst)
230
278
  end
231
279
 
232
280
  Blacklight::SolrResponse::Facets::FacetField.new facet_name, items
233
281
  end
282
+
283
+ def construct_pivot_field lst, parent_fq = {}
284
+ items = []
285
+
286
+ lst[:pivot].each do |i|
287
+ items << construct_pivot_field(i, parent_fq.merge({ lst[:field] => lst[:value] }))
288
+ end if lst[:pivot]
289
+
290
+ Blacklight::SolrResponse::Facets::FacetItem.new(:value => lst[:value], :hits => lst[:count], :field => lst[:field], :items => items, :fq => parent_fq)
291
+
292
+ end
293
+
234
294
  end