hydra-head 3.1.0.pre5 → 3.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/HISTORY.textile +14 -1
  2. data/app/helpers/application_helper.rb +1 -166
  3. data/app/helpers/article_metadata_helper.rb +2 -78
  4. data/app/helpers/blacklight_helper.rb +2 -195
  5. data/app/helpers/downloads_helper.rb +3 -18
  6. data/app/helpers/generic_content_objects_helper.rb +2 -14
  7. data/app/helpers/hydra/application_helper_behavior.rb +10 -0
  8. data/app/helpers/hydra/article_metadata_helper_behavior.rb +82 -0
  9. data/app/helpers/hydra/blacklight_helper_behavior.rb +203 -0
  10. data/app/helpers/hydra/downloads_helper_behavior.rb +21 -0
  11. data/app/helpers/hydra/generic_content_objects_helper_behavior.rb +16 -0
  12. data/app/helpers/hydra/hydra_assets_helper_behavior.rb +66 -0
  13. data/app/helpers/hydra/hydra_djatoka_helper_behavior.rb +23 -0
  14. data/app/helpers/hydra/hydra_fedora_metadata_helper_behavior.rb +349 -0
  15. data/app/helpers/hydra/hydra_helper_behavior.rb +184 -0
  16. data/app/helpers/hydra/hydra_uploader_helper_behavior.rb +18 -0
  17. data/app/helpers/hydra/inline_editable_metadata_helper_behavior.rb +15 -0
  18. data/app/helpers/hydra/javascript_includes_helper_behavior.rb +91 -0
  19. data/app/helpers/hydra/personalization_helper_behavior.rb +44 -0
  20. data/app/helpers/hydra/release_process_helper_behavior.rb +32 -0
  21. data/app/helpers/hydra_assets_helper.rb +2 -64
  22. data/app/helpers/hydra_djatoka_helper.rb +3 -22
  23. data/app/helpers/hydra_fedora_metadata_helper.rb +2 -347
  24. data/app/helpers/hydra_helper.rb +2 -182
  25. data/app/helpers/hydra_uploader_helper.rb +2 -16
  26. data/app/helpers/inline_editable_metadata_helper.rb +3 -14
  27. data/app/helpers/javascript_includes_helper.rb +2 -89
  28. data/app/helpers/personalization_helper.rb +2 -42
  29. data/app/helpers/release_process_helper.rb +2 -30
  30. data/lib/blacklight/blacklight_helper_behavior.rb +612 -0
  31. data/lib/hydra-head/version.rb +1 -1
  32. data/lib/railties/hydra-fixtures.rake +0 -1
  33. data/tasks/hydra-head.rake +1 -2
  34. data/test_support/features/step_definitions/edit_metadata_steps.rb +0 -1
  35. data/{spec → test_support/spec}/controllers/catalog_valid_html_spec.rb +1 -11
  36. data/test_support/spec/helpers/blacklight_helper_spec.rb +6 -2
  37. data/test_support/spec/spec_helper.rb +5 -3
  38. metadata +23 -14
  39. data/lib/hydra/fixture_loader.rb +0 -48
  40. data/lib/stanford/searchworks_helper.rb +0 -1338
  41. data/lib/stanford/solr_helper.rb +0 -108
  42. data/lib/stanford_blacklight_extensions.rb +0 -6
  43. data/spec-rails2/helpers/hydra_fedora_metadata_helper_spec.rb +0 -219
  44. data/spec-rails2/spec_helper.rb +0 -88
@@ -1,184 +1,4 @@
1
- require "hydra/submission_workflow"
2
1
  module HydraHelper
