blacklight 3.0pre1

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.
Files changed (170) hide show
  1. data/.gitignore +17 -0
  2. data/.gitmodules +6 -0
  3. data/.yardopts +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +14 -0
  6. data/README.rdoc +168 -0
  7. data/Rakefile +9 -0
  8. data/app/controllers/bookmarks_controller.rb +98 -0
  9. data/app/controllers/feedback_controller.rb +37 -0
  10. data/app/controllers/folder_controller.rb +49 -0
  11. data/app/controllers/saved_searches_controller.rb +45 -0
  12. data/app/controllers/search_history_controller.rb +25 -0
  13. data/app/helpers/blacklight_helper.rb +606 -0
  14. data/app/helpers/bookmarks_helper.rb +3 -0
  15. data/app/helpers/catalog_helper.rb +65 -0
  16. data/app/helpers/feedback_helper.rb +2 -0
  17. data/app/helpers/hash_as_hidden_fields.rb +57 -0
  18. data/app/helpers/render_constraints_helper.rb +120 -0
  19. data/app/helpers/saved_searches_helper.rb +2 -0
  20. data/app/helpers/search_history_helper.rb +2 -0
  21. data/app/models/bookmark.rb +6 -0
  22. data/app/models/record_mailer.rb +43 -0
  23. data/app/models/search.rb +19 -0
  24. data/app/views/_flash_msg.html.erb +6 -0
  25. data/app/views/_user_util_links.html.erb +13 -0
  26. data/app/views/bookmarks/index.html.erb +33 -0
  27. data/app/views/catalog/_bookmark_control.html.erb +25 -0
  28. data/app/views/catalog/_bookmark_form.html.erb +8 -0
  29. data/app/views/catalog/_citation.html.erb +15 -0
  30. data/app/views/catalog/_constraints.html.erb +7 -0
  31. data/app/views/catalog/_constraints_element.html.erb +33 -0
  32. data/app/views/catalog/_did_you_mean.html.erb +10 -0
  33. data/app/views/catalog/_document_list.html.erb +30 -0
  34. data/app/views/catalog/_email_form.html.erb +11 -0
  35. data/app/views/catalog/_facet_limit.html.erb +33 -0
  36. data/app/views/catalog/_facet_pagination.html.erb +28 -0
  37. data/app/views/catalog/_facets.html.erb +9 -0
  38. data/app/views/catalog/_folder_control.html.erb +12 -0
  39. data/app/views/catalog/_home.html.erb +6 -0
  40. data/app/views/catalog/_home_text.html.erb +6 -0
  41. data/app/views/catalog/_index_partials/_default.erb +11 -0
  42. data/app/views/catalog/_marc_view.html.erb +33 -0
  43. data/app/views/catalog/_opensearch_response_metadata.html.erb +3 -0
  44. data/app/views/catalog/_previous_next_doc.html.erb +6 -0
  45. data/app/views/catalog/_refworks_form.html.erb +7 -0
  46. data/app/views/catalog/_results_pagination.html.erb +11 -0
  47. data/app/views/catalog/_search_form.html.erb +14 -0
  48. data/app/views/catalog/_show_partials/_default.html.erb +9 -0
  49. data/app/views/catalog/_show_sidebar.html.erb +1 -0
  50. data/app/views/catalog/_show_tools.html.erb +46 -0
  51. data/app/views/catalog/_sms_form.html.erb +23 -0
  52. data/app/views/catalog/_solr_request.html.erb +5 -0
  53. data/app/views/catalog/_sort_and_per_page.html.erb +20 -0
  54. data/app/views/catalog/_unapi_microformat.html.erb +1 -0
  55. data/app/views/catalog/citation.html.erb +1 -0
  56. data/app/views/catalog/email.erb +1 -0
  57. data/app/views/catalog/endnote.endnote.erb +1 -0
  58. data/app/views/catalog/facet.html.erb +28 -0
  59. data/app/views/catalog/index.atom.builder +108 -0
  60. data/app/views/catalog/index.html.erb +37 -0
  61. data/app/views/catalog/index.rss.builder +19 -0
  62. data/app/views/catalog/librarian_view.html.erb +3 -0
  63. data/app/views/catalog/opensearch.json.erb +0 -0
  64. data/app/views/catalog/opensearch.xml.erb +11 -0
  65. data/app/views/catalog/send_email_record.erb +0 -0
  66. data/app/views/catalog/show.endnote.erb +1 -0
  67. data/app/views/catalog/show.html.erb +42 -0
  68. data/app/views/catalog/show.refworks.erb +1 -0
  69. data/app/views/catalog/sms.erb +1 -0
  70. data/app/views/catalog/unapi.xml.builder +6 -0
  71. data/app/views/feedback/complete.html.erb +3 -0
  72. data/app/views/feedback/show.html.erb +20 -0
  73. data/app/views/folder/_tools.html.erb +23 -0
  74. data/app/views/folder/index.html.erb +44 -0
  75. data/app/views/layouts/blacklight.html.erb +49 -0
  76. data/app/views/record_mailer/email_record.erb +6 -0
  77. data/app/views/record_mailer/sms_record.erb +4 -0
  78. data/app/views/saved_searches/index.html.erb +27 -0
  79. data/app/views/search_history/index.html.erb +23 -0
  80. data/blacklight.gemspec +50 -0
  81. data/config.ru +4 -0
  82. data/config/routes.rb +54 -0
  83. data/db/seeds.rb +7 -0
  84. data/features/generators.feature +77 -0
  85. data/features/support/aruba.rb +9 -0
  86. data/install.rb +0 -0
  87. data/install/solr.yml +8 -0
  88. data/lib/blacklight.rb +121 -0
  89. data/lib/blacklight/catalog.rb +311 -0
  90. data/lib/blacklight/comma_link_renderer.rb +27 -0
  91. data/lib/blacklight/configurable.rb +46 -0
  92. data/lib/blacklight/controller.rb +121 -0
  93. data/lib/blacklight/engine.rb +32 -0
  94. data/lib/blacklight/exceptions.rb +13 -0
  95. data/lib/blacklight/marc.rb +46 -0
  96. data/lib/blacklight/marc/citation.rb +251 -0
  97. data/lib/blacklight/search_fields.rb +107 -0
  98. data/lib/blacklight/solr.rb +7 -0
  99. data/lib/blacklight/solr/document.rb +239 -0
  100. data/lib/blacklight/solr/document/dublin_core.rb +40 -0
  101. data/lib/blacklight/solr/document/email.rb +15 -0
  102. data/lib/blacklight/solr/document/marc.rb +84 -0
  103. data/lib/blacklight/solr/document/marc_export.rb +430 -0
  104. data/lib/blacklight/solr/document/sms.rb +13 -0
  105. data/lib/blacklight/solr/facet_paginator.rb +93 -0
  106. data/lib/blacklight/solr_helper.rb +413 -0
  107. data/lib/blacklight/user.rb +55 -0
  108. data/lib/blacklight/version.rb +3 -0
  109. data/lib/colorize.rb +196 -0
  110. data/lib/generators/blacklight/blacklight_generator.rb +134 -0
  111. data/lib/generators/blacklight/templates/SolrMarc.jar +0 -0
  112. data/lib/generators/blacklight/templates/catalog_controller.rb +8 -0
  113. data/lib/generators/blacklight/templates/config/SolrMarc/config-test.properties +37 -0
  114. data/lib/generators/blacklight/templates/config/SolrMarc/config.properties +37 -0
  115. data/lib/generators/blacklight/templates/config/SolrMarc/index.properties +97 -0
  116. data/lib/generators/blacklight/templates/config/SolrMarc/index_scripts/dewey.bsh +47 -0
  117. data/lib/generators/blacklight/templates/config/SolrMarc/index_scripts/format.bsh +126 -0
  118. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/README_MAPS +1 -0
  119. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/callnumber_map.properties +407 -0
  120. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/composition_era_map.properties +56 -0
  121. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/country_map.properties +379 -0
  122. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/format_map.properties +50 -0
  123. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/instrument_map.properties +101 -0
  124. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/language_map.properties +490 -0
  125. data/lib/generators/blacklight/templates/config/blacklight_config.rb +245 -0
  126. data/lib/generators/blacklight/templates/config/solr.yml +6 -0
  127. data/lib/generators/blacklight/templates/migrations/add_user_types_to_bookmarks_searches.rb +11 -0
  128. data/lib/generators/blacklight/templates/migrations/create_bookmarks.rb +17 -0
  129. data/lib/generators/blacklight/templates/migrations/create_searches.rb +15 -0
  130. data/lib/generators/blacklight/templates/migrations/remove_editable_fields_from_bookmarks.rb +11 -0
  131. data/lib/generators/blacklight/templates/public/images/blacklight/bg.png +0 -0
  132. data/lib/generators/blacklight/templates/public/images/blacklight/border.png +0 -0
  133. data/lib/generators/blacklight/templates/public/images/blacklight/bul_sq_gry.gif +0 -0
  134. data/lib/generators/blacklight/templates/public/images/blacklight/checkmark.gif +0 -0
  135. data/lib/generators/blacklight/templates/public/images/blacklight/logo.png +0 -0
  136. data/lib/generators/blacklight/templates/public/images/blacklight/magnifying_glass.gif +0 -0
  137. data/lib/generators/blacklight/templates/public/images/blacklight/remove.gif +0 -0
  138. data/lib/generators/blacklight/templates/public/images/blacklight/separator.gif +0 -0
  139. data/lib/generators/blacklight/templates/public/images/blacklight/start_over.gif +0 -0
  140. data/lib/generators/blacklight/templates/public/javascripts/blacklight.js +485 -0
  141. data/lib/generators/blacklight/templates/public/javascripts/jquery-1.4.2.min.js +154 -0
  142. data/lib/generators/blacklight/templates/public/javascripts/jquery-ui-1.8.1.custom.min.js +756 -0
  143. data/lib/generators/blacklight/templates/public/stylesheets/blacklight.css +487 -0
  144. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  145. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  146. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  147. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  148. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  149. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  150. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_gloss-wave_35_558fd0_500x100.png +0 -0
  151. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  152. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  153. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  154. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  155. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_2e4f81_256x240.png +0 -0
  156. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  157. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  158. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/jquery-ui-1.8.1.custom.css +486 -0
  159. data/lib/generators/blacklight/templates/public/stylesheets/yui.css +31 -0
  160. data/lib/generators/blacklight/templates/solr_document.rb +30 -0
  161. data/lib/railties/blacklight.rake +66 -0
  162. data/lib/railties/cucumber.rake +53 -0
  163. data/lib/railties/rspec.rake +188 -0
  164. data/lib/railties/solr_marc.rake +148 -0
  165. data/lib/railties/test_solr_server.rb +130 -0
  166. data/spec/helpers/catalog_helper_spec.rb +111 -0
  167. data/spec/views/catalog/_sms_form.html.erb_spec.rb +19 -0
  168. data/tasks/blacklight_tasks.rake +4 -0
  169. data/uninstall.rb +1 -0
  170. metadata +431 -0
