mods_display 0.0.1.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +26 -0
- data/README.md +136 -0
- data/Rakefile +5 -0
- data/lib/mods_display.rb +30 -0
- data/lib/mods_display/configuration.rb +73 -0
- data/lib/mods_display/configuration/base.rb +23 -0
- data/lib/mods_display/configuration/subject.rb +11 -0
- data/lib/mods_display/controller_extension.rb +32 -0
- data/lib/mods_display/fields/abstract.rb +32 -0
- data/lib/mods_display/fields/audience.rb +7 -0
- data/lib/mods_display/fields/cartographics.rb +21 -0
- data/lib/mods_display/fields/collection.rb +21 -0
- data/lib/mods_display/fields/contents.rb +7 -0
- data/lib/mods_display/fields/description.rb +30 -0
- data/lib/mods_display/fields/field.rb +89 -0
- data/lib/mods_display/fields/format.rb +34 -0
- data/lib/mods_display/fields/identifier.rb +60 -0
- data/lib/mods_display/fields/imprint.rb +68 -0
- data/lib/mods_display/fields/language.rb +33 -0
- data/lib/mods_display/fields/location.rb +25 -0
- data/lib/mods_display/fields/name.rb +97 -0
- data/lib/mods_display/fields/note.rb +49 -0
- data/lib/mods_display/fields/related_item.rb +24 -0
- data/lib/mods_display/fields/related_location.rb +14 -0
- data/lib/mods_display/fields/subject.rb +103 -0
- data/lib/mods_display/fields/title.rb +49 -0
- data/lib/mods_display/fields/values.rb +11 -0
- data/lib/mods_display/html.rb +87 -0
- data/lib/mods_display/model_extension.rb +20 -0
- data/lib/mods_display/version.rb +3 -0
- data/mods_display.gemspec +24 -0
- data/spec/configuration/base_spec.rb +29 -0
- data/spec/fields/abstract_spec.rb +21 -0
- data/spec/fields/audience_spec.rb +21 -0
- data/spec/fields/cartographics_spec.rb +39 -0
- data/spec/fields/collection_spec.rb +31 -0
- data/spec/fields/contents_spec.rb +21 -0
- data/spec/fields/description_spec.rb +37 -0
- data/spec/fields/format_spec.rb +35 -0
- data/spec/fields/identifier_spec.rb +49 -0
- data/spec/fields/imprint_spec.rb +78 -0
- data/spec/fields/language_spec.rb +55 -0
- data/spec/fields/location_spec.rb +25 -0
- data/spec/fields/name_spec.rb +88 -0
- data/spec/fields/note_spec.rb +53 -0
- data/spec/fields/related_item_spec.rb +37 -0
- data/spec/fields/related_location_spec.rb +31 -0
- data/spec/fields/subject_spec.rb +89 -0
- data/spec/fields/title_spec.rb +47 -0
- data/spec/fixtures/cartographics_fixtures.rb +52 -0
- data/spec/fixtures/imprint_fixtures.rb +89 -0
- data/spec/fixtures/name_fixtures.rb +3 -0
- data/spec/fixtures/subjects_fixtures.rb +70 -0
- data/spec/integration/configuration_spec.rb +37 -0
- data/spec/integration/installation_spec.rb +26 -0
- data/spec/spec_helper.rb +35 -0
- metadata +182 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright (c) 2012-2013. The Board of Trustees of the Leland Stanford Junior University. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use of this distribution in source and binary forms, with or without modification, are permitted provided that: The above copyright notice and this permission notice appear in all copies and supporting documentation; The name, identifiers, and trademarks of The Board of Trustees of the Leland Stanford Junior University are not used in advertising or publicity without the express prior written permission of The Board of Trustees of the Leland Stanford Junior University; Recipients acknowledge that this distribution is made available as a research courtesy, "as is", potentially with defects, without any obligation on the part of The Board of Trustees of the Leland Stanford Junior University to provide support, services, or repair;
|
4
|
+
|
5
|
+
THE BOARD OF TRUSTEES OF THE LELAND STANFORD JUNIOR UNIVERSITY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE BOARD OF TRUSTEES OF THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
6
|
+
|
7
|
+
MIT License
|
8
|
+
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
10
|
+
a copy of this software and associated documentation files (the
|
11
|
+
"Software"), to deal in the Software without restriction, including
|
12
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
13
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
14
|
+
permit persons to whom the Software is furnished to do so, subject to
|
15
|
+
the following conditions:
|
16
|
+
|
17
|
+
The above copyright notice and this permission notice shall be
|
18
|
+
included in all copies or substantial portions of the Software.
|
19
|
+
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
21
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
23
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
24
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
25
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
26
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/sul-dlss/mods_display.png?branch=master)](https://travis-ci.org/sul-dlss/mods_display)
|
2
|
+
|
3
|
+
# ModsDisplay
|
4
|
+
|
5
|
+
A gem for displaying MODS Metadata in a configurable way.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'mods_display'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install mods_display
|
20
|
+
|
21
|
+
Include the `ModelExtension` into your model.
|
22
|
+
|
23
|
+
class MyClass
|
24
|
+
include ModsDisplay::ModelExtension
|
25
|
+
end
|
26
|
+
|
27
|
+
Configure the source of the MODS xml string
|
28
|
+
|
29
|
+
class MyClass
|
30
|
+
....
|
31
|
+
|
32
|
+
mods_xml_source do |model|
|
33
|
+
model.mods
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
Include the `ControllerExtension` into your rails controller (or another class if not using rails).
|
39
|
+
|
40
|
+
class MyController
|
41
|
+
include ModsDisplay::ControllerExtension
|
42
|
+
end
|
43
|
+
|
44
|
+
Optionally configure the mods display gem (more on configuration later).
|
45
|
+
|
46
|
+
class MyController
|
47
|
+
....
|
48
|
+
configure_mods_display do
|
49
|
+
....
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
## Configuration
|
54
|
+
|
55
|
+
In the class that you include the `ModsDisplay::ControllerExtension` you can configure various behavior for different fields. The configuration options provided by `ModsDisplay::Configuration::Base` are:
|
56
|
+
|
57
|
+
* label_class
|
58
|
+
* value_class
|
59
|
+
* delimiter
|
60
|
+
* link
|
61
|
+
|
62
|
+
### Label and Value classes
|
63
|
+
|
64
|
+
Both label_ and value_class accept strings to put in as a class.
|
65
|
+
|
66
|
+
class MyController
|
67
|
+
include ModsDisplay::ControllerExtension
|
68
|
+
|
69
|
+
configure_mods_display do
|
70
|
+
title do
|
71
|
+
label_class "title-label"
|
72
|
+
value_class "title-value"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
### Delimiter
|
78
|
+
|
79
|
+
The delimiter configuration option accepts a string which will be used to delimit multiple multiple values within a single label.
|
80
|
+
|
81
|
+
configure_mods_display do
|
82
|
+
note do
|
83
|
+
delimiter "<br/>"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
Note: The default is a comma and a space (", ")
|
88
|
+
|
89
|
+
### Link
|
90
|
+
|
91
|
+
The link configuration option takes 2 parameters. The first is a key that is a method_name available in the class including `ModsDisplay::ControllerExtension` and the 2nd is options to pass to that method. This method must return a string that will be used as the href attribute of the link. (NOTE: If you have the %value% token in your options that will be replaced with the value of the field being linked)
|
92
|
+
|
93
|
+
class MyController
|
94
|
+
include ModsDisplay::ControllerExtension
|
95
|
+
|
96
|
+
configure_mods_display do
|
97
|
+
format do
|
98
|
+
link :format_path, '"%value%"'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def format_path(format)
|
103
|
+
"http://example.com/?f[format_field][]=#{format}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
### Special Subject Configuration
|
108
|
+
|
109
|
+
Depending on the implementation of subjects there may be different ways you would want to link them. The standard way of linking will just create a link passing the value to the href and the link text. However; in certain cases the subjects should be linked so that each subject to the right of a delimiter should have the values of all its preceding values in the href.
|
110
|
+
|
111
|
+
[Country](http://example.com/?"Country") > [State](http://example.com/?"Country State") > [City](http://example.com/?"Country State City")
|
112
|
+
|
113
|
+
This can be accomplished by setting the hierarchical_link configuration option to true for subjects
|
114
|
+
|
115
|
+
configure_mods_display do
|
116
|
+
subject do
|
117
|
+
hierarchical_link true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
NOTE: The default delimiter is set to > for subjects.
|
122
|
+
|
123
|
+
## Usage
|
124
|
+
|
125
|
+
Once installed, the class that included the `ControllerExtension` (`MyController`) will have the `render_mods_display` method available. This method takes one argument which is an instance of the class that included the `ModelExtension` (`MyClass`).
|
126
|
+
|
127
|
+
render_mods_display(@model) # where @model.is_a?(MyClass)
|
128
|
+
|
129
|
+
|
130
|
+
## Contributing
|
131
|
+
|
132
|
+
1. Fork it
|
133
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
134
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
135
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
136
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/mods_display.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "mods_display/controller_extension"
|
2
|
+
require "mods_display/html"
|
3
|
+
require "mods_display/model_extension"
|
4
|
+
require "mods_display/configuration"
|
5
|
+
require "mods_display/configuration/base"
|
6
|
+
require "mods_display/configuration/subject"
|
7
|
+
require "mods_display/fields/field"
|
8
|
+
require "mods_display/fields/abstract"
|
9
|
+
require "mods_display/fields/audience"
|
10
|
+
require "mods_display/fields/collection"
|
11
|
+
require "mods_display/fields/contents"
|
12
|
+
require "mods_display/fields/cartographics"
|
13
|
+
require "mods_display/fields/description"
|
14
|
+
require "mods_display/fields/format"
|
15
|
+
require "mods_display/fields/identifier"
|
16
|
+
require "mods_display/fields/imprint"
|
17
|
+
require "mods_display/fields/language"
|
18
|
+
require "mods_display/fields/location"
|
19
|
+
require "mods_display/fields/name"
|
20
|
+
require "mods_display/fields/note"
|
21
|
+
require "mods_display/fields/related_item"
|
22
|
+
require "mods_display/fields/related_location"
|
23
|
+
require "mods_display/fields/subject"
|
24
|
+
require "mods_display/fields/title"
|
25
|
+
require "mods_display/fields/values"
|
26
|
+
require "mods_display/version"
|
27
|
+
|
28
|
+
module ModsDisplay
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class ModsDisplay::Configuration
|
2
|
+
def initialize &config
|
3
|
+
instance_eval &config
|
4
|
+
end
|
5
|
+
|
6
|
+
def title &title
|
7
|
+
@title ||= ModsDisplay::Configuration::Base.new(&title || Proc.new{})
|
8
|
+
end
|
9
|
+
|
10
|
+
def name &name
|
11
|
+
@name ||= ModsDisplay::Configuration::Base.new(&name || Proc.new{})
|
12
|
+
end
|
13
|
+
|
14
|
+
def format &format
|
15
|
+
@format ||= ModsDisplay::Configuration::Base.new(&format || Proc.new{})
|
16
|
+
end
|
17
|
+
|
18
|
+
def imprint &imprint
|
19
|
+
@imprint ||= ModsDisplay::Configuration::Base.new(&imprint || Proc.new{})
|
20
|
+
end
|
21
|
+
|
22
|
+
def language &language
|
23
|
+
@language ||= ModsDisplay::Configuration::Base.new(&language || Proc.new{})
|
24
|
+
end
|
25
|
+
|
26
|
+
def description &description
|
27
|
+
@description ||= ModsDisplay::Configuration::Base.new(&description || Proc.new{})
|
28
|
+
end
|
29
|
+
|
30
|
+
def cartographics &cartographics
|
31
|
+
@cartographics ||= ModsDisplay::Configuration::Base.new(&cartographics || Proc.new{})
|
32
|
+
end
|
33
|
+
|
34
|
+
def abstract &abstract
|
35
|
+
@abstract ||= ModsDisplay::Configuration::Base.new(&abstract || Proc.new{})
|
36
|
+
end
|
37
|
+
|
38
|
+
def contents &contents
|
39
|
+
@contents ||= ModsDisplay::Configuration::Base.new(&contents || Proc.new{})
|
40
|
+
end
|
41
|
+
|
42
|
+
def audience &audience
|
43
|
+
@audience ||= ModsDisplay::Configuration::Base.new(&audience || Proc.new{})
|
44
|
+
end
|
45
|
+
|
46
|
+
def note ¬e
|
47
|
+
@note ||= ModsDisplay::Configuration::Base.new(¬e || Proc.new{})
|
48
|
+
end
|
49
|
+
|
50
|
+
def collection &collection
|
51
|
+
@collection ||= ModsDisplay::Configuration::Base.new(&collection || Proc.new{})
|
52
|
+
end
|
53
|
+
|
54
|
+
def related_location &related_location
|
55
|
+
@related_location ||= ModsDisplay::Configuration::Base.new(&related_location || Proc.new{})
|
56
|
+
end
|
57
|
+
|
58
|
+
def related_item &related_item
|
59
|
+
@related_item ||= ModsDisplay::Configuration::Base.new(&related_item || Proc.new{})
|
60
|
+
end
|
61
|
+
|
62
|
+
def subject &subject
|
63
|
+
@subject ||= ModsDisplay::Configuration::Subject.new(&subject || Proc.new{})
|
64
|
+
end
|
65
|
+
|
66
|
+
def identifier &identifier
|
67
|
+
@identifier ||= ModsDisplay::Configuration::Base.new(&identifier || Proc.new{})
|
68
|
+
end
|
69
|
+
|
70
|
+
def location &location
|
71
|
+
@location ||= ModsDisplay::Configuration::Base.new(&location || Proc.new{})
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ModsDisplay::Configuration::Base
|
2
|
+
def initialize &config
|
3
|
+
instance_eval &config if block_given?
|
4
|
+
end
|
5
|
+
|
6
|
+
def label_class label_class=""
|
7
|
+
@label_class ||= label_class
|
8
|
+
end
|
9
|
+
|
10
|
+
def value_class value_class=""
|
11
|
+
@value_class ||= value_class
|
12
|
+
end
|
13
|
+
|
14
|
+
def delimiter delimiter=", "
|
15
|
+
@delimiter ||= delimiter
|
16
|
+
end
|
17
|
+
|
18
|
+
def link method_name="", args={}
|
19
|
+
return @link if method_name == ""
|
20
|
+
@link ||= [method_name, args]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ModsDisplay::ControllerExtension
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
base.class_eval do
|
6
|
+
def mods_display_config
|
7
|
+
@mods_display_config || self.class.mods_display_config
|
8
|
+
end
|
9
|
+
if base.respond_to?(:helper_method)
|
10
|
+
helper_method :mods_display_config, :render_mods_display
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_mods_display model
|
16
|
+
return "" if model.mods_display_xml.nil?
|
17
|
+
ModsDisplay::HTML.new(mods_display_config, model.mods_display_xml, self)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def configure_mods_display &config
|
24
|
+
@mods_display_config = ModsDisplay::Configuration.new &config
|
25
|
+
end
|
26
|
+
|
27
|
+
def mods_display_config
|
28
|
+
@mods_display_config
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class ModsDisplay::Abstract < ModsDisplay::Field
|
3
|
+
|
4
|
+
def label
|
5
|
+
super || "Abstract"
|
6
|
+
end
|
7
|
+
|
8
|
+
def text
|
9
|
+
return link_value(super) unless super.nil?
|
10
|
+
link_value(@value.text)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def link_value(val)
|
16
|
+
val = val.dup
|
17
|
+
# http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
18
|
+
url = /(?i)\b(?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\([^\s()<>]+|\([^\s()<>]+\)*\))+(?:\([^\s()<>]+|\([^\s()<>]+\)*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])/i
|
19
|
+
# http://www.regular-expressions.info/email.html
|
20
|
+
email = /[A-Z0-9_\.%\+\-\']+@(?:[A-Z0-9\-]+\.)+(?:[A-Z]{2,4}|museum|travel)/i
|
21
|
+
matches = [val.scan(url), val.scan(email)].flatten
|
22
|
+
matches.each do |match|
|
23
|
+
if match =~ email
|
24
|
+
val = val.gsub(match, "<a href='mailto:#{match}'>#{match}</a>")
|
25
|
+
else
|
26
|
+
val = val.gsub(match, "<a href='#{match}'>#{match}</a>")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
val
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class ModsDisplay::Cartographics < ModsDisplay::Field
|
2
|
+
|
3
|
+
def fields
|
4
|
+
return nil if @value.nil?
|
5
|
+
return_values = []
|
6
|
+
@value.each do |val|
|
7
|
+
if val.respond_to?(:cartographics)
|
8
|
+
val.cartographics.each do |field|
|
9
|
+
scale = field.scale.empty? ? "Scale not given" : field.scale.text
|
10
|
+
projection = field.projection.empty? ? nil : field.projection.text
|
11
|
+
coordinates = field.coordinates.empty? ? nil : field.coordinates.text
|
12
|
+
post_scale = [projection, coordinates].compact.length > 0 ? [projection, coordinates].compact.join(" ") : nil
|
13
|
+
return_values << ModsDisplay::Values.new({:label => (displayLabel(field) || label || "Map Data"),
|
14
|
+
:values => [[scale, post_scale].compact.join(" ; ")]})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
return_values
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class ModsDisplay::Collection < ModsDisplay::Field
|
2
|
+
|
3
|
+
def label
|
4
|
+
super || "Collection"
|
5
|
+
end
|
6
|
+
|
7
|
+
def fields
|
8
|
+
return_values = []
|
9
|
+
@value.each do |val|
|
10
|
+
if val.respond_to?(:titleInfo) and
|
11
|
+
val.respond_to?(:typeOfResource) and
|
12
|
+
val.typeOfResource.attributes.length > 0 and
|
13
|
+
val.typeOfResource.attributes.first.has_key?("collection") and
|
14
|
+
val.typeOfResource.attributes.first["collection"].value == "yes"
|
15
|
+
return_values << ModsDisplay::Values.new(:label => label, :values => [val.titleInfo.text.strip])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
return_values
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|