blacklight 3.0.0pre4 → 3.0.0pre6

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 (51) hide show
  1. data/VERSION +1 -1
  2. data/app/controllers/bookmarks_controller.rb +1 -1
  3. data/app/controllers/folder_controller.rb +1 -1
  4. data/app/helpers/blacklight_helper.rb +5 -4
  5. data/app/helpers/catalog_helper.rb +22 -18
  6. data/app/views/bookmarks/index.html.erb +1 -1
  7. data/app/views/catalog/_citation.html.erb +6 -1
  8. data/app/views/catalog/_results_pagination.html.erb +2 -7
  9. data/app/views/catalog/_sms_form.html.erb +1 -1
  10. data/app/views/catalog/index.html.erb +1 -1
  11. data/app/views/kaminari/blacklight/_first_page.html.erb +11 -0
  12. data/app/views/kaminari/blacklight/_gap.html.erb +8 -0
  13. data/app/views/kaminari/blacklight/_last_page.html.erb +11 -0
  14. data/app/views/kaminari/blacklight/_next_page.html.erb +11 -0
  15. data/app/views/kaminari/blacklight/_page.html.erb +12 -0
  16. data/app/views/kaminari/blacklight/_paginator.html.erb +23 -0
  17. data/app/views/kaminari/blacklight/_prev_page.html.erb +11 -0
  18. data/app/views/record_mailer/email_record.text.erb +5 -0
  19. data/app/views/record_mailer/sms_record.text.erb +4 -0
  20. data/blacklight.gemspec +4 -5
  21. data/config/locales/kaminari.yml +10 -0
  22. data/config/routes.rb +8 -46
  23. data/features/default_setup.feature +2 -1
  24. data/lib/blacklight.rb +5 -7
  25. data/lib/blacklight/catalog.rb +7 -24
  26. data/lib/blacklight/controller.rb +7 -1
  27. data/lib/blacklight/engine.rb +0 -11
  28. data/lib/blacklight/routes.rb +91 -0
  29. data/lib/blacklight/solr/document.rb +16 -1
  30. data/lib/blacklight/solr/document/marc_export.rb +174 -4
  31. data/lib/blacklight/solr_helper.rb +7 -2
  32. data/lib/generators/blacklight/blacklight_generator.rb +6 -0
  33. data/lib/generators/blacklight/templates/public/stylesheets/blacklight/blacklight.css +3 -3
  34. data/lib/railties/all_tests.rake +18 -6
  35. data/lib/railties/blacklight.rake +3 -2
  36. data/lib/railties/blacklight_cucumber.rake +1 -1
  37. data/lib/railties/blacklight_rspec.rake +1 -1
  38. data/lib/railties/solr_marc.rake +1 -1
  39. data/test_support/spec/controllers/application_controller_spec.rb +2 -2
  40. data/test_support/spec/controllers/catalog_controller_spec.rb +0 -24
  41. data/test_support/spec/helpers/blacklight_helper_spec.rb +4 -4
  42. data/test_support/spec/helpers/catalog_helper_spec.rb +22 -18
  43. data/test_support/spec/helpers/solr_helper_spec.rb +22 -5
  44. data/test_support/spec/lib/blacklight_solr_document_spec.rb +16 -9
  45. data/test_support/spec/lib/marc_export_spec.rb +308 -8
  46. data/test_support/spec/lib/tasks/solr_marc_task_spec.rb +1 -1
  47. data/test_support/spec/views/catalog/index.atom.builder_spec.rb +1 -1
  48. data/test_support/spec/views/catalog/show.html.erb_spec.rb +3 -3
  49. metadata +26 -18
  50. data/app/views/record_mailer/email_record.erb +0 -6
  51. data/app/views/record_mailer/sms_record.erb +0 -4
@@ -1,11 +1,10 @@
1
1
  module Blacklight::Catalog
2
2
  extend ActiveSupport::Concern
3
-
3
+ include Blacklight::SolrHelper
4
4
 
5
5
  # The following code is executed when someone includes blacklight::catalog in their
6
6
  # own controller.
7
7
  included do
8
- include Blacklight::SolrHelper
9
8
  before_filter :search_session, :history_session