3
- include Hydra::SubmissionWorkflow
4
-
5
- # collection of stylesheet links to be rendered in the <head>
6
- def stylesheet_links
7
- @stylesheet_links ||= []
8
- end
9
-
10
- # collection of javascript includes to be rendered in the <head>
11
- def javascript_includes
12
- @javascript_includes ||= []
13
- end
14
-
15
- def async_load_tag( url, tag )
16
- # Commenting out becasue async_load is provieded by a JS file that we're not currently loading.
17
- # javascript_tag do
18
- # "window._token='#{form_authenticity_token}'"
19
- # "async_load('#{url}', '\##{tag}');"
20
- # end
21
- end
22
-
23
- def link_to_multifacet( name, args={} )
24
- facet_params = {}
25
- options = {}
26
- args.each_pair do |k,v|
27
- if k == :options
28
- options = v
29
- else
30
- facet_params[:f] ||= {}
31
- facet_params[:f][k] ||= []
32
- v = v.instance_of?(Array) ? v.first : v
33
- facet_params[:f][k].push(v)
34
- end
35
- end
36
-
37
- link_to(name, catalog_index_path(facet_params), options).html_safe
38
- end
39
-
40
- def edit_and_browse_links
41
- result = ""
42
- if params[:action] == "edit"
43
- result << "<a href=\"#{catalog_path(@document[:id], :viewing_context=>"browse")}\" class=\"browse toggle\">Switch to browse view</a>"
44
- else
45
- result << "<a href=\"#{edit_catalog_path(@document[:id], :viewing_context=>"edit")}\" class=\"edit toggle\">Switch to edit view</a>"
46
- end
47
- return result.html_safe
48
- end
49
-
50
- def grouped_result_count(response, facet_name=nil, facet_value=nil)
51
- if facet_name && facet_value
52
- facet = response.facets.detect {|f| f.name == facet_name}
53
- facet_item = facet.items.detect {|i| i.value == facet_value} if facet
54
- count = facet_item ? facet_item.hits : 0
55
- else
56
- count = response.docs.total
57
- end
58
- pluralize(count, 'document')
59
- end
60
-
61
- def grouping_facet
62
- fields = Hash[sort_fields]
63
- case h(params[:sort])
64
- when fields['date -']
65
- 'year_facet'
66
- when fields['date +']
67
- 'year_facet'
68
- when fields['document type']
69
- 'medium_t'
70
- when fields['location']
71
- 'series_facet'
72
- else
73
- nil
74
- end
75
- end
76
-
77
- def document_fedora_show_html_title
78
- @document.datastreams["descMetadata"].title_values.first
79
- end
80
-
81
- # Returns the hits for facet_value within facet solr_fname within the solr_result.
82
- def facet_value_hits(solr_result, solr_fname, facet_value, default_response="1")
83
- item = solr_result.facets.detect {|f| f.name == solr_fname}.items.detect {|i| i.value == facet_value}
84
- if item
85
- return item.hits
86
- else
87
- return default_response
88
- end
89
- end
90
-
91
- def get_html_data_with_label(doc, label, field_string, opts={})
92
- if opts[:default] && !doc[field_string]
93
- doc[field_string] = opts[:default]
94
- end
95
-
96
- if doc[field_string]
97
- field = doc[field_string]
98
- text = "<dt>#{label}</dt><dd>"
99
- if field.is_a?(Array)
100
- field.each do |l|
101
- text += "#{CGI::unescapeHTML(l)}"
102
- if l != h(field.last)
103
- text += "<br/>"
104
- end
105
- end
106
- else
107
- text += CGI::unescapeHTML(field)
108
- end
109
- #Does the field have a vernacular equivalent?
110
- if doc["vern_#{field_string}"]
111
- vern_field = doc["vern_#{field_string}"]
112
- text += "<br/>"
113
- if vern_field.is_a?(Array)
114
- vern_field.each do |l|
115
- text += "#{CGI::unescapeHTML(l)}"
116
- if l != h(vern_field.last)
117
- text += "<br/>"
118
- end
119
- end
120
- else
121
- text += CGI::unescapeHTML(vern_field)
122
- end
123
- end
124
- text += "</dd>"
125
- text
126
- end
127
- end
128
-
129
- def get_textile_data_with_label(doc, label, field_string, opts={})
130
- if opts[:default] && !doc[field_string]
131
- doc[field_string] = opts[:default]
132
- end
133
-
134
- if doc[field_string]
135
- field = doc[field_string]
136
- text = "<dt>#{label}</dt><dd>"
137
- if field.is_a?(Array)
138
- field.each do |l|
139
- text += "#{RedCloth.new(l).to_html}"
140
- if l != h(field.last)
141
- text += "<br/>"
142
- end
143
- end
144
- else
145
- text += RedCloth.new(field).to_html
146
- end
147
- text += "</dd>"
148
- text
149
- end
150
- end
151
-
152
- def render_previous_workflow_steps
153
- "#{previous_show_partials(params[:wf_step]).map{|partial| render partial}}"
154
- end
155
-
156
- def render_submission_workflow_step
157
- if params.has_key?(:wf_step)
158
- render workflow_partial_for_step(params[:wf_step])
159
- else
160
- render workflow_partial_for_step(first_step_in_workflow)
161
- end
162
- end
163
-
164
-
165
- def render_all_workflow_steps
166
- "#{all_edit_partials.map{|partial| render partial}}"
167
- end
168
-
169
- def submit_name
170
- if session[:scripts]
171
- return "Save"
172
- elsif params[:new_asset]
173
- return "Continue"
174
- else
175
- return "Save and Continue"
176
- end
177
- end
178
-
179
- ### TODO this method is also in Hydra::Controller -- DRY it out
180
- def user_key
181
- current_user.send(Devise.authentication_keys.first)
182
- end
183
-
2
+ include Hydra::HydraHelperBehavior
184
3
  end
4
+
@@ -1,18 +1,4 @@
1
1
  module HydraUploaderHelper
2
-
3
- # Generate the appropriate url for posting uploads to
4
- # Uses the +container_id+ method to figure out what container uploads should go into
5
- def upload_url
6
- upload_url = asset_file_assets_path(:asset_id=>container_id)
7
- end
8
-
9
- # The id of the container that uploads should be posted into
10
- # If params[:container_id] is not set, it uses params[:id] (assumes that you're uploading items into the current object)
11
- def container_id
12
- if !params[:asset_id].nil?
13
- return params[:asset_id]
14
- else
15
- return params[:id]
16
- end
17
- end
2
+ include Hydra::HydraUploaderHelperBehavior
18
3
  end
4
+
@@ -1,15 +1,4 @@
1
1
  module InlineEditableMetadataHelper
2
-
3
- def inline_editable_text_field(object_name, method, options = {})
4
- end
5
-
6
- def inline_editable_text_area(object_name, method, options = {})
7
- end
8
-
9
- def inline_editable_select(object_name, method, options = {})
10
- end
11
-
12
- def inline_editable_checkbox(object_name, method, options = {})
13
- end
14
-
15
- end
2
+ include Hydra::InlineEditableMetadataHelperBehavior
3
+ end
4
+
@@ -1,91 +1,4 @@
1
- # Use this helper to declare which javascript should be loaded in which views
2
- # Internally, it relies on include_javascript_for_#{controller}_#{action} helper methods
3
- # These helper methods will usually append their includes to the controller's javascript_includes array
4
- #
5
- # @example Within your views (or in your controllers), call the helper like this
6
- # include_javascript_for "hydrangea_articles", "edit"
7
- #
8
- # To declare your own array of includes for a specific content type or action, define a helper method in your host application or plugin like this
9
- # @example Declaring the javascript includes for hydrangea_datasets show view while reusing the includes from catalog_edit
10
- # def include_javascript_for_hydrangea_datasets_show
11
- # include_javascript_for_catalog_edit
12
- # javascript_includes << ['hydrangeaArticleBehaviors.js', {:plugin=>:hydrangea_articles}]
13
- # end
14
1
  module JavascriptIncludesHelper
