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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/VERSION +1 -1
- data/app/assets/stylesheets/blacklight/_facets.scss +11 -10
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +14 -14
- data/app/helpers/blacklight/configuration_helper_behavior.rb +16 -10
- data/app/helpers/blacklight/facets_helper_behavior.rb +15 -14
- data/app/helpers/blacklight/url_helper_behavior.rb +1 -1
- data/app/models/bookmark.rb +1 -4
- data/app/models/search.rb +3 -6
- data/app/views/catalog/_facet_layout.html.erb +2 -2
- data/app/views/catalog/_facet_limit.html.erb +5 -3
- data/app/views/catalog/_facet_pivot.html.erb +4 -4
- data/app/views/catalog/_home_text.html.erb +8 -48
- data/app/views/catalog/_index_default.html.erb +3 -3
- data/app/views/catalog/_show_default.html.erb +3 -3
- data/app/views/catalog/_sms_form.html.erb +1 -1
- data/app/views/catalog/facet.html.erb +1 -1
- data/blacklight.gemspec +1 -1
- data/config/jetty.yml +0 -3
- data/config/locales/blacklight.de.yml +2 -0
- data/config/locales/blacklight.en.yml +2 -0
- data/config/locales/blacklight.es.yml +2 -0
- data/config/locales/blacklight.fr.yml +2 -0
- data/config/locales/blacklight.pt-BR.yml +2 -0
- data/lib/blacklight.rb +70 -26
- data/lib/blacklight/abstract_repository.rb +29 -0
- data/lib/blacklight/base.rb +7 -7
- data/lib/blacklight/bookmarks.rb +5 -5
- data/lib/blacklight/catalog.rb +34 -19
- data/lib/blacklight/catalog/search_context.rb +1 -1
- data/lib/blacklight/configuration.rb +112 -46
- data/lib/blacklight/configuration/facet_field.rb +9 -7
- data/lib/blacklight/configuration/field.rb +27 -0
- data/lib/blacklight/configuration/fields.rb +25 -20
- data/lib/blacklight/configuration/search_field.rb +6 -8
- data/lib/blacklight/configuration/solr_field.rb +3 -18
- data/lib/blacklight/configuration/sort_field.rb +6 -7
- data/lib/blacklight/document.rb +156 -0
- data/lib/blacklight/document/dublin_core.rb +41 -0
- data/lib/blacklight/document/email.rb +16 -0
- data/lib/blacklight/document/export.rb +107 -0
- data/lib/blacklight/document/extensions.rb +56 -0
- data/lib/blacklight/document/schema_org.rb +7 -0
- data/lib/blacklight/document/semantic_fields.rb +51 -0
- data/lib/blacklight/document/sms.rb +14 -0
- data/lib/blacklight/document_presenter.rb +3 -3
- data/lib/blacklight/exceptions.rb +9 -2
- data/lib/blacklight/facet.rb +21 -16
- data/lib/blacklight/request_builders.rb +60 -284
- data/lib/blacklight/routes.rb +1 -1
- data/lib/blacklight/search_builder.rb +130 -0
- data/lib/blacklight/search_helper.rb +316 -0
- data/lib/blacklight/solr.rb +1 -0
- data/lib/blacklight/solr/document.rb +4 -187
- data/lib/blacklight/solr/document/dublin_core.rb +3 -37
- data/lib/blacklight/solr/document/email.rb +4 -13
- data/lib/blacklight/solr/document/export.rb +3 -103
- data/lib/blacklight/solr/document/extensions.rb +4 -52
- data/lib/blacklight/solr/document/more_like_this.rb +1 -1
- data/lib/blacklight/solr/document/schema_org.rb +4 -4
- data/lib/blacklight/solr/document/sms.rb +4 -11
- data/lib/blacklight/solr/facet_paginator.rb +2 -2
- data/lib/blacklight/solr/search_builder.rb +264 -0
- data/lib/blacklight/solr_helper.rb +6 -261
- data/lib/blacklight/solr_repository.rb +30 -24
- data/lib/blacklight/solr_response.rb +3 -3
- data/lib/blacklight/user.rb +1 -2
- data/lib/blacklight/utils.rb +0 -23
- data/lib/generators/blacklight/controller_generator.rb +38 -0
- data/lib/generators/blacklight/document_generator.rb +20 -0
- data/lib/generators/blacklight/install_generator.rb +38 -39
- data/lib/generators/blacklight/models_generator.rb +2 -62
- data/lib/generators/blacklight/templates/catalog_controller.rb +3 -4
- data/lib/generators/blacklight/templates/config/{solr.yml → blacklight.yml} +3 -0
- data/lib/generators/blacklight/templates/config/jetty.yml +0 -3
- data/lib/generators/blacklight/templates/solr_document.rb +6 -6
- data/lib/generators/blacklight/test_support_generator.rb +1 -6
- data/lib/generators/blacklight/user_generator.rb +59 -0
- data/lib/railties/blacklight.rake +16 -7
- data/spec/controllers/catalog_controller_spec.rb +9 -15
- data/spec/features/facets_spec.rb +8 -0
- data/spec/helpers/configuration_helper_spec.rb +6 -13
- data/spec/helpers/facets_helper_spec.rb +3 -2
- data/spec/lib/blacklight/configuration_spec.rb +11 -38
- data/spec/lib/blacklight/{solr/document → document}/dublin_core_spec.rb +4 -4
- data/spec/lib/blacklight/{solr/document → document}/email_spec.rb +2 -2
- data/spec/lib/blacklight/{solr/document → document}/sms_spec.rb +2 -2
- data/spec/lib/blacklight/search_builder_spec.rb +145 -0
- data/spec/lib/blacklight/search_helper_spec.rb +775 -0
- data/spec/lib/blacklight/solr/document/more_like_this_spec.rb +1 -1
- data/spec/lib/blacklight/solr/search_builder_spec.rb +561 -0
- data/spec/lib/blacklight/solr_helper_spec.rb +5 -1291
- data/spec/lib/blacklight/solr_repository_spec.rb +13 -13
- data/spec/models/record_mailer_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
- data/spec/views/catalog/_constraints.html.erb_spec.rb +1 -1
- data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +2 -2
- data/spec/views/catalog/index.atom.builder_spec.rb +1 -1
- data/tasks/blacklight.rake +1 -1
- data/template.demo.rb +1 -1
- metadata +33 -45
- data/doc/Adding-new-document-actions.md +0 -94
- data/doc/Atom-Responses.md +0 -90
- data/doc/Blacklight-Add-ons.md +0 -23
- data/doc/Blacklight-configuration.md +0 -411
- data/doc/Blacklight-on-Heroku.md +0 -100
- data/doc/Blacklight-out-of-the-box.md +0 -47
- data/doc/Bookmarks.md +0 -1
- data/doc/Code4Lib-2014.md +0 -94
- data/doc/Configuration---Facet-Fields.md +0 -130
- data/doc/Configuration---Results-View.md +0 -224
- data/doc/Configuration---Solr-fields.md +0 -106
- data/doc/Configuring-and-Customizing-Blacklight.md +0 -257
- data/doc/Configuring-rails-routes.md +0 -13
- data/doc/Contributing-to-Blacklight.md +0 -43
- data/doc/Examples.md +0 -120
- data/doc/Extending-or-Modifying-Blacklight-Search-Behavior.md +0 -141
- data/doc/Home.md +0 -100
- data/doc/How-to-release-a-version.md +0 -45
- data/doc/Indexing-your-data-into-solr.md +0 -36
- data/doc/Internationalization.md +0 -32
- data/doc/JSON-API.md +0 -83
- data/doc/Pagination.md +0 -52
- data/doc/Providing-your-own-view-templates.md +0 -69
- data/doc/Quickstart.md +0 -153
- data/doc/README_SOLR.md +0 -245
- data/doc/Saved-Searches.md +0 -5
- data/doc/Solr-Configuration.md +0 -154
- data/doc/Sunspot-for-indexing.md +0 -46
- data/doc/Support.md +0 -33
- data/doc/Theming.md +0 -62
- data/doc/Understanding-Rails-and-Blacklight.md +0 -75
- data/doc/User-Authentication.md +0 -60
- data/doc/_Sidebar.md +0 -9
- data/doc/testing.md +0 -58
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
module Blacklight
|
|
2
|
-
class Configuration::SearchField < Blacklight::Configuration::
|
|
2
|
+
class Configuration::SearchField < Blacklight::Configuration::Field
|
|
3
3
|
def normalize! blacklight_config = nil
|
|
4
|
-
|
|
5
|
-
|
|
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 <
|
|
3
|
-
def
|
|
4
|
-
|
|
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::
|
|
2
|
+
class Configuration::SortField < Blacklight::Configuration::Field
|
|
3
3
|
def normalize! blacklight_config = nil
|
|
4
|
-
|
|
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.
|
|
11
|
-
|
|
8
|
+
self.sort ||= self.field
|
|
9
|
+
|
|
10
|
+
self
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def validate!
|
|
15
|
-
raise ArgumentError.new("Must supply a
|
|
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
|