10
9
  before_filter :delete_or_assign_search_session_params, :only => :index
11
10
  after_filter :set_additional_search_session_values, :only=>:index
@@ -92,22 +91,6 @@ module Blacklight::Catalog
92
91
  @pagination = get_facet_pagination(params[:id], params)
93
92
  end
94
93
 
95
- # single document image resource
96
- def image
97
- end
98
-
99
- # single document availability status (true/false)
100
- def status
101
- end
102
-
103
- # single document availability info
104
- def availability
105
- end
106
-
107
- # collection/search UI via Google maps
108
- def map
109
- end
110
-
111
94
  # method to serve up XML OpenSearch description and JSON autocomplete response
112
95
  def opensearch
113
96
  respond_to do |format|
@@ -122,11 +105,11 @@ module Blacklight::Catalog
122
105
 
123
106
  # citation action
124
107
  def citation
125
- @response, @documents = get_solr_response_for_field_values("id",params[:id])
108
+ @response, @documents = get_solr_response_for_field_values(SolrDocument.unique_key,params[:id])
126
109
  end
127
110
  # grabs a bunch of documents to export to endnote
128
111
  def endnote
129
- @response, @documents = get_solr_response_for_field_values("id",params[:id])
112
+ @response, @documents = get_solr_response_for_field_values(SolrDocument.unique_key,params[:id])
130
113
  respond_to do |format|
131
114
  format.endnote
132
115
  end
@@ -134,14 +117,14 @@ module Blacklight::Catalog
134
117
 
135
118
  # Email Action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
136
119
  def email
137
- @response, @documents = get_solr_response_for_field_values("id",params[:id])
120
+ @response, @documents = get_solr_response_for_field_values(SolrDocument.unique_key,params[:id])
138
121
  if request.post?
139
122
  if params[:to]
140
123
  from = request.host # host w/o port for From address (from address cannot have port#)
141
124
  url_gen_params = {:host => request.host_with_port, :protocol => request.protocol}
142
125
 
143
126
  if params[:to].match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
144
- email = RecordMailer.create_email_record(@documents, {:to => params[:to], :message => params[:message]}, from, url_gen_params)
127
+ email = RecordMailer.email_record(@documents, {:to => params[:to], :message => params[:message]}, from, url_gen_params)
145
128
  else
146
129
  flash[:error] = "You must enter a valid email address"
147
130
  end
@@ -155,7 +138,7 @@ module Blacklight::Catalog
155
138
 
156
139
  # SMS action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
157
140
  def sms
158
- @response, @documents = get_solr_response_for_field_values("id",params[:id])
141
+ @response, @documents = get_solr_response_for_field_values(SolrDocument.unique_key,params[:id])
159
142
  if request.post?
160
143
  from = request.host # host w/o port for From address (from address cannot have port#)
161
144
  url_gen_params = {:host => request.host_with_port, :protocol => request.protocol}
@@ -166,7 +149,7 @@ module Blacklight::Catalog
166
149
  if phone_num.length != 10
167
150
  flash[:error] = "You must enter a valid 10 digit phone number"
168
151
  else
169
- email = RecordMailer.create_sms_record(@documents, {:to => phone_num, :carrier => params[:carrier]}, from, url_gen_params)
152
+ email = RecordMailer.sms_record(@documents, {:to => phone_num, :carrier => params[:carrier]}, from, url_gen_params)
170
153
  end
171
154
  email.deliver unless flash[:error]
172
155
  redirect_to :back
@@ -86,7 +86,13 @@ module Blacklight::Controller
86
86
  # don't use a layout, otherwise use the "application.html.erb" layout
87
87
  #
88
88
  def choose_layout
89
- 'blacklight' unless request.xml_http_request? || ! params[:no_layout].blank?
89
+ layout_name unless request.xml_http_request? || ! params[:no_layout].blank?
90
+ end
91
+
92
+ #over-ride this one locally to change what layout BL controllers use, usually
93
+ #by defining it in your own application_controller.rb
94
+ def layout_name
95
+ 'blacklight'
90
96
  end
91
97
 
92
98
  def current_user_session
