blacklight 5.9.4 → 5.10.0

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 (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