15
-
16
- # Add the appropriate javascripts for the specified content type & action into the Controller's javascript_includes array
17
- # If you have defined custom javascript includes for that content_type & action, they will be used.
18
- # @param [String or Symbol] content_type
19
- # @param [String or Symbol] action
20
- # @example This will rely on the include_javascript_for_hydranea_articles_edit helper method if it's defined. Defaults to calling include_default_javascript("edit")
21
- # include_javascript_for "hydrangea_articles", "edit"
22
- def include_javascript_for(content_type, action, opts={})
23
- begin
24
- method_name = "include_javascript_for_#{content_type.to_s}_#{action.to_s}"
25
- logger.debug "attempting to include #{method_name}"
26
- self.send(method_name.to_sym)
27
- rescue
28
- logger.debug "... no specific includes defined for #{content_type.to_s}. Using defaults for #{action.to_s} views"
29
- include_default_javascript( action )
30
- end
31
- end
32
-
33
- # Add the default javascript to the controller's javascript_includes
34
- # Takes a method argument (ie. show or edit) to decide which defaults to use.
35
- # Currently configured to use the javascript includes for catalog show / edit.
36
- # @param [String or Symbol] method Currently only "show" and "edit" have defaults set
37
- def include_default_javascript(method)
38
- case method.to_s
39
- when "show"
40
- include_javascript_for_catalog_show
41
- when "edit"
42
- include_javascript_for_catalog_edit
43
- else
44
- logger.debug "No default javascript includes defined for #{method} views. Doing nothing."
45
- end
46
- end
47
-
48
- #
49
- # Helpers for Catalog Show & Edit Javascript Includes
50
- #
51
-
52
- # Adds the appropriate javascripts to javascript_includes for CatalogController show views
53
- # Override this if you want to change the set of javascript_includes for CatalogController show views
54
- def include_javascript_for_catalog_show
55
- javascript_includes << ['custom', {:plugin=>"hydra-head"}]
56
-
57
- # This file contains the page initialization scripts for catalog show views
58
- javascript_includes << ["catalog/show", {:plugin=>"hydra-head"}]
59
- end
60
-
61
- # Adds the appropriate javascripts to javascript_includes for CatalogController edit views
62
- # Override this if you want to change the set of javascript_includes for CatalogController edit views
63
- def include_javascript_for_catalog_edit
64
- # This _would_ include the fluid infusion javascripts, but we don't want them
65
- # javascript_includes << infusion_javascripts(:default_no_jquery, :extras=>[:inline_editor_integrations], :debug=>true, :render_html=>false)
66
-
67
- javascript_includes << ["jquery.jeditable.mini.js", {:plugin=>"hydra-head"}]
68
- javascript_includes << ["jquery.form.js", {:plugin=>"hydra-head"}]
69
- javascript_includes << ['custom', {:plugin=>"hydra-head"}]
70
-
71
- javascript_includes << ["jquery.hydraMetadata.js", {:plugin=>"hydra-head"}]
72
- javascript_includes << ["jquery.notice.js", {:plugin=>"hydra-head"}]
73
-
74
- javascript_includes << ["jquery.jeditable.mini.js", "date-picker/js/datepicker", "jquery.form.js", 'custom', "catalog/edit", "jquery.hydraMetadata.js", "jquery.notice.js", {:plugin=>"hydra-head"}]
75
- # For DatePicker
76
- javascript_includes << ["jquery.ui.widget.js","jquery.ui.datepicker.js", "mediashelf.datepicker.js", {:plugin=>"hydra-head" }]
77
-
78
- # For Fancybox
79
- javascript_includes << ["fancybox/jquery.fancybox-1.3.1.pack.js", {:plugin=>"hydra-head"}]
80
- stylesheet_links << ["/javascripts/fancybox/jquery.fancybox-1.3.1.css", {:plugin=>"hydra-head"}]
2
+ include Hydra::JavascriptIncludesHelperBehavior
3
+ end
81
4
 
82
- # For slider controls
83
- javascript_includes << ["select_to_ui_slider/selectToUISlider.jQuery.js", {:plugin=>"hydra-head"}]
84
- stylesheet_links << ["/javascripts/select_to_ui_slider/css/ui.slider.extras.css", {:plugin=>"hydra-head"}]
85
- stylesheet_links << ["slider", {:plugin=>"hydra-head"}]
86
-
87
- # This file contains the page initialization scripts for catalog edit views
88
- javascript_includes << ["catalog/edit", {:plugin=>"hydra-head"}]
89
- end
90
-
91
- end
@@ -1,44 +1,4 @@
1
1
  module PersonalizationHelper