@@ -11,17 +11,6 @@ module Blackight
11
11
  ActionView::Base.send :include, BlacklightHelper
12
12
  end
13
13
 
14
- # Go ahead and innitialize Blacklight at the very end of the rails
15
- # innitilization process.
16
- # See: http://www.cowboycoded.com/2010/08/02/hooking-in-your-rails-3-engine-or-railtie-initializer-in-the-right-place/
17
- initializer 'blacklight.init', :after=> :disable_dependency_loading do |app|
18
- # Check for a blacklight_install envrionment variable - if set then blacklight
19
- # is actively being installed and we should not attempt an init at this time.
20
- if defined?(Rails::Server)
21
- Blacklight.init
22
- end
23
- end
24
-
25
14
  # This makes our rake tasks visible.
26
15
  rake_tasks do
27
16
  Dir.chdir(File.expand_path(File.join(File.dirname(__FILE__), '..'))) do
@@ -0,0 +1,91 @@
1
+ module Blacklight
2
+ class Routes
3
+
4
+ def initialize(router, options)
5
+ @router = router
6
+ @options = options
7
+ end
8
+
9
+ def draw
10
+ route_sets.each do |r|
11
+ self.send(r)
12
+ end
13
+ end
14
+
15
+ protected
16
+
17
+ def add_routes &blk
18
+ @router.instance_exec(@options, &blk)
19
+ end
20
+
21
+ def route_sets
22
+ (@options[:only] || default_route_sets) - (@options[:except] || [])
23
+ end
24
+
25
+ def default_route_sets
26
+ [:bookmarks, :folders, :search_history, :saved_searches, :catalog, :feedback]
27
+ end
28
+
29
+ module RouteSets
30
+ def bookmarks
31
+ add_routes do |options|
32
+ match "bookmarks/clear", :to => "bookmarks#clear", :as => "clear_bookmarks"
33
+ resources :bookmarks
34
+ end
35
+ end
36
+
37
+
38
+ def folders
39
+ add_routes do |options|
40
+ match "folder/clear", :to => "folder#clear", :as => "clear_folder"
41
+ match "folder/destroy", :to => "folder#destroy"
42
+ resources :folder, :only => [:index, :update, :destroy]
43
+ end
44
+ end
45
+
46
+ def search_history
47
+ add_routes do |options|
48
+ match "search_history", :to => "search_history#index", :as => "search_history"
49
+ match "search_history/clear", :to => "search_history#clear", :as => "clear_search_history"
50
+ match "search_history/destroy/:id", :to => "search_history#destroy", :as => "delete_search"
51
+ end
52
+ end
53
+
54
+
55
+ def saved_searches
56
+ add_routes do |options|
57
+ match "saved_searches/clear", :to => "saved_searches#clear", :as => "clear_saved_searches"
58
+ match "saved_searches", :to => "saved_searches#index", :as => "saved_searches"
59
+ match "saved_searches/save/:id", :to => "saved_searches#save", :as => "save_search"
60
+ match "saved_searches/forget/:id", :to => "saved_searches#forget", :as => "forget_search"
61
+ end
62
+ end
63
+
64
+ def catalog
65
+ add_routes do |options|
66
+ # Catalog stuff.
67
+ match 'catalog/opensearch', :as => "opensearch_catalog"
68
+ match 'catalog/citation', :as => "citation_catalog"
69
+ match 'catalog/email', :as => "email_catalog"
70
+ match 'catalog/sms', :as => "sms_catalog"
71
+ match 'catalog/endnote', :as => "endnote_catalog"
72
+ match 'catalog/send_email_record', :as => "send_email_record_catalog"
73
+ match "catalog/facet/:id", :to => 'catalog#facet', :as => 'catalog_facet'
74
+ match 'catalog/unapi', :to => "catalog#unapi", :as => 'unapi'
75
+ resources :catalog, :only => [:index, :show, :update]
76
+ match 'catalog/:id/librarian_view', :to => "catalog#librarian_view", :as => "librarian_view_catalog"
77
+ end
78
+ end
79
+
80
+
81
+ # Feedback
82
+ def feedback
83
+ add_routes do |options|
84
+ match "feedback", :to => "feedback#show"
85
+ match "feedback/complete", :to => "feedback#complete"
86
+ end
87
+ end
88
+ end
89
+ include RouteSets
90
+ end
91
+ end
@@ -82,6 +82,7 @@ module Blacklight::Solr::Document
82
82
 
