blacklight 5.9.4 → 5.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/VERSION +1 -1
  4. data/app/assets/stylesheets/blacklight/_facets.scss +11 -10
  5. data/app/helpers/blacklight/blacklight_helper_behavior.rb +14 -14
  6. data/app/helpers/blacklight/configuration_helper_behavior.rb +16 -10
  7. data/app/helpers/blacklight/facets_helper_behavior.rb +15 -14
  8. data/app/helpers/blacklight/url_helper_behavior.rb +1 -1
  9. data/app/models/bookmark.rb +1 -4
  10. data/app/models/search.rb +3 -6
  11. data/app/views/catalog/_facet_layout.html.erb +2 -2
  12. data/app/views/catalog/_facet_limit.html.erb +5 -3
  13. data/app/views/catalog/_facet_pivot.html.erb +4 -4
  14. data/app/views/catalog/_home_text.html.erb +8 -48
  15. data/app/views/catalog/_index_default.html.erb +3 -3
  16. data/app/views/catalog/_show_default.html.erb +3 -3
  17. data/app/views/catalog/_sms_form.html.erb +1 -1
  18. data/app/views/catalog/facet.html.erb +1 -1
  19. data/blacklight.gemspec +1 -1
  20. data/config/jetty.yml +0 -3
  21. data/config/locales/blacklight.de.yml +2 -0
  22. data/config/locales/blacklight.en.yml +2 -0
  23. data/config/locales/blacklight.es.yml +2 -0
  24. data/config/locales/blacklight.fr.yml +2 -0
  25. data/config/locales/blacklight.pt-BR.yml +2 -0
  26. data/lib/blacklight.rb +70 -26
  27. data/lib/blacklight/abstract_repository.rb +29 -0
  28. data/lib/blacklight/base.rb +7 -7
  29. data/lib/blacklight/bookmarks.rb +5 -5
  30. data/lib/blacklight/catalog.rb +34 -19
  31. data/lib/blacklight/catalog/search_context.rb +1 -1
  32. data/lib/blacklight/configuration.rb +112 -46
  33. data/lib/blacklight/configuration/facet_field.rb +9 -7
  34. data/lib/blacklight/configuration/field.rb +27 -0
  35. data/lib/blacklight/configuration/fields.rb +25 -20
  36. data/lib/blacklight/configuration/search_field.rb +6 -8
  37. data/lib/blacklight/configuration/solr_field.rb +3 -18
  38. data/lib/blacklight/configuration/sort_field.rb +6 -7
  39. data/lib/blacklight/document.rb +156 -0
  40. data/lib/blacklight/document/dublin_core.rb +41 -0
  41. data/lib/blacklight/document/email.rb +16 -0
  42. data/lib/blacklight/document/export.rb +107 -0
  43. data/lib/blacklight/document/extensions.rb +56 -0
  44. data/lib/blacklight/document/schema_org.rb +7 -0
  45. data/lib/blacklight/document/semantic_fields.rb +51 -0
  46. data/lib/blacklight/document/sms.rb +14 -0
  47. data/lib/blacklight/document_presenter.rb +3 -3
  48. data/lib/blacklight/exceptions.rb +9 -2
  49. data/lib/blacklight/facet.rb +21 -16
  50. data/lib/blacklight/request_builders.rb +60 -284
  51. data/lib/blacklight/routes.rb +1 -1
  52. data/lib/blacklight/search_builder.rb +130 -0
  53. data/lib/blacklight/search_helper.rb +316 -0
  54. data/lib/blacklight/solr.rb +1 -0
  55. data/lib/blacklight/solr/document.rb +4 -187
  56. data/lib/blacklight/solr/document/dublin_core.rb +3 -37
  57. data/lib/blacklight/solr/document/email.rb +4 -13
  58. data/lib/blacklight/solr/document/export.rb +3 -103
  59. data/lib/blacklight/solr/document/extensions.rb +4 -52
  60. data/lib/blacklight/solr/document/more_like_this.rb +1 -1
  61. data/lib/blacklight/solr/document/schema_org.rb +4 -4
  62. data/lib/blacklight/solr/document/sms.rb +4 -11
  63. data/lib/blacklight/solr/facet_paginator.rb +2 -2
  64. data/lib/blacklight/solr/search_builder.rb +264 -0
  65. data/lib/blacklight/solr_helper.rb +6 -261
  66. data/lib/blacklight/solr_repository.rb +30 -24
  67. data/lib/blacklight/solr_response.rb +3 -3
  68. data/lib/blacklight/user.rb +1 -2
  69. data/lib/blacklight/utils.rb +0 -23
  70. data/lib/generators/blacklight/controller_generator.rb +38 -0
  71. data/lib/generators/blacklight/document_generator.rb +20 -0
  72. data/lib/generators/blacklight/install_generator.rb +38 -39
  73. data/lib/generators/blacklight/models_generator.rb +2 -62
  74. data/lib/generators/blacklight/templates/catalog_controller.rb +3 -4
  75. data/lib/generators/blacklight/templates/config/{solr.yml → blacklight.yml} +3 -0
  76. data/lib/generators/blacklight/templates/config/jetty.yml +0 -3
  77. data/lib/generators/blacklight/templates/solr_document.rb +6 -6
  78. data/lib/generators/blacklight/test_support_generator.rb +1 -6
  79. data/lib/generators/blacklight/user_generator.rb +59 -0
  80. data/lib/railties/blacklight.rake +16 -7
  81. data/spec/controllers/catalog_controller_spec.rb +9 -15
  82. data/spec/features/facets_spec.rb +8 -0
  83. data/spec/helpers/configuration_helper_spec.rb +6 -13
  84. data/spec/helpers/facets_helper_spec.rb +3 -2
  85. data/spec/lib/blacklight/configuration_spec.rb +11 -38
  86. data/spec/lib/blacklight/{solr/document → document}/dublin_core_spec.rb +4 -4
  87. data/spec/lib/blacklight/{solr/document → document}/email_spec.rb +2 -2
  88. data/spec/lib/blacklight/{solr/document → document}/sms_spec.rb +2 -2
  89. data/spec/lib/blacklight/search_builder_spec.rb +145 -0
  90. data/spec/lib/blacklight/search_helper_spec.rb +775 -0
  91. data/spec/lib/blacklight/solr/document/more_like_this_spec.rb +1 -1
  92. data/spec/lib/blacklight/solr/search_builder_spec.rb +561 -0
  93. data/spec/lib/blacklight/solr_helper_spec.rb +5 -1291
  94. data/spec/lib/blacklight/solr_repository_spec.rb +13 -13
  95. data/spec/models/record_mailer_spec.rb +2 -2
  96. data/spec/spec_helper.rb +1 -0
  97. data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
  98. data/spec/views/catalog/_constraints.html.erb_spec.rb +1 -1
  99. data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +2 -2
  100. data/spec/views/catalog/index.atom.builder_spec.rb +1 -1
  101. data/tasks/blacklight.rake +1 -1
  102. data/template.demo.rb +1 -1
  103. metadata +33 -45
  104. data/doc/Adding-new-document-actions.md +0 -94
  105. data/doc/Atom-Responses.md +0 -90
  106. data/doc/Blacklight-Add-ons.md +0 -23
  107. data/doc/Blacklight-configuration.md +0 -411
  108. data/doc/Blacklight-on-Heroku.md +0 -100
  109. data/doc/Blacklight-out-of-the-box.md +0 -47
  110. data/doc/Bookmarks.md +0 -1
  111. data/doc/Code4Lib-2014.md +0 -94
  112. data/doc/Configuration---Facet-Fields.md +0 -130
  113. data/doc/Configuration---Results-View.md +0 -224
  114. data/doc/Configuration---Solr-fields.md +0 -106
  115. data/doc/Configuring-and-Customizing-Blacklight.md +0 -257
  116. data/doc/Configuring-rails-routes.md +0 -13
  117. data/doc/Contributing-to-Blacklight.md +0 -43
  118. data/doc/Examples.md +0 -120
  119. data/doc/Extending-or-Modifying-Blacklight-Search-Behavior.md +0 -141
  120. data/doc/Home.md +0 -100
  121. data/doc/How-to-release-a-version.md +0 -45
  122. data/doc/Indexing-your-data-into-solr.md +0 -36
  123. data/doc/Internationalization.md +0 -32
  124. data/doc/JSON-API.md +0 -83
  125. data/doc/Pagination.md +0 -52
  126. data/doc/Providing-your-own-view-templates.md +0 -69
  127. data/doc/Quickstart.md +0 -153
  128. data/doc/README_SOLR.md +0 -245
  129. data/doc/Saved-Searches.md +0 -5
  130. data/doc/Solr-Configuration.md +0 -154
  131. data/doc/Sunspot-for-indexing.md +0 -46
  132. data/doc/Support.md +0 -33
  133. data/doc/Theming.md +0 -62
  134. data/doc/Understanding-Rails-and-Blacklight.md +0 -75
  135. data/doc/User-Authentication.md +0 -60
  136. data/doc/_Sidebar.md +0 -9
  137. data/doc/testing.md +0 -58