@@ -0,0 +1,25 @@
1
+ class SearchHistoryController < ApplicationController
2
+ def index
3
+ @searches = searches_from_history
4
+ end
5
+
6
+ #TODO we may want to remove unsaved (those without user_id) items from the database when removed from history
7
+ def destroy
8
+ if session[:history].delete(params[:id].to_i)
9
+ flash[:notice] = "Successfully removed that search history item."
10
+ else
11
+ flash[:error] = "Couldn't remove that search history item."
12
+ end
13
+ redirect_to :back
14
+ end
15
+
16
+ #TODO we may want to remove unsaved (those without user_id) items from the database when removed from history
17
+ def clear
18
+ if session[:history].clear
19
+ flash[:notice] = "Cleared your search history."
20
+ else
21
+ flash[:error] = "There was a problem clearing your search history."
22
+ end
23
+ redirect_to :back
24
+ end
25
+ end
@@ -0,0 +1,606 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Methods added to this helper will be available to all templates in the hosting application
4
+ #
5
+ module BlacklightHelper
6
+ include HashAsHiddenFields
7
+ include RenderConstraintsHelper
8
+
9
+
10
+ def application_name
11
+ 'Blacklight'
12
+ end
13
+
14
+ ##
15
+ # This method should be included in any Blacklight layout, including
16
+ # custom ones. It will output results of #render_js_includes,
17
+ # #render_stylesheet_includes, and all the content of
18
+ # current_controller#extra_head_content.
19
+ #
20
+ # Uses controller methods #extra_head_content, #javascript_includes,
21
+ # and #stylesheet_links to find content. Tolerates it if those
22
+ # methods don't exist, silently skipping.
23
+ #
24
+ # By a layout outputting this in html HEAD, it provides an easy way for
25
+ # local config or extra plugins to add HEAD content.
26
+ #
27
+ # Add your own css or remove the defaults by simply editing
28
+ # controller.stylesheet_links, controller.javascript_includes,
29
+ # or controller.extra_head_content.
30
+ #
31
+ #
32
+ #
33
+ # in an initializer or other startup file (plugin init.rb?):
34
+ #
35
+ # == Apply to all actions in all controllers:
36
+ #
37
+ # ApplicationController.before_filter do |controller|
38
+ # # remove default jquery-ui theme.
39
+ # controller.stylesheet_links.each do |args|
40
+ # args.delete_if {|a| a =~ /^|\/jquery-ui-[\d.]+\.custom\.css$/ }
41
+ # end
42
+ #
43
+ # # add in a different jquery-ui theme, or any other css or what have you
44
+ # controller.stylesheet_links << 'my_css.css'
45
+ #
46
+ # controller.javascript_includes << "my_local_behaviors.js"
47
+ #
48
+ # controller.extra_head_content << '<link rel="something" href="something">'
49
+ # end
50
+ #
51
+ # == Apply to a particular action in a particular controller:
52
+ #
53
+ # CatalogController.before_filter :only => :show |controller|
54
+ # controller.extra_head_content << '<link rel="something" href="something">'
55
+ # end
56
+ #
57
+ # == Or in a view file that wants to add certain header content? no problem:
58
+ #
59
+ # <% stylesheet_links << "mystylesheet.css" %>
60
+ # <% javascript_includes << "my_js.js" %>
61
+ # <% extra_head_content << capture do %>
62
+ # <%= tag :link, { :href => some_method_for_something, :rel => "alternate" } %>
63
+ # <% end %>
64
+ #
65
+ # == Full power of javascript_include_tag and stylesheet_link_tag
66
+ # Note that the elements added to stylesheet_links and javascript_links
67
+ # are arguments to Rails javascript_include_tag and stylesheet_link_tag
68
+ # respectively, you can pass complex arguments. eg:
69
+ #
70
+ # stylesheet_links << ["stylesheet1.css", "stylesheet2.css", {:cache => "mykey"}]
71
+ # javascript_includes << ["myjavascript.js", {:plugin => :myplugin} ]
72
+ def render_head_content
73
+ render_stylesheet_includes +
74
+ render_js_includes +
75
+ render_extra_head_content
76
+ end
77
+
78
+ ##
79
+ # Assumes controller has a #stylesheet_link_tag method, array with
80
+ # each element being a set of arguments for stylesheet_link_tag
81
+ # See #render_head_content for instructions on local code or plugins
82
+ # adding stylesheets.
83
+ def render_stylesheet_includes
84
+ return "".html_safe unless respond_to?(:stylesheet_links)
85
+
86
+ stylesheet_links.collect do |args|
87
+ stylesheet_link_tag(*args)
88
+ end.join("\n").html_safe
89
+ end
90
+
91
+
92
+ ##
93
+ # Assumes controller has a #js_includes method, array with each
94
+ # element being a set of arguments for javsascript_include_tag.
95
+ # See #render_head_content for instructions on local code or plugins
96
+ # adding js files.
97
+ def render_js_includes
98
+ return "".html_safe unless respond_to?(:javascript_includes)
99
+
100
+ javascript_includes.collect do |args|
101
+ javascript_include_tag(*args)
102
+ end.join("\n").html_safe
103
+ end
104
+
105
+ ##
106
+ # Assumes controller has a #extra_head_content method
107
+ #
108
+ def render_extra_head_content
109
+ return "".html_safe unless respond_to?(:extra_head_content)
110
+
111
+ extra_head_content.join("\n").html_safe
112
+ end
113
+
114
+ # Create <link rel="alternate"> links from a documents dynamically
115
+ # provided export formats. Currently not used by standard BL layouts,
116
+ # but available for your custom layouts to provide link rel alternates.
117
+ #
118
+ # Returns empty string if no links available.
119
+ #
120
+ # :unique => true, will ensure only one link is output for every
121
+ # content type, as required eg in atom. Which one 'wins' is arbitrary.
122
+ # :exclude => array of format shortnames, formats to not include at all.
123
+ def render_link_rel_alternates(document=@document, options = {})
124
+ options = {:unique => false, :exclude => []}.merge(options)
125
+
126
+ return nil if document.nil?
127
+
128
+ seen = Set.new
129
+
130
+ html = ""
131
+ document.export_formats.each_pair do |format, spec|
132
+ unless( options[:exclude].include?(format) ||
133
+ (options[:unique] && seen.include?(spec[:content_type]))
134
+ )
135
+ html << tag(:link, {:rel=>"alternate", :title=>format, :type => spec[:content_type], :href=> catalog_url(document[:id], format)}) << "\n"
136
+
137
+ seen.add(spec[:content_type]) if options[:unique]
138
+ end
139
+ end
140
+ return html.html_safe
141
+ end
142
+
143
+ def render_opensearch_response_metadata
144
+ render :partial => 'catalog/opensearch_response_metadata'
145
+ end
146
+
147
+ def render_body_class
148
+ extra_body_classes.join " "
149
+ end
150
+
151
+ # collection of items to be rendered in the @sidebar
152
+ def sidebar_items
153
+ @sidebar_items ||= []
154
+ end
155
+
156
+ def extra_body_classes
157
+ @extra_body_classes ||= ['blacklight-' + controller.controller_name, 'blacklight-' + [controller.controller_name, controller.action_name].join('-')]
158
+ end
159
+
160
+ #
161
+ # Blacklight.config based helpers ->
162
+ #
163
+
164
+ # used in the catalog/_facets partial
165
+ def facet_field_labels
166
+ Blacklight.config[:facet][:labels]
167
+ end
168
+
169
+ # used in the catalog/_facets partial
170
+ def facet_field_names
171
+ Blacklight.config[:facet][:field_names]
172
+ end
173
+
174
+ # used in the catalog/_facets partial and elsewhere
175
+ # Renders a single section for facet limit with a specified
176
+ # solr field used for faceting. Can be over-ridden for custom
177
+ # display on a per-facet basis.
178
+ def render_facet_limit(solr_field)
179
+ render( :partial => "catalog/facet_limit", :locals => {:solr_field =>solr_field })
180
+ end
181
+
182
+ def render_document_list_partial options={}
183
+ render :partial=>'catalog/document_list'
184
+ end
185
+
186
+ # Save function area for search results 'index' view, normally
187
+ # renders next to title. Includes just 'Folder' by default.
188
+ def render_index_doc_actions(document, options={})
189
+ content_tag("div", :class=>"documentFunctions") do
190
+ raw("#{render(:partial => 'bookmark_control', :locals => {:document=> document}.merge(options))}
191
+ #{render(:partial => 'folder_control', :locals => {:document=> document}.merge(options))}")
192
+ end
193
+ end
194
+
195
+ # Save function area for item detail 'show' view, normally
196
+ # renders next to title. By default includes 'Folder' and 'Bookmarks'
197
+ def render_show_doc_actions(document=@document, options={})
198
+ content_tag("div", :class=>"documentFunctions") do
199
+ raw("#{render(:partial => 'bookmark_control', :locals => {:document=> document}.merge(options))}
200
+ #{render(:partial => 'folder_control', :locals => {:document=> document}.merge(options))}")
201
+ end
202
+ end
203
+
204
+ # used in the catalog/_index_partials/_default view
205
+ def index_field_names
206
+ Blacklight.config[:index_fields][:field_names]
207
+ end
208
+
209
+ # used in the _index_partials/_default view
210
+ def index_field_labels
211
+ Blacklight.config[:index_fields][:labels]
212
+ end
213
+
214
+ def spell_check_max
215
+ Blacklight.config[:spell_max] || 0
216
+ end
217
+
218
+ def render_index_field_label args
219
+ field = args[:field]
220
+ html_escape index_field_labels[field]
221
+ end
222
+
223
+ def render_index_field_value args
224
+ value = args[:value]
225
+ value ||= args[:document].get(args[:field], :sep => nil) if args[:document] and args[:field]
226
+ render_field_value value
227
+ end
228
+
229
+ # Used in the show view for displaying the main solr document heading
230
+ def document_heading
231
+ @document[Blacklight.config[:show][:heading]] || @document.id
232
+ end
233
+ def render_document_heading
234
+ content_tag(:h1, document_heading)
235
+ end
236
+
237
+ # Used in the show view for setting the main html document title
238
+ def document_show_html_title
239
+ @document[Blacklight.config[:show][:html_title]]
240
+ end
241
+
242
+ # Used in citation view for displaying the title
243
+ def citation_title(document)
244
+ document[Blacklight.config[:show][:html_title]]
245
+ end
246
+
247
+ # Used in the document_list partial (search view) for building a select element
248
+ def sort_fields
249
+ Blacklight.config[:sort_fields]
250
+ end
251
+
252
+ # Used in the document list partial (search view) for creating a link to the document show action
253
+ def document_show_link_field
254
+ Blacklight.config[:index][:show_link].to_sym
255
+ end
256
+
257
+ # Used in the search form partial for building a select tag
258
+ def search_fields
259
+ Blacklight.search_field_options_for_select
260
+ end
261
+
262
+ # used in the catalog/_show/_default partial
263
+ def document_show_fields
264
+ Blacklight.config[:show_fields][:field_names]
265
+ end
266
+
267
+ # used in the catalog/_show/_default partial
268
+ def document_show_field_labels
269
+ Blacklight.config[:show_fields][:labels]
270
+ end
271
+
272
+ def render_document_show_field_label args
273
+ field = args[:field]
274
+ html_escape document_show_field_labels[field]
275
+ end
276
+
277
+ def render_document_show_field_value args
278
+ value = args[:value]
279
+ value ||= args[:document].get(args[:field], :sep => nil) if args[:document] and args[:field]
280
+ render_field_value value
281
+ end
282
+
283
+ def render_field_value value=nil
284
+ value = [value] unless value.is_a? Array
285
+ return value.map { |v| html_escape v }.join(field_value_separator).html_safe
286
+ end
287
+
288
+ def field_value_separator
289
+ ', '
290
+ end
291
+
292
+ # Return a normalized partial name that can be used to contruct view partial path
293
+ def document_partial_name(document)
294
+ # .to_s is necessary otherwise the default return value is not always a string
295
+ # using "_" as sep. to more closely follow the views file naming conventions
296
+ # parameterize uses "-" as the default sep. which throws errors
297
+ display_type = document[Blacklight.config[:show][:display_type]]
298
+ if display_type
299
+ if display_type.respond_to?(:join)
300
+ "#{display_type.join(" ").gsub("-"," ")}".parameterize("_").to_s
301
+ else
302
+ "#{display_type.gsub("-"," ")}".parameterize("_").to_s
303
+ end
304
+ end
305
+ end
306
+
307
+ # given a doc and action_name, this method attempts to render a partial template
308
+ # based on the value of doc[:format]
309
+ # if this value is blank (nil/empty) the "default" is used
310
+ # if the partial is not found, the "default" partial is rendered instead
311
+ def render_document_partial(doc, action_name)
312
+ format = document_partial_name(doc)
313
+ begin
314
+ render :partial=>"catalog/_#{action_name}_partials/#{format}", :locals=>{:document=>doc}
315
+ rescue ActionView::MissingTemplate
316
+ render :partial=>"catalog/_#{action_name}_partials/default", :locals=>{:document=>doc}
317
+ end
318
+ end
319
+
320
+ # Search History and Saved Searches display
321
+ def link_to_previous_search(params)
322
+ link_to(raw(render_search_to_s(params)), catalog_index_path(params)).html_safe
323
+ end
324
+
325
+ #
326
+ # facet param helpers ->
327
+ #
328
+
329
+ # Standard display of a facet value in a list. Used in both _facets sidebar
330
+ # partial and catalog/facet expanded list. Will output facet value name as
331
+ # a link to add that to your restrictions, with count in parens.
332
+ # first arg item is a facet value item from rsolr-ext.
333
+ # options consist of:
334
+ # :suppress_link => true # do not make it a link, used for an already selected value for instance
335
+ def render_facet_value(facet_solr_field, item, options ={})
336
+ (link_to_unless(options[:suppress_link], item.value, add_facet_params_and_redirect(facet_solr_field, item.value), :class=>"facet_select label") + " " + render_facet_count(item.hits)).html_safe
337
+ end
338
+
339
+ # Standard display of a SELECTED facet value, no link, special span
340
+ # with class, and 'remove' button.
341
+ def render_selected_facet_value(facet_solr_field, item)
342
+ content_tag(:span, render_facet_value(facet_solr_field, item, :suppress_link => true), :class => "selected label") +
343
+ link_to("[remove]", remove_facet_params(facet_solr_field, item.value, params), :class=>"remove")
344
+ end
345
+
346
+ # Renders a count value for facet limits. Can be over-ridden locally
347
+ # to change style, for instance not use parens. And can be called
348
+ # by plugins to get consistent display.
349
+ def render_facet_count(num)
350
+ content_tag("span", "(" + format_num(num) + ")", :class => "count")
351
+ end
352
+
353
+ # adds the value and/or field to params[:f]
354
+ # Does NOT remove request keys and otherwise ensure that the hash
355
+ # is suitable for a redirect. See
356
+ # add_facet_params_and_redirect
357
+ def add_facet_params(field, value)
358
+ p = params.dup
359
+ p[:f] = params[:f].nil? ? {} : params[:f].dup # the command above is not deep in rails3, !@#$!@#$
360
+ p[:f][field] ||= []
361
+ p[:f][field].push(value)
362
+ p
363
+ end
364
+
365
+ # Used in catalog/facet action, facets.rb view, for a click
366
+ # on a facet value. Add on the facet params to existing
367
+ # search constraints. Remove any paginator-specific request
368
+ # params, or other request params that should be removed
369
+ # for a 'fresh' display.
370
+ # Change the action to 'index' to send them back to
371
+ # catalog/index with their new facet choice.
372
+ def add_facet_params_and_redirect(field, value)
373
+ new_params = add_facet_params(field, value)
374
+
375
+ # Delete page, if needed.
376
+ new_params.delete(:page)
377
+
378
+ # Delete any request params from facet-specific action, needed
379
+ # to redir to index action properly.
380
+ Blacklight::Solr::FacetPaginator.request_keys.values.each do |paginator_key|
381
+ new_params.delete(paginator_key)
382
+ end
383
+ new_params.delete(:id)
384
+
385
+ # Force action to be index.
386
+ new_params[:action] = "index"
387
+ new_params
388
+ end
389
+ # copies the current params (or whatever is passed in as the 3rd arg)
390
+ # removes the field value from params[:f]
391
+ # removes the field if there are no more values in params[:f][field]
392
+ # removes additional params (page, id, etc..)
393
+ def remove_facet_params(field, value, source_params=params)
394
+ p = source_params.dup
395
+ # need to dup the facet values too,
396
+ # if the values aren't dup'd, then the values
397
+ # from the session will get remove in the show view...
398
+ p[:f] = p[:f].dup
399
+ p.delete :page
400
+ p.delete :id
401
+ p.delete :counter
402
+ p.delete :commit
403
+ #return p unless p[field]
404
+ p[:f][field] = p[:f][field] - [value]
405
+ p[:f].delete(field) if p[:f][field].size == 0
406
+ p
407
+ end
408
+
409
+ # true or false, depending on whether the field and value is in params[:f]
410
+ def facet_in_params?(field, value)
411
+ params[:f] and params[:f][field] and params[:f][field].include?(value)
412
+ end
413
+
414
+ #
415
+ # shortcut for built-in Rails helper, "number_with_delimiter"
416
+ #
417
+ def format_num(num); number_with_delimiter(num) end
418
+
419
+ #
420
+ # link based helpers ->
421
+ #
422
+
423
+ # create link to query (e.g. spelling suggestion)
424
+ def link_to_query(query)
425
+ p = params.dup
426
+ p.delete :page
427
+ p.delete :action
428
+ p[:q]=query
429
+ link_url = catalog_index_path(p)
430
+ link_to(query, link_url)
431
+ end
432
+
433
+ def render_document_index_label doc, opts
434
+ label = nil
435
+ label ||= doc.get(opts[:label]) if opts[:label].instance_of? Symbol
436
+ label ||= opts[:label].call(doc, opts) if opts[:label].instance_of? Proc
437
+ label ||= opts[:label] if opts[:label].is_a? String
438
+ label ||= doc.id
439
+ end
440
+
441
+ # link_to_document(doc, :label=>'VIEW', :counter => 3)
442
+ # Use the catalog_path RESTful route to create a link to the show page for a specific item.
443
+ # catalog_path accepts a HashWithIndifferentAccess object. The solr query params are stored in the session,
444
+ # so we only need the +counter+ param here. We also need to know if we are viewing to document as part of search results.
445
+ def link_to_document(doc, opts={:label=>Blacklight.config[:index][:show_link].to_sym, :counter => nil, :results_view => true})
446
+ label = render_document_index_label doc, opts
447
+ link_to_with_data(label, catalog_path(doc[:id]), {:method => :put, :class => label.parameterize, :data => opts}).html_safe
448
+ end
449
+
450
+ # link_back_to_catalog(:label=>'Back to Search')
451
+ # Create a link back to the index screen, keeping the user's facet, query and paging choices intact by using session.
452
+ def link_back_to_catalog(opts={:label=>'Back to Search'})
453
+ query_params = session[:search] ? session[:search].dup : {}
454
+ query_params.delete :counter
455
+ query_params.delete :total
456
+ link_url = catalog_index_path + "?" + query_params.to_query
457
+ link_to opts[:label], link_url
458
+ end
459
+
460
+ # Create form input type=hidden fields representing the entire search context,
461
+ # for inclusion in a form meant to change some aspect of it, like
462
+ # re-sort or change records per page. Can pass in params hash
463
+ # as :params => hash, otherwise defaults to #params. Can pass
464
+ # in certain top-level params keys to _omit_, defaults to :page
465
+ def search_as_hidden_fields(options={})
466
+
467
+ options = {:params => params, :omit_keys => [:page]}.merge(options)
468
+ my_params = options[:params].dup
469
+ options[:omit_keys].each {|omit_key| my_params.delete(omit_key)}
470
+ # removing action and controller from duplicate params so that we don't get hidden fields for them.
471
+ my_params.delete(:action)
472
+ my_params.delete(:controller)
473
+ # hash_as_hidden_fields in hash_as_hidden_fields.rb
474
+ return hash_as_hidden_fields(my_params)
475
+ end
476
+
477
+
478
+
479
+ def link_to_previous_document(previous_document)
480
+ return if previous_document == nil
481
+ link_to_document previous_document, :label=>'« Previous', :counter => session[:search][:counter].to_i - 1
482
+ end
483
+
484
+ def link_to_next_document(next_document)
485
+ return if next_document == nil
486
+ link_to_document next_document, :label=>'Next »', :counter => session[:search][:counter].to_i + 1
487
+ end
488
+
489
+ # Use case, you want to render an html partial from an XML (say, atom)
490
+ # template. Rails API kind of lets us down, we need to hack Rails internals
491
+ # a bit. code taken from:
492
+ # http://stackoverflow.com/questions/339130/how-do-i-render-a-partial-of-a-different-format-in-rails
493
+ def with_format(format, &block)
494
+ old_format = @template_format
495
+ @template_format = format
496
+ result = block.call
497
+ @template_format = old_format
498
+ return result
499
+ end
500
+
501
+
502
+ # This is an updated +link_to+ that allows you to pass a +data+ hash along with the +html_options+
503
+ # which are then written to the generated form for non-GET requests. The key is the form element name
504
+ # and the value is the value:
505
+ #
506
+ # link_to_with_data('Name', some_path(some_id), :method => :post, :html)
507
+ def link_to_with_data(*args, &block)
508
+ if block_given?
509
+ options = args.first || {}
510
+ html_options = args.second
511
+ concat(link_to(capture(&block), options, html_options))
512
+ else
513
+ name = args.first
514
+ options = args.second || {}
515
+ html_options = args.third
516
+
517
+ url = url_for(options)
518
+
519
+ if html_options
520
+ html_options = html_options.stringify_keys
521
+ href = html_options['href']
522
+ convert_options_to_javascript_with_data!(html_options, url)
523
+ tag_options = tag_options(html_options)
524
+ else
525
+ tag_options = nil
526
+ end
527
+
528
+ href_attr = "href=\"#{url}\"" unless href
529
+ "<a #{href_attr}#{tag_options}>#{h(name) || h(url)}</a>".html_safe
530
+ end
531
+ end
532
+
533
+ # This is derived from +convert_options_to_javascript+ from module +UrlHelper+ in +url_helper.rb+
534
+ def convert_options_to_javascript_with_data!(html_options, url = '')
535
+ confirm, popup = html_options.delete("confirm"), html_options.delete("popup")
536
+
537
+ method, href = html_options.delete("method"), html_options['href']
538
+ data = html_options.delete("data")
539
+ data = data.stringify_keys if data
540
+
541
+ html_options["onclick"] = case
542
+ when method
543
+ "#{method_javascript_function_with_data(method, url, href, data)}return false;"
544
+ else
545
+ html_options["onclick"]
546
+ end
547
+ end
548
+
549
+ # This is derived from +method_javascript_function+ from module +UrlHelper+ in +url_helper.rb+
550
+ def method_javascript_function_with_data(method, url = '', href = nil, data=nil)
551
+ action = (href && url.size > 0) ? "'#{url}'" : 'this.href'
552
+ submit_function =
553
+ "var f = document.createElement('form'); f.style.display = 'none'; " +
554
+ "this.parentNode.appendChild(f); f.method = 'POST'; f.action = #{action};"+
555
+ "if(event.metaKey || event.ctrlKey){f.target = '_blank';};" # if the command or control key is being held down while the link is clicked set the form's target to _blank
556
+ if data
557
+ data.each_pair do |key, value|
558
+ submit_function << "var d = document.createElement('input'); d.setAttribute('type', 'hidden'); "
559
+ submit_function << "d.setAttribute('name', '#{key}'); d.setAttribute('value', '#{escape_javascript(value.to_s)}'); f.appendChild(d);"
560
+ end
561
+ end
562
+ unless method == :post
563
+ submit_function << "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); "
564
+ submit_function << "m.setAttribute('name', '_method'); m.setAttribute('value', '#{method}'); f.appendChild(m);"
565
+ end
566
+
567
+ if protect_against_forgery?
568
+ submit_function << "var s = document.createElement('input'); s.setAttribute('type', 'hidden'); "
569
+ submit_function << "s.setAttribute('name', '#{request_forgery_protection_token}'); s.setAttribute('value', '#{escape_javascript form_authenticity_token}'); f.appendChild(s);"
570
+ end
571
+ submit_function << "f.submit();"
572
+ end
573
+
574
+ # determines if the given document id is in the folder
575
+ def item_in_folder?(doc_id)
576
+ session[:folder_document_ids] && session[:folder_document_ids].include?(doc_id) ? true : false
577
+ end
578
+
579
+ # puts together a collection of documents into one refworks export string
580
+ def render_refworks_texts(documents)
581
+ val = ''
582
+ documents.each do |doc|
583
+ if doc.respond_to?(:to_marc)
584
+ val += doc.export_as_refworks_marc_txt + "\n"
585
+ end
586
+ end
587
+ val
588
+ end
589
+
590
+ # puts together a collection of documents into one endnote export string
591
+ def render_endnote_texts(documents)
592
+ val = ''
593
+ documents.each do |doc|
594
+ if doc.respond_to?(:to_marc)
595
+ val += doc.export_as_endnote + "\n"
596
+ end
597
+ end
598
+ val
599
+ end
600
+
601
+
602
+ def render_document_unapi_microformat(document, options={})
603
+ render(:partial=>'catalog/unapi_microformat', :locals => {:document=> document}.merge(options))
604
+ end
605
+
606
+ end