83
83
  def self.included(base)
84
84
  base.send :include, RSolr::Ext::Model
85
+ base.send :include, InstanceMethods
85
86
  base.send :extend, ClassMethods
86
87
 
87
88
  # after_initialize hook comes from RSolr::Ext::Model, I think.
@@ -90,7 +91,13 @@ module Blacklight::Solr::Document
90
91
  apply_extensions
91
92
  end
92
93
  end
93
-
94
+
95
+ module InstanceMethods
96
+ def id
97
+ self[self.class.unique_key]
98
+ end
99
+ end
100
+
94
101
 
95
102
  # Needs to be called in initializer of class including this module, to
96
103
  # apply all registered extensions on a per-document basis
@@ -192,6 +199,14 @@ module Blacklight::Solr::Document
192
199
  # extendability architecture
193
200
  module ClassMethods
194
201
  attr_writer :registered_extensions
202
+
203
+ def unique_key
204
+ Blacklight.config[:unique_key] || 'id'
205
+ end
206
+
207
+ def connection
208
+ @connection ||= Blacklight.solr
209
+ end
195
210
 
196
211
  # Returns array of hashes of registered extensions. Each hash
197
212
  # has a :module_obj key and a :condition_proc key. Usually this
@@ -39,6 +39,10 @@ module Blacklight::Solr::Document::MarcExport
39
39
  def export_as_mla_citation_txt
40
40
  mla_citation( to_marc )
41
41
  end
42
+
43
+ def export_as_chicago_citation_txt
44
+ chicago_citation( to_marc )
45
+ end
42
46
 
43
47
  # Exports as an OpenURL KEV (key-encoded value) query string.
44
48
  # For use to create COinS, among other things. COinS are
@@ -220,6 +224,129 @@ module Blacklight::Solr::Document::MarcExport
220
224
 
221
225
  protected
222
226
 