@@ -1,14 +1,12 @@
1
1
  module Blacklight
2
- class Configuration::SearchField < Blacklight::Configuration::SolrField
2
+ class Configuration::SearchField < Blacklight::Configuration::Field
3
3
  def normalize! blacklight_config = nil
4
- # Some normalization, calculate display_label from key,
5
- # and make sure we have a qt from defaults.
6
- self.key ||= self.field
7
- self.field ||= self.key
8
- self.label ||= self.key.try(:titlecase)
9
- self.qt ||= blacklight_config.default_solr_params[:qt] if blacklight_config && blacklight_config.default_solr_params
10
- self.if = self.include_in_simple_select if self.if.nil?
4
+ self.if ||= self.include_in_simple_select
5
+
11
6
  super
7
+ self.qt ||= blacklight_config.default_solr_params[:qt] if blacklight_config && blacklight_config.default_solr_params
8
+
9
+ self
12
10
  end
13
11
 
14
12
  def validate!
@@ -1,22 +1,7 @@
1
1
  module Blacklight
2
- class Configuration::SolrField < OpenStructWithHashAccess
3
- def normalize! blacklight_config = nil
4
- self.label ||= default_label
5
- self.if = true if self.if.nil?
6
- self.unless = false if self.unless.nil?
7
- self
8
- end
9
-
10
- def validate!
11
- raise ArgumentError.new("Must supply a solr field name") if self.field.nil?
12
- end
13
-
14
- def default_label
15
- if self.field.respond_to?(:titleize)
16
- self.field.try(:titleize)
17
- else
18
- self.field.to_s.titleize
19
- end
2
+ class Configuration::SolrField < Blacklight::Configuration::Field
3
+ def self.extended *args
4
+ Deprecation.warn Blacklight::Configuration::SolrField, "Blacklight::Configuration::SolrField is deprecated; use Blacklight::Configuration::Field instead"
20
5
  end