2
-
3
- DEFAULT_USER_ATTRIBUTES = ['full_name', 'affiliation', 'photo']
4
-
5
- # Helper methods to retrieve information from the user attributes
6
- #
7
- # == get_full_name_from_login
8
- #
9
- # Given a login, returns a string concatenating first_name and last_name
10
- #
11
- # == get_affiliation_from_login
12
- #
13
- # Given a login, returns a string
14
- #
15
- # == get_photo_from_login
16
- #
17
- # Given a login, returns a string representing either a path or a url pointing to an image file
18
- DEFAULT_USER_ATTRIBUTES.each do |m|
19
- class_eval <<-EOC
20
- def #{m}_from_login login
21
- get_user_attribute(login, '#{m}')
22
- end
23
- EOC
24
- end
25
-
26
- # Creates an image tag with the user#photo attribute as the source
27
- # @param [string] login the login of the user
28
- # @return an html image tag or an empty string
29
- def user_photo_tag login
30
- path = photo_from_login login
31
- path == "" ? "" : image_tag(path)
32
- end
33
-
34
- private
35
-
36
- # Retrieves an attribute from the user
37
- # @param [string] login the login of the user
38
- # @param [string] the name of the attribute: out of the box values are first_name, last_name, full_name, affiliation, and photo
39
- def get_user_attribute login, attribute
40
- user = User.find_by_login(login)
41
- user.nil? ? "" : user.send(attribute.to_sym)
42
- end
43
-
2
+ include Hydra::PersonalizationHelperBehavior
44
3
  end
4
+
@@ -1,32 +1,4 @@
1
1
  module ReleaseProcessHelper
2
-
3
- def display_release_status_notice(document)
4
- readiness = document.test_release_readiness
5
- if readiness == true
6
- flash[:notice] ||= []
7
- if document.submitted_for_release?
8
- flash[:notice] << "This item has been released for library circulation."
9
- else
10
- flash[:notice] << "This item is ready to be released for library circulation."
11
- end
12
- else
13
- flash[:error] ||= []
14
- flash[:error] = flash[:error] | readiness[:failures]
15
- end
16
- end
2
+ include Hydra::ReleaseProcessHelperBehavior
3
+ end
17
4
 