227
+ # Main method for defining chicago style citation. If we don't end up converting to using a citation formatting service
228
+ # we should make this receive a semantic document and not MARC so we can use this with other formats.
229
+ def chicago_citation(marc)
230
+ authors = get_all_authors(marc)
231
+ author_text = ""
232
+ unless authors[:primary_authors].blank?
233
+ if authors[:primary_authors].length > 10
234
+ authors[:primary_authors].each_with_index do |author,index|
235
+ if index < 7
236
+ if index == 0
237
+ author_text << "#{author}"
238
+ if author.ends_with?(",")
239
+ author_text << " "
240
+ else
241
+ author_text << ", "
242
+ end
243
+ else
244
+ author_text << "#{name_reverse(author)}, "
245
+ end
246
+ end
247
+ end
248
+ author_text << " et al."
249
+ elsif authors[:primary_authors].length > 1
250
+ authors[:primary_authors].each_with_index do |author,index|
251
+ if index == 0
252
+ author_text << "#{author}"
253
+ if author.ends_with?(",")
254
+ author_text << " "
255
+ else
256
+ author_text << ", "
257
+ end
258
+ elsif index + 1 == authors[:primary_authors].length
259
+ author_text << "and #{name_reverse(author)}."
260
+ else
261
+ author_text << "#{name_reverse(author)}, "
262
+ end
263
+ end
264
+ else
265
+ author_text << authors[:primary_authors].first
266
+ end
267
+ else
268
+ temp_authors = []
269
+ authors[:translators].each do |translator|
270
+ temp_authors << [translator, "trans."]
271
+ end
272
+ authors[:editors].each do |editor|
273
+ temp_authors << [editor, "ed."]
274
+ end
275
+ authors[:compilers].each do |compiler|
276
+ temp_authors << [compiler, "comp."]
277
+ end
278
+
279
+ unless temp_authors.blank?
280
+ if temp_authors.length > 10
281
+ temp_authors.each_with_index do |author,index|
282
+ if index < 7
283
+ author_text << "#{author.first} #{author.last} "
284
+ end
285
+ end
286
+ author_text << " et al."
287
+ elsif temp_authors.length > 1
288
+ temp_authors.each_with_index do |author,index|
289
+ if index == 0
290
+ author_text << "#{author.first} #{author.last}, "
291
+ elsif index + 1 == temp_authors.length
292
+ author_text << "and #{name_reverse(author.first)} #{author.last}"
293
+ else
294
+ author_text << "#{name_reverse(author.first)} #{author.last}, "
295
+ end
296
+ end
297
+ else
298
+ author_text << "#{temp_authors.first.first} #{temp_authors.first.last}"
299
+ end
300
+ end
301
+ end
302
+ title = ""
303
+ additional_title = ""
304
+ section_title = ""
305
+ if marc["245"] and (marc["245"]["a"] or marc["245"]["b"])
306
+ title << citation_title(clean_end_punctuation(marc["245"]["a"]).strip) if marc["245"]["a"]
307
+ title << ": #{citation_title(clean_end_punctuation(marc["245"]["b"]).strip)}" if marc["245"]["b"]
308
+ end
309
+ if marc["245"] and (marc["245"]["n"] or marc["245"]["p"])
310
+ section_title << citation_title(clean_end_punctuation(marc["245"]["n"])) if marc["245"]["n"]
311
+ if marc["245"]["p"]
312
+ section_title << ", <i>#{citation_title(clean_end_punctuation(marc["245"]["p"]))}.</i>"
313
+ elsif marc["245"]["n"]
314
+ section_title << "."
315
+ end
316
+ end
317
+
318
+ if !authors[:primary_authors].blank? and (!authors[:translators].blank? or !authors[:editors].blank? or !authors[:compilers].blank?)
319
+ additional_title << "Translated by #{authors[:translators].collect{|name| name_reverse(name)}.join(" and ")}. " unless authors[:translators].blank?
320
+ additional_title << "Edited by #{authors[:editors].collect{|name| name_reverse(name)}.join(" and ")}. " unless authors[:editors].blank?
321
+ additional_title << "Compiled by #{authors[:compilers].collect{|name| name_reverse(name)}.join(" and ")}. " unless authors[:compilers].blank?
322
+ end
323
+
324
+ edition = ""
325
+ edition << setup_edition(marc) unless setup_edition(marc).nil?
326
+
327
+ pub_info = ""
328
+ if marc["260"] and (marc["260"]["a"] or marc["260"]["b"])
329
+ pub_info << clean_end_punctuation(marc["260"]["a"]).strip if marc["260"]["a"]
330
+ pub_info << ": #{clean_end_punctuation(marc["260"]["b"]).strip}" if marc["260"]["b"]
331
+ pub_info << ", #{setup_pub_date(marc)}" if marc["260"]["c"]
332
+ elsif marc["502"] and marc["502"]["a"] # MARC 502 is the Dissertation Note. This holds the correct pub info for these types of records.
333
+ pub_info << marc["502"]["a"]
334
+ elsif marc["502"] and (marc["502"]["b"] or marc["502"]["c"] or marc["502"]["d"]) #sometimes the dissertation note is encoded in pieces in the $b $c and $d sub fields instead of lumped into the $a
335
+ pub_info << "#{marc["502"]["b"]}, #{marc["502"]["c"]}, #{clean_end_punctuation(marc["502"]["d"])}"
336
+ end
337
+
338
+ citation = ""
339
+ citation << "#{author_text} " unless author_text.blank?
340
+ citation << "<i>#{title}.</i> " unless title.blank?
341
+ citation << "#{section_title} " unless section_title.blank?
342
+ citation << "#{additional_title} " unless additional_title.blank?
343
+ citation << "#{edition} " unless edition.blank?
344
+ citation << "#{pub_info}." unless pub_info.blank?
345
+ citation
346
+ end
347
+
348
+
349
+
223
350
  def mla_citation(record)
224
351
  text = ''
225
352
  authors_final = []
@@ -320,11 +447,11 @@ module Blacklight::Solr::Document::MarcExport
320
447
  if !record.find{|f| f.tag == '260'}.nil?