21
6
  end
22
7
  end
@@ -1,18 +1,17 @@
1
1
  module Blacklight
2
- class Configuration::SortField < Blacklight::Configuration::SolrField
2
+ class Configuration::SortField < Blacklight::Configuration::Field
3
3
  def normalize! blacklight_config = nil
4
- self.sort ||= self.field
5
-
6
- self.field ||= self.key
4
+ super
7
5
  self.field ||= self.label.try(:parameterize)
8
6
  self.field ||= self.sort
9
7
 
10
- self.key ||= self.field
11
- super
8
+ self.sort ||= self.field
9
+
10
+ self
12
11
  end
13
12
 
14
13
  def validate!
15
- raise ArgumentError.new("Must supply a solr sort string") if self.sort.nil?
14
+ raise ArgumentError.new("Must supply a sort string") if self.sort.nil?
16
15
  end
17
16
  end
18
17
  end
@@ -0,0 +1,156 @@
1
+ ##
2
+ ##
3
+ # = Introduction
4
+ # Blacklight::Document is the module with logic for a class representing
5
+ # an individual document returned from Solr results. It can be added in to any
6
+ # local class you want, but in default Blacklight a SolrDocument class is
7
+ # provided for you which is pretty much a blank class "include"ing
8
+ # Blacklight::Document.
9
+ #
10
+ # Blacklight::Document provides some DefaultFinders.
11
+ #
12
+ # It also provides support for Document Extensions, which advertise supported
13
+ # transformation formats.
14
+ #
15
+ module Blacklight::Document
16
+ autoload :SchemaOrg, 'blacklight/document/schema_org'
17
+ autoload :DublinCore, 'blacklight/document/dublin_core'
18
+ autoload :Email, 'blacklight/document/email'
19
+ autoload :SemanticFields, 'blacklight/document/semantic_fields'
20
+ autoload :Sms, 'blacklight/document/sms'
21
+ autoload :Extensions, 'blacklight/document/extensions'
22
+ autoload :Export, 'blacklight/document/export'
23
+
24
+ extend ActiveSupport::Concern
25
+ include Blacklight::Document::SchemaOrg
26
+ include Blacklight::Document::SemanticFields
27
+ include Blacklight::Document::Export
28
+
29
+ included do
30
+ extend ActiveModel::Naming
31
+ include Blacklight::Document::Extensions
32
+ end
33
+
34
+ attr_reader :response
35
+ alias_method :solr_response, :response
36
+
37
+ def initialize(source_doc={}, response=nil)
38
+ @_source = source_doc.with_indifferent_access
39
+ @response = response
40
+ apply_extensions
41
+ end
42
+
43
+ def to_model
44
+ self
45
+ end
46
+
47
+ def persisted?
48
+ true
49
+ end
50
+
51
+ # the wrapper method to the @_source object.
52
+ # If a method is missing, it gets sent to @_source
53
+ # with all of the original params and block
54
+ def method_missing(m, *args, &b)
55
+ @_source.send(m, *args, &b)
56
+ end
57
+
58
+ def [] *args
59
+ @_source.send :[], *args
60
+ end
61
+
62
+ # Helper method to check if value/multi-values exist for a given key.
63
+ # The value can be a string, or a RegExp
64
+ # Multiple "values" can be given; only one needs to match.
65
+ #
66
+ # Example:
67
+ # doc.has?(:location_facet)
68
+ # doc.has?(:location_facet, 'Clemons')
69
+ # doc.has?(:id, 'h009', /^u/i)
70
+ def has?(k, *values)
71
+ return true if key?(k) and values.empty?
72
+ return false if self[k].nil?
73
+ target = self[k]
74
+ if target.is_a?(Array)
75
+ values.each do |val|
76
+ return target.any?{|tv| val.is_a?(Regexp) ? (tv =~ val) : (tv==val)}
77
+ end
78
+ else
79
+ return values.any? {|val| val.is_a?(Regexp) ? (target =~ val) : (target == val)}
80
+ end
81
+ end
82
+
83
+ def key? k
84
+ @_source.key? k
85
+ end
86
+
87
+ # helper
88
+ # key is the name of the field
89
+ # opts is a hash with the following valid keys:
90
+ # - :sep - a string used for joining multivalued field values
91
+ # - :default - a value to return when the key doesn't exist
92
+ # if :sep is nil and the field is a multivalued field, the array is returned
93
+ def get(key, opts={:sep=>', ', :default=>nil})
94
+ if key? key
95
+ val = self[key]
96
+ (val.is_a?(Array) and opts[:sep]) ? val.join(opts[:sep]) : val
97
+ else
98
+ opts[:default]
99
+ end
100
+ end
101
+
102
+ def first key
103
+ Array(self[key]).first
104
+ end
105
+
106
+ def id
107
+ self[self.class.unique_key]
108
+ end
109
+
110
+ def to_param
111
+ id.to_s
112
+ end
113
+
114
+ def as_json(options = nil)
115
+ @_source.as_json(options)
116
+ end
117
+
118
+ def to_partial_path
119
+ 'catalog/document'
120
+ end
121
+
122
+ def destroyed?
123
+ false
124
+ end
125
+
126
+ def new_record?
127
+ false
128
+ end
129
+
130
+ def has_highlight_field? k
131
+ false
132
+ end
133
+
134
+ def highlight_field k
135
+ nil
136
+ end
137
+
138
+
139
+ # Certain class-level methods needed for the document-specific
140
+ # extendability architecture
141
+ module ClassMethods
142
+
143
+ attr_writer :unique_key
144
+ def unique_key
145
+ @unique_key ||= 'id'
146
+ end
147
+
148
+ def primary_key
149
+ unique_key
150
+ end
151
+
152
+ def base_class
153
+ self
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,41 @@
1
+ require 'builder'
2
+
3
+ # This module provide Dublin Core export based on the document's semantic values
4
+ module Blacklight::Document::DublinCore
5
+
6
+ def self.extended(document)
7
+ # Register our exportable formats
8
+ Blacklight::Document::DublinCore.register_export_formats( document )
9
+ end
10
+
11
+ def self.register_export_formats(document)
12
+ document.will_export_as(:xml)
13
+ document.will_export_as(:dc_xml, "text/xml")
14
+ document.will_export_as(:oai_dc_xml, "text/xml")
15
+ end
16
+
17
+ def dublin_core_field_names
18
+ [:contributor, :coverage, :creator, :date, :description, :format, :identifier, :language, :publisher, :relation, :rights, :source, :subject, :title, :type]
19
+ end
20
+
21
+ # dublin core elements are mapped against the #dublin_core_field_names whitelist.
22
+ def export_as_oai_dc_xml
23
+ xml = Builder::XmlMarkup.new
24
+ xml.tag!("oai_dc:dc",
25
+ 'xmlns:oai_dc' => "http://www.openarchives.org/OAI/2.0/oai_dc/",
26
+ 'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
27
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
28
+ 'xsi:schemaLocation' => %{http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd}) do
29
+ self.to_semantic_values.select { |field, values| dublin_core_field_names.include? field.to_sym }.each do |field,values|
30
+ values.each do |v|
31
+ xml.tag! 'dc:' + field.to_s, v
32
+ end
33
+ end
34
+ end
35
+ xml.target!
36
+ end
37
+
38
+ alias_method :export_as_xml, :export_as_oai_dc_xml
39
+ alias_method :export_as_dc_xml, :export_as_oai_dc_xml
40
+
41
+ end
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # This module provides the body of an email export based on the document's semantic values
3
+ module Blacklight::Document::Email
4
+
5
+ # Return a text string that will be the body of the email
6
+ def to_email_text
7
+ semantics = self.to_semantic_values
8
+ body = []
9
+ body << I18n.t('blacklight.email.text.title', value: semantics[:title].join(" ")) unless semantics[:title].blank?
10
+ body << I18n.t('blacklight.email.text.author', value: semantics[:author].join(" ")) unless semantics[:author].blank?
11
+ body << I18n.t('blacklight.email.text.format', value: semantics[:format].join(" ")) unless semantics[:format].blank?
12
+ body << I18n.t('blacklight.email.text.language', value: semantics[:language].join(" ")) unless semantics[:language].blank?
13
+ return body.join("\n") unless body.empty?
14
+ end
15
+
16
+ end
@@ -0,0 +1,107 @@
1
+ # == Transformation conventions
2
+ # The main use case for extensions is for transforming a Document to another
3
+ # format. Either to another type of Ruby object, or to an exportable string in
4
+ # a certain format.
5
+ #
6
+ # The convention for methods contained in extensions that transform to a ruby
7
+ # object is "to_*". For instance, "to_marc" would return a Ruby Marc object.
8
+ #
9
+ # The convention for methods contained in extensions that transform to an
10
+ # exportable file of some kind is "export_as_*". For instance,
11
+ # "export_as_marc21" would return a String object containing valid marc21, and
12
+ # "export_as_marcxml" would return a String object containing valid marcxml.
13
+ #
14
+ # The tokens used after "export_as" should normally be the format names as
15
+ # registered with Rails Mime::Type.
16
+ #
17
+ # == Advertising export formats
18
+ #
19
+ # If an extension advertises what export formats it can provide, than those
20
+ # formats will automatically be delivered by the Blacklight catalog/show
21
+ # controller, and potentially automatically advertised in various places
22
+ # that advertise available formats. (HTML link rel=alternate; Atom
23
+ # link rel=alterate; etc).
24
+ #
25
+ # Export formats are 'registered' by calling the #will_export_as method
26
+ # on a Document instance. An extension would usually do this in a
27
+ # self.extended method, so it can be called on Documents that have
28
+ # the given extension added to them. For instance:
29
+ #
30
+ # module DemoMarcExtension
31
+ # def self.extended(document)
32
+ # document.will_export_as(:marc21, "application/marc")
33
+ # document.will_export_as(:marcxml, "application/marcxml+xml")
34
+ # end
35
+ #
36
+ # def export_as_marc21 ; something ; end
37
+ # def export_as_marcxml ; something ; end
38
+ # end
39
+ #
40
+ module Blacklight::Document::Export
41
+
42
+ ##
43
+ # Register exportable formats supported by the individual document.
44
+ # Usually called by an extension in it's self.extended method, to
45
+ # register the formats that extension can export.
46
+ #
47
+ # some_document.will_export_as(:some_format, "application/type") means
48
+ # that the document (usually via an extension) has a method
49
+ # "export_as_some_format" which returns a String of content that
50
+ # is described by the mime content_type given.
51
+ #
52
+ # The format name should ideally _already_ be registered with
53
+ # Rails Mime::Type, in your application initializer, representing
54
+ # the content type given. However, this method will attempt to
55
+ # register it using Mime::Type.register_alias if it's not previously
56
+ # registered. This is a bit sketchy though.
57
+ def will_export_as(short_name, content_type = nil)
58
+ #Lookup in Rails Mime::Type, register if needed, otherwise take
59
+ # content-type from registration if needed. This uses
60
+ # some 'api' to Mime::Type that may or may not be entirely
61
+ # public, the fact that a Mime::CONST is registered for every
62
+ # type. But that's the only way to do the kind of check we need, sorry.
63
+ if defined?(Mime) && Mime.const_defined?(short_name.to_s.upcase)
64
+ mime_type = "Mime::#{short_name.to_s.upcase}".constantize
65
+ content_type = mime_type.to_s unless content_type
66
+ else
67
+ # not registered, we need to register. Use register_alias to be least
68
+ # likely to interfere with host app.
69
+ Mime::Type.register_alias(content_type, short_name)
70
+ end
71
+
72
+ # if content_type is nil, look it up from Rails Mime::Type
73
+ if content_type.nil?
74
+ # Accurate lookup in Rails Mime::Type is kind of pain, it doesn't
75
+ # really provide the right API.
76
+ if defined?(type_const_name)
77
+ content_type = type_const_name.constantize.to_s
78
+ end
79
+ end
80
+ export_formats[short_name] = {content_type: content_type}
81
+ end
82
+
83
+ # Collects formats that this doc can export as.
84
+ # Returns a hash, keys are format short-names that can
85
+ # be exported. Hash includes:
86
+ # :content-type => mime-content-type
87
+ # maybe more later
88
+ # To see if a given export format is supported by this document,
89
+ # simply call document.export_formats.keys.include?(:my_format)
90
+ # Then call #export_as! to do the export.
91
+ def export_formats
92
+ @export_formats ||= {}
93
+ end
94
+
95
+ # Call with a format shortname, export_as(:marc), simply returns
96
+ # #export_as_marc . Later we may expand the design to allow you
97
+ # to register an arbitrary method name instead of insisting
98
+ # on the convention, so clients should call this method so
99
+ # they'll still keep working if we do that.
100
+ def export_as(short_name)
101
+ send("export_as_#{short_name.to_s}")
102
+ end
103
+
104
+ def exports_as? short_name
105
+ respond_to? "export_as_#{short_name.to_s}"
106
+ end
107
+ end
@@ -0,0 +1,56 @@
1
+ # = Document Extensions
2
+ # An Blacklight::Document extension is simply a ruby module which is mixed
3
+ # in to individual Document instances. The intended use case is for documents
4
+ # containing some particular format of source material, such as Marc. An
5
+ # extension can be registered with your document class, along with a block
6
+ # containing custom logic for which documents to apply the extension to.
7
+ #
8
+ # SolrDocument.use_extension(MyExtension) {|document| my_logic_on_document(document}
9
+ #
10
+ # MyExtension will be mixed-in (using ruby 'extend') only to those documents
11
+ # where the block results in true.
12
+ #
13
+ # == Extension Parameters
14
+ # Every class that includes Blacklight::Solr::Document::Extensions gets a
15
+ # #extension_parameters method for saving arbitrary parameters on class-wide
16
+ # level that can be retrieved by extensions. These are arbitrary, just
17
+ # conventions with a given extension. For instance:
18
+ # SolrDocument.extension_parameters[:marc_source_field] = "solr_stored_field_name"
19
+ #
20
+ module Blacklight::Document::Extensions
21
+ extend ActiveSupport::Concern
22
+
23
+ # Needs to be called in initializer of class including this module, to
24
+ # apply all registered extensions on a per-document basis
25
+ def apply_extensions
26
+ self.class.registered_extensions.each do | registration|
27
+ self.extend( registration[:module_obj] ) if registration[:condition_proc].nil? || registration[:condition_proc].call( self )
28
+ end
29
+ end
30
+
31
+ module ClassMethods
32
+ attr_writer :registered_extensions
33
+
34
+ # want to zero out all previously registered extensions you can call:
35
+ # SolrDocument.registered_extensions = nil
36
+ def registered_extensions
37
+ @registered_extensions ||= []
38
+ end
39
+
40
+ def extension_parameters
41
+ @extension_parameters ||= {}
42
+ end
43
+
44
+ # Register an extension module with the class. A block taking one
45
+ # parameter can be supplied; the block will be passed an instance of
46
+ # a Document, and the extension will be applied only if the block
47
+ # evaluates as true. If no condition is given, the extension will
48
+ # be applied to every instance of the class.
49
+ #
50
+ # SolrDocument.use_extension( SomeExtensionModule ) { | document | should_apply_some_extension?(document) }
51
+ # SolrDocument.use_extension( SomeExtensionModule) # will be applied to all docs
52
+ def use_extension( module_obj, &condition )
53
+ registered_extensions << {module_obj: module_obj, condition_proc: condition}
54
+ end
55
+ end
56
+ end