blacklight 3.0.0pre4 → 3.0.0pre6

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