321
448
  pub_date = record.find{|f| f.tag == '260'}
322
449
  if pub_date.find{|s| s.code == 'c'}
323
- date_value = pub_date.find{|s| s.code == 'c'}.value.gsub(/[^0-9]/, "") unless pub_date.find{|s| s.code == 'c'}.value.gsub(/[^0-9]/, "").blank?
450
+ date_value = pub_date.find{|s| s.code == 'c'}.value.gsub(/[^0-9|n\.d\.]/, "")[0,4] unless pub_date.find{|s| s.code == 'c'}.value.gsub(/[^0-9|n\.d\.]/, "")[0,4].blank?
324
451
  end
325
- return nil unless !date_value.nil?
452
+ return nil if date_value.nil?
326
453
  end
327
- date_value
454
+ clean_end_punctuation(date_value) if date_value
328
455
  end
329
456
  def setup_pub_info(record)
330
457
  text = ''
@@ -357,6 +484,22 @@ module Blacklight::Solr::Document::MarcExport
357
484
  end
358
485
  new_text.join(" ")
359
486
  end
487
+
488
+ # This will replace the mla_citation_title method with a better understanding of how MLA and Chicago citation titles are formatted.
489
+ # This method will take in a string and capitalize all of the non-prepositions.
490
+ def citation_title(title_text)
491
+ prepositions = ["a","about","across","an","and","before","but","by","for","it","of","the","to","with","without"]
492
+ new_text = []
493
+ title_text.split(" ").each_with_index do |word,index|
494
+ if (index == 0 and word != word.upcase) or (word.length > 1 and word != word.upcase and !prepositions.include?(word))
495
+ # the split("-") will handle the capitalization of hyphenated words
496
+ new_text << word.split("-").map!{|w| w.capitalize }.join("-")
497
+ else
498
+ new_text << word
499
+ end
500
+ end
501
+ new_text.join(" ")
502
+ end
360
503
 
361
504
  def setup_title_info(record)
362
505
  text = ''
@@ -407,11 +550,37 @@ module Blacklight::Solr::Document::MarcExport
407
550
  author_list.push(clean_end_punctuation(l.find{|s| s.code == 'a'}.value)) unless l.find{|s| s.code == 'a'}.value.nil?
408
551
  end
409
552
  end
410
-
553
+
411
554
  author_list.uniq!
412
555
  author_list
413
556
  end
414
557
 
558
+ # This is a replacement method for the get_author_list method. This new method will break authors out into primary authors, translators, editors, and compilers
559
+ def get_all_authors(record)
560
+ translator_code = "trl"; editor_code = "edt"; compiler_code = "com"
561
+ primary_authors = []; translators = []; editors = []; compilers = []
562
+ record.find_all{|f| f.tag === "100" }.each do |field|
563
+ primary_authors << field["a"] if field["a"]
564
+ end
565
+ record.find_all{|f| f.tag === "700" }.each do |field|
566
+ if field["a"]
567
+ relators = []
568
+ relators << clean_end_punctuation(field["e"]) if field["e"]
569
+ relators << clean_end_punctuation(field["4"]) if field["4"]
570
+ if relators.include?(translator_code)
571
+ translators << field["a"]
572
+ elsif relators.include?(editor_code)
573
+ editors << field["a"]
574
+ elsif relators.include?(compiler_code)
575
+ compilers << field["a"]
576
+ else
577
+ primary_authors << field["a"]
578
+ end
579
+ end
580
+ end
581
+ {:primary_authors => primary_authors, :translators => translators, :editors => editors, :compilers => compilers}
582
+ end
583
+
415
584
  def abbreviate_name(name)
416
585
  name_parts = name.split(", ")
417
586
  first_name_parts = name_parts.last.split(" ")
@@ -423,6 +592,7 @@ module Blacklight::Solr::Document::MarcExport
423
592
 
424
593
  def name_reverse(name)
425
594
  name = clean_end_punctuation(name)
595
+ return name unless name =~ /,/
426
596
  temp_name = name.split(", ")
427
597
  return temp_name.last + " " + temp_name.first
428
598
  end