18
- def check_embargo_date_format
19
- if params.keys.include? [:embargo, :embargo_release_date]
20
- em_date = params[[:embargo, :embargo_release_date]]["0"]
21
- unless em_date.blank?
22
- begin
23
- !Date.parse(em_date)
24
- rescue
25
- params[[:embargo,:embargo_release_date]]["0"] = ""
26
- raise "Unacceptable date format"
27
- end
28
- end
29
- end
30
- end
31
-
32
- end
@@ -0,0 +1,612 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # -*- coding: utf-8 -*-
3
+ # Copied from blacklight 3.0. Do not change this file inside hydra. Override in app/helpers/hydra/blacklight_helper_behavior.rb
4
+ # When Blacklight 3.2 comes out, remove this file.
5
+ #
6
+ # Methods added to this helper will be available to all templates in the hosting application
7
+ #
8
+ module Blacklight::BlacklightHelperBehavior
9
+ include HashAsHiddenFields
10
+ include RenderConstraintsHelper
11
+
12
+
13
+ def application_name
14
+ 'Blacklight'
15
+ end
16
+
17
+ ##
18
+ # This method should be included in any Blacklight layout, including
19
+ # custom ones. It will output results of #render_js_includes,
20
+ # #render_stylesheet_includes, and all the content of
21
+ # current_controller#extra_head_content.
22
+ #
23
+ # Uses controller methods #extra_head_content, #javascript_includes,
24
+ # and #stylesheet_links to find content. Tolerates it if those
25
+ # methods don't exist, silently skipping.
26
+ #
27
+ # By a layout outputting this in html HEAD, it provides an easy way for
28
+ # local config or extra plugins to add HEAD content.
29
+ #
30
+ # Add your own css or remove the defaults by simply editing
31
+ # controller.stylesheet_links, controller.javascript_includes,
32
+ # or controller.extra_head_content.
33
+ #
34
+ #
35
+ #
36
+ # in an initializer or other startup file (plugin init.rb?):
37
+ #
38
+ # == Apply to all actions in all controllers:
39
+ #
40
+ # ApplicationController.before_filter do |controller|
41
+ # # remove default jquery-ui theme.
42
+ # controller.stylesheet_links.each do |args|
43
+ # args.delete_if {|a| a =~ /^|\/jquery-ui-[\d.]+\.custom\.css$/ }
44
+ # end
45
+ #
46
+ # # add in a different jquery-ui theme, or any other css or what have you
47
+ # controller.stylesheet_links << 'my_css.css'
48
+ #
49
+ # controller.javascript_includes << "my_local_behaviors.js"
50
+ #
51
+ # controller.extra_head_content << '<link rel="something" href="something">'
52
+ # end
53
+ #
54
+ # == Apply to a particular action in a particular controller:
55
+ #
56
+ # CatalogController.before_filter :only => :show |controller|
57
+ # controller.extra_head_content << '<link rel="something" href="something">'
58
+ # end
59
+ #
60
+ # == Or in a view file that wants to add certain header content? no problem:
61
+ #
62
+ # <% stylesheet_links << "mystylesheet.css" %>
63
+ # <% javascript_includes << "my_js.js" %>
64
+ # <% extra_head_content << capture do %>
65
+ # <%= tag :link, { :href => some_method_for_something, :rel => "alternate" } %>
66
+ # <% end %>
67
+ #
68
+ # == Full power of javascript_include_tag and stylesheet_link_tag
69
+ # Note that the elements added to stylesheet_links and javascript_links
70
+ # are arguments to Rails javascript_include_tag and stylesheet_link_tag
71
+ # respectively, you can pass complex arguments. eg:
72
+ #
73
+ # stylesheet_links << ["stylesheet1.css", "stylesheet2.css", {:cache => "mykey"}]
74
+ # javascript_includes << ["myjavascript.js", {:plugin => :myplugin} ]
75
+ def render_head_content
76
+ render_stylesheet_includes +
77
+ render_js_includes +
78
+ render_extra_head_content
79
+ end
80
+
81
+ ##
82
+ # Assumes controller has a #stylesheet_link_tag method, array with
83
+ # each element being a set of arguments for stylesheet_link_tag
84
+ # See #render_head_content for instructions on local code or plugins
85
+ # adding stylesheets.
86
+ def render_stylesheet_includes
87
+ return "".html_safe unless respond_to?(:stylesheet_links)
88
+
89
+ stylesheet_links.uniq.collect do |args|
90
+ stylesheet_link_tag(*args)
91
+ end.join("\n").html_safe
92
+ end
93
+
94
+
95
+ ##
96
+ # Assumes controller has a #js_includes method, array with each
97
+ # element being a set of arguments for javsascript_include_tag.
98
+ # See #render_head_content for instructions on local code or plugins
99
+ # adding js files.
100
+ def render_js_includes
101
+ return "".html_safe unless respond_to?(:javascript_includes)
102
+
103
+ javascript_includes.uniq.collect do |args|
104
+ javascript_include_tag(*args)
105
+ end.join("\n").html_safe
106
+ end
107
+
108
+ ##
109
+ # Assumes controller has a #extra_head_content method
110
+ #
111
+ def render_extra_head_content
112
+ return "".html_safe unless respond_to?(:extra_head_content)
113
+
114
+ extra_head_content.join("\n").html_safe
115
+ end
116
+
117
+ # Create <link rel="alternate"> links from a documents dynamically
118
+ # provided export formats. Currently not used by standard BL layouts,
119
+ # but available for your custom layouts to provide link rel alternates.
120
+ #
121
+ # Returns empty string if no links available.
122
+ #
123
+ # :unique => true, will ensure only one link is output for every
124
+ # content type, as required eg in atom. Which one 'wins' is arbitrary.
125
+ # :exclude => array of format shortnames, formats to not include at all.
126
+ def render_link_rel_alternates(document=@document, options = {})
127
+ options = {:unique => false, :exclude => []}.merge(options)
128
+
129
+ return nil if document.nil?
130
+
131
+ seen = Set.new
132
+
133
+ html = ""
134
+ document.export_formats.each_pair do |format, spec|
135
+ unless( options[:exclude].include?(format) ||
136
+ (options[:unique] && seen.include?(spec[:content_type]))
137
+ )
138
+ html << tag(:link, {:rel=>"alternate", :title=>format, :type => spec[:content_type], :href=> catalog_url(document.id, format)}) << "\n"
139
+
140
+ seen.add(spec[:content_type]) if options[:unique]
141
+ end
142
+ end
143
+ return html.html_safe
144
+ end
145
+
146
+ def render_opensearch_response_metadata
147
+ render :partial => 'catalog/opensearch_response_metadata'
148
+ end
149
+
150
+ def render_body_class
151
+ extra_body_classes.join " "
152
+ end
153
+
154
+ # collection of items to be rendered in the @sidebar
155
+ def sidebar_items
156
+ @sidebar_items ||= []
157
+ end
158
+
159
+ def extra_body_classes
160
+ @extra_body_classes ||= ['blacklight-' + controller.controller_name, 'blacklight-' + [controller.controller_name, controller.action_name].join('-')]
161
+ end
162
+
163
+ #
164
+ # Blacklight.config based helpers ->
165
+ #
166
+
167
+ # used in the catalog/_facets partial
168
+ def facet_field_labels
169
+ Blacklight.config[:facet][:labels]
170
+ end
171
+
172
+ # used in the catalog/_facets partial
173
+ def facet_field_names
174
+ Blacklight.config[:facet][:field_names]
175
+ end
176
+
177
+ # used in the catalog/_facets partial and elsewhere
178
+ # Renders a single section for facet limit with a specified
179
+ # solr field used for faceting. Can be over-ridden for custom
180
+ # display on a per-facet basis.
181
+ def render_facet_limit(solr_field)
182
+ render( :partial => "catalog/facet_limit", :locals => {:solr_field =>solr_field })
183
+ end
184
+
185
+ def render_document_list_partial options={}
186
+ render :partial=>'catalog/document_list'
187
+ end
188
+
189
+ # Save function area for search results 'index' view, normally
190
+ # renders next to title. Includes just 'Folder' by default.
191
+ def render_index_doc_actions(document, options={})
192
+ content_tag("div", :class=>"documentFunctions") do
193
+ raw("#{render(:partial => 'bookmark_control', :locals => {:document=> document}.merge(options))}
194
+ #{render(:partial => 'folder_control', :locals => {:document=> document}.merge(options))}")
195
+ end
196
+ end
197
+
198
+ # Save function area for item detail 'show' view, normally
199
+ # renders next to title. By default includes 'Folder' and 'Bookmarks'
200
+ def render_show_doc_actions(document=@document, options={})
201
+ content_tag("div", :class=>"documentFunctions") do
202
+ raw("#{render(:partial => 'bookmark_control', :locals => {:document=> document}.merge(options))}
203
+ #{render(:partial => 'folder_control', :locals => {:document=> document}.merge(options))}")
204
+ end
205
+ end
206
+
207
+ # used in the catalog/_index_partials/_default view
208
+ def index_field_names
209
+ Blacklight.config[:index_fields][:field_names]
210
+ end
211
+
212
+ # used in the _index_partials/_default view
213
+ def index_field_labels
214
+ Blacklight.config[:index_fields][:labels]
215
+ end
216
+
217
+ def spell_check_max
218
+ Blacklight.config[:spell_max] || 0
219
+ end
220
+
221
+ def render_index_field_label args
222
+ field = args[:field]
223
+ html_escape index_field_labels[field]
224
+ end
225
+
226
+ def render_index_field_value args
227
+ value = args[:value]
228
+ value ||= args[:document].get(args[:field], :sep => nil) if args[:document] and args[:field]
229
+ render_field_value value
230
+ end
231
+
232
+ # Used in the show view for displaying the main solr document heading
233
+ def document_heading
234
+ @document[Blacklight.config[:show][:heading]] || @document.id
235
+ end
236
+ def render_document_heading
237
+ content_tag(:h1, document_heading)
238
+ end
239
+
240
+ # Used in the show view for setting the main html document title
241
+ def document_show_html_title
242
+ @document[Blacklight.config[:show][:html_title]]
243
+ end
244
+
245
+ # Used in citation view for displaying the title
246
+ def citation_title(document)
247
+ document[Blacklight.config[:show][:html_title]]
248
+ end
249
+
250
+ # Used in the document_list partial (search view) for building a select element
251
+ def sort_fields
252
+ Blacklight.config[:sort_fields]
253
+ end
254
+
255
+ # Used in the document list partial (search view) for creating a link to the document show action
256
+ def document_show_link_field
257
+ Blacklight.config[:index][:show_link].to_sym
258
+ end
259
+
260
+ # Used in the search form partial for building a select tag
261
+ def search_fields
262
+ Blacklight.search_field_options_for_select
263
+ end
264
+
265
+ # used in the catalog/_show/_default partial
266
+ def document_show_fields
267
+ Blacklight.config[:show_fields][:field_names]
268
+ end
269
+
270
+ # used in the catalog/_show/_default partial
271
+ def document_show_field_labels
272
+ Blacklight.config[:show_fields][:labels]
273
+ end
274
+
275
+ def render_document_show_field_label args
276
+ field = args[:field]
277
+ html_escape document_show_field_labels[field]
278
+ end
279
+
280
+ def render_document_show_field_value args
281
+ value = args[:value]
282
+ value ||= args[:document].get(args[:field], :sep => nil) if args[:document] and args[:field]
283
+ render_field_value value
284
+ end
285
+
286
+ def render_field_value value=nil
287
+ value = [value] unless value.is_a? Array
288
+ value = value.collect { |x| x.respond_to?(:force_encoding) ? x.force_encoding("UTF-8") : x}
289
+ return value.map { |v| html_escape v }.join(field_value_separator).html_safe
290
+ end
291
+
292
+ def field_value_separator
293
+ ', '
294
+ end
295
+
296
+ # Return a normalized partial name that can be used to contruct view partial path
297
+ def document_partial_name(document)
298
+ # .to_s is necessary otherwise the default return value is not always a string
299
+ # using "_" as sep. to more closely follow the views file naming conventions
300
+ # parameterize uses "-" as the default sep. which throws errors
301
+ display_type = document[Blacklight.config[:show][:display_type]]
302
+
303
+ return 'default' unless display_type
304
+ display_type = display_type.join(" ") if display_type.respond_to?(:join)
305
+
306
+ "#{display_type.gsub("-"," ")}".parameterize("_").to_s
307
+ end
308
+
309
+ # given a doc and action_name, this method attempts to render a partial template
310
+ # based on the value of doc[:format]
311
+ # if this value is blank (nil/empty) the "default" is used
312
+ # if the partial is not found, the "default" partial is rendered instead
313
+ def render_document_partial(doc, action_name)
314
+ format = document_partial_name(doc)
315
+ begin
316
+ render :partial=>"catalog/_#{action_name}_partials/#{format}", :locals=>{:document=>doc}
317
+ rescue ActionView::MissingTemplate
318
+ render :partial=>"catalog/_#{action_name}_partials/default", :locals=>{:document=>doc}
319
+ end
320
+ end
321
+
322
+ # Search History and Saved Searches display
323
+ def link_to_previous_search(params)
324
+ link_to(raw(render_search_to_s(params)), catalog_index_path(params)).html_safe
325
+ end
326
+
327
+ #
328
+ # facet param helpers ->
329
+ #
330
+
331
+ # Standard display of a facet value in a list. Used in both _facets sidebar
332
+ # partial and catalog/facet expanded list. Will output facet value name as
333
+ # a link to add that to your restrictions, with count in parens.
334
+ # first arg item is a facet value item from rsolr-ext.
335
+ # options consist of:
336
+ # :suppress_link => true # do not make it a link, used for an already selected value for instance
337
+ def render_facet_value(facet_solr_field, item, options ={})
338
+ (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
339
+ end
340
+
341
+ # Standard display of a SELECTED facet value, no link, special span
342
+ # with class, and 'remove' button.
343
+ def render_selected_facet_value(facet_solr_field, item)
344
+ content_tag(:span, render_facet_value(facet_solr_field, item, :suppress_link => true), :class => "selected label") +
345
+ link_to("[remove]", remove_facet_params(facet_solr_field, item.value, params), :class=>"remove")
346
+ end
347
+
348
+ # Renders a count value for facet limits. Can be over-ridden locally
349
+ # to change style, for instance not use parens. And can be called
350
+ # by plugins to get consistent display.
351
+ def render_facet_count(num)
352
+ content_tag("span", "(" + format_num(num) + ")", :class => "count")
353
+ end
354
+
355
+ # adds the value and/or field to params[:f]
356
+ # Does NOT remove request keys and otherwise ensure that the hash
357
+ # is suitable for a redirect. See
358
+ # add_facet_params_and_redirect
359
+ def add_facet_params(field, value)
360
+ p = params.dup
361
+ p[:f] = (p[:f] || {}).dup # the command above is not deep in rails3, !@#$!@#$
362
+ p[:f][field] = (p[:f][field] || []).dup
363
+ p[:f][field].push(value)
364
+ p
365
+ end
366
+
367
+ # Used in catalog/facet action, facets.rb view, for a click
368
+ # on a facet value. Add on the facet params to existing
369
+ # search constraints. Remove any paginator-specific request
370
+ # params, or other request params that should be removed
371
+ # for a 'fresh' display.
372
+ # Change the action to 'index' to send them back to
373
+ # catalog/index with their new facet choice.
374
+ def add_facet_params_and_redirect(field, value)
375
+ new_params = add_facet_params(field, value)
376
+
377
+ # Delete page, if needed.
378
+ new_params.delete(:page)
379
+
380
+ # Delete any request params from facet-specific action, needed
381
+ # to redir to index action properly.
382
+ Blacklight::Solr::FacetPaginator.request_keys.values.each do |paginator_key|
383
+ new_params.delete(paginator_key)
384
+ end
385
+ new_params.delete(:id)
386
+
387
+ # Force action to be index.
388
+ new_params[:action] = "index"
389
+ new_params
390
+ end
391
+ # copies the current params (or whatever is passed in as the 3rd arg)
392
+ # removes the field value from params[:f]
393
+ # removes the field if there are no more values in params[:f][field]
394
+ # removes additional params (page, id, etc..)
395
+ def remove_facet_params(field, value, source_params=params)
396
+ p = source_params.dup
397
+ # need to dup the facet values too,
398
+ # if the values aren't dup'd, then the values
399
+ # from the session will get remove in the show view...
400
+ p[:f] = p[:f].dup
401
+ p[:f][field] = p[:f][field].nil? ? [] : p[:f][field].dup
402
+ p.delete :page
403
+ p.delete :id
404
+ p.delete :counter
405
+ p.delete :commit
406
+ #return p unless p[field]
407
+ p[:f][field] = p[:f][field] - [value]
408
+ p[:f].delete(field) if p[:f][field].size == 0
409
+ p
410
+ end
411
+
412
+ # true or false, depending on whether the field and value is in params[:f]
413
+ def facet_in_params?(field, value)
414
+ params[:f] and params[:f][field] and params[:f][field].include?(value)
415
+ end
416
+
417
+ #
418
+ # shortcut for built-in Rails helper, "number_with_delimiter"
419
+ #
420
+ def format_num(num); number_with_delimiter(num) end
421
+
422
+ #
423
+ # link based helpers ->
424
+ #
425
+
426
+ # create link to query (e.g. spelling suggestion)
427
+ def link_to_query(query)
428
+ p = params.dup
429
+ p.delete :page
430
+ p.delete :action
431
+ p[:q]=query
432
+ link_url = catalog_index_path(p)
433
+ link_to(query, link_url)
434
+ end
435
+
436
+ def render_document_index_label doc, opts
437
+ label = nil
438
+ label ||= doc.get(opts[:label]) if opts[:label].instance_of? Symbol
439
+ label ||= opts[:label].call(doc, opts) if opts[:label].instance_of? Proc
440
+ label ||= opts[:label] if opts[:label].is_a? String
441
+ label ||= doc.id
442
+ end
443
+
444
+ # link_to_document(doc, :label=>'VIEW', :counter => 3)
445
+ # Use the catalog_path RESTful route to create a link to the show page for a specific item.
446
+ # catalog_path accepts a HashWithIndifferentAccess object. The solr query params are stored in the session,
447
+ # so we only need the +counter+ param here. We also need to know if we are viewing to document as part of search results.
448
+ def link_to_document(doc, opts={:label=>Blacklight.config[:index][:show_link].to_sym, :counter => nil, :results_view => true})
449
+ label = render_document_index_label doc, opts
450
+ link_to_with_data(label, catalog_path(doc.id), {:method => :put, :class => label.parameterize, :data => opts}).html_safe
451
+ end
452
+
453
+ # link_back_to_catalog(:label=>'Back to Search')
454
+ # Create a link back to the index screen, keeping the user's facet, query and paging choices intact by using session.
455
+ def link_back_to_catalog(opts={:label=>'Back to Search'})
456
+ query_params = session[:search] ? session[:search].dup : {}
457
+ query_params.delete :counter
458
+ query_params.delete :total
459
+ link_url = catalog_index_path + "?" + query_params.to_query
460
+ link_to opts[:label], link_url
461
+ end
462
+
463
+ # Create form input type=hidden fields representing the entire search context,
464
+ # for inclusion in a form meant to change some aspect of it, like
465
+ # re-sort or change records per page. Can pass in params hash
466
+ # as :params => hash, otherwise defaults to #params. Can pass
467
+ # in certain top-level params keys to _omit_, defaults to :page
468
+ def search_as_hidden_fields(options={})
469
+
470
+ options = {:params => params, :omit_keys => [:page]}.merge(options)
471
+ my_params = options[:params].dup
472
+ options[:omit_keys].each {|omit_key| my_params.delete(omit_key)}
473
+ # removing action and controller from duplicate params so that we don't get hidden fields for them.
474
+ my_params.delete(:action)
475
+ my_params.delete(:controller)
476
+ # commit is just an artifact of submit button, we don't need it, and
477
+ # don't want it to pile up with another every time we press submit again!
478
+ my_params.delete(:commit)
479
+ # hash_as_hidden_fields in hash_as_hidden_fields.rb
480
+ return hash_as_hidden_fields(my_params)
481
+ end
482
+
483
+
484
+
485
+ def link_to_previous_document(previous_document)
486
+ return if previous_document == nil
487
+ link_to_document previous_document, :label=>'« Previous', :counter => session[:search][:counter].to_i - 1
488
+ end
489
+
490
+ def link_to_next_document(next_document)
491
+ return if next_document == nil
492
+ link_to_document next_document, :label=>'Next »', :counter => session[:search][:counter].to_i + 1
493
+ end
494
+
495
+ # Use case, you want to render an html partial from an XML (say, atom)
496
+ # template. Rails API kind of lets us down, we need to hack Rails internals
497
+ # a bit. code taken from:
498
+ # http://stackoverflow.com/questions/339130/how-do-i-render-a-partial-of-a-different-format-in-rails
499
+ def with_format(format, &block)
500
+ old_format = @template_format
501
+ @template_format = format
502
+ result = block.call
503
+ @template_format = old_format
504
+ return result
505
+ end
506
+
507
+
508
+ # This is an updated +link_to+ that allows you to pass a +data+ hash along with the +html_options+
509
+ # which are then written to the generated form for non-GET requests. The key is the form element name
510
+ # and the value is the value:
511
+ #
512
+ # link_to_with_data('Name', some_path(some_id), :method => :post, :html)
513
+ def link_to_with_data(*args, &block)
514
+ if block_given?
515
+ options = args.first || {}
516
+ html_options = args.second
517
+ concat(link_to(capture(&block), options, html_options))
518
+ else
519
+ name = args.first
520
+ options = args.second || {}
521
+ html_options = args.third
522
+
523
+ url = url_for(options)
524
+
525
+ if html_options
526
+ html_options = html_options.stringify_keys
527
+ href = html_options['href']
528
+ convert_options_to_javascript_with_data!(html_options, url)
529
+ tag_options = tag_options(html_options)
530
+ else
531
+ tag_options = nil
532
+ end
533
+
534
+ href_attr = "href=\"#{url}\"" unless href
535
+ "<a #{href_attr}#{tag_options}>#{h(name) || h(url)}</a>".html_safe
536
+ end
537
+ end
538
+
539
+ # This is derived from +convert_options_to_javascript+ from module +UrlHelper+ in +url_helper.rb+
540
+ def convert_options_to_javascript_with_data!(html_options, url = '')
541
+ confirm, popup = html_options.delete("confirm"), html_options.delete("popup")
542
+
543
+ method, href = html_options.delete("method"), html_options['href']
544
+ data = html_options.delete("data")
545
+ data = data.stringify_keys if data
546
+
547
+ html_options["onclick"] = case
548
+ when method
549
+ "#{method_javascript_function_with_data(method, url, href, data)}return false;"
550
+ else
551
+ html_options["onclick"]
552
+ end
553
+ end
554
+
555
+ # This is derived from +method_javascript_function+ from module +UrlHelper+ in +url_helper.rb+
556
+ def method_javascript_function_with_data(method, url = '', href = nil, data=nil)
557
+ action = (href && url.size > 0) ? "'#{url}'" : 'this.href'
558
+ submit_function =
559
+ "var f = document.createElement('form'); f.style.display = 'none'; " +
560
+ "this.parentNode.appendChild(f); f.method = 'POST'; f.action = #{action};"+
561
+ "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
562
+ if data
563
+ data.each_pair do |key, value|
564
+ submit_function << "var d = document.createElement('input'); d.setAttribute('type', 'hidden'); "
565
+ submit_function << "d.setAttribute('name', '#{key}'); d.setAttribute('value', '#{escape_javascript(value.to_s)}'); f.appendChild(d);"
566
+ end
567
+ end
568
+ unless method == :post
569
+ submit_function << "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); "
570
+ submit_function << "m.setAttribute('name', '_method'); m.setAttribute('value', '#{method}'); f.appendChild(m);"
571
+ end
572
+
573
+ if protect_against_forgery?
574
+ submit_function << "var s = document.createElement('input'); s.setAttribute('type', 'hidden'); "
575
+ submit_function << "s.setAttribute('name', '#{request_forgery_protection_token}'); s.setAttribute('value', '#{escape_javascript form_authenticity_token}'); f.appendChild(s);"
576
+ end
577
+ submit_function << "f.submit();"
578
+ end
579
+
580
+ # determines if the given document id is in the folder
581
+ def item_in_folder?(doc_id)
582
+ session[:folder_document_ids] && session[:folder_document_ids].include?(doc_id) ? true : false
583
+ end
584
+
585
+ # puts together a collection of documents into one refworks export string
586
+ def render_refworks_texts(documents)
587
+ val = ''
588
+ documents.each do |doc|
589
+ if doc.respond_to?(:to_marc)
590
+ val += doc.export_as_refworks_marc_txt + "\n"
591
+ end
592
+ end
593
+ val
594
+ end
595
+
596
+ # puts together a collection of documents into one endnote export string
597
+ def render_endnote_texts(documents)
598
+ val = ''
599
+ documents.each do |doc|
600
+ if doc.respond_to?(:to_marc)
601
+ val += doc.export_as_endnote + "\n"
602
+ end
603
+ end
604
+ val
605
+ end
606
+
607
+
608
+ def render_document_unapi_microformat(document, options={})
609
+ render(:partial=>'catalog/unapi_microformat', :locals => {:document=> document}.merge(options))
610
+ end
611
+
612
+ end