mods_display 0.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.gitignore +19 -0
  2. data/.travis.yml +5 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +26 -0
  5. data/README.md +136 -0
  6. data/Rakefile +5 -0
  7. data/lib/mods_display.rb +30 -0
  8. data/lib/mods_display/configuration.rb +73 -0
  9. data/lib/mods_display/configuration/base.rb +23 -0
  10. data/lib/mods_display/configuration/subject.rb +11 -0
  11. data/lib/mods_display/controller_extension.rb +32 -0
  12. data/lib/mods_display/fields/abstract.rb +32 -0
  13. data/lib/mods_display/fields/audience.rb +7 -0
  14. data/lib/mods_display/fields/cartographics.rb +21 -0
  15. data/lib/mods_display/fields/collection.rb +21 -0
  16. data/lib/mods_display/fields/contents.rb +7 -0
  17. data/lib/mods_display/fields/description.rb +30 -0
  18. data/lib/mods_display/fields/field.rb +89 -0
  19. data/lib/mods_display/fields/format.rb +34 -0
  20. data/lib/mods_display/fields/identifier.rb +60 -0
  21. data/lib/mods_display/fields/imprint.rb +68 -0
  22. data/lib/mods_display/fields/language.rb +33 -0
  23. data/lib/mods_display/fields/location.rb +25 -0
  24. data/lib/mods_display/fields/name.rb +97 -0
  25. data/lib/mods_display/fields/note.rb +49 -0
  26. data/lib/mods_display/fields/related_item.rb +24 -0
  27. data/lib/mods_display/fields/related_location.rb +14 -0
  28. data/lib/mods_display/fields/subject.rb +103 -0
  29. data/lib/mods_display/fields/title.rb +49 -0
  30. data/lib/mods_display/fields/values.rb +11 -0
  31. data/lib/mods_display/html.rb +87 -0
  32. data/lib/mods_display/model_extension.rb +20 -0
  33. data/lib/mods_display/version.rb +3 -0
  34. data/mods_display.gemspec +24 -0
  35. data/spec/configuration/base_spec.rb +29 -0
  36. data/spec/fields/abstract_spec.rb +21 -0
  37. data/spec/fields/audience_spec.rb +21 -0
  38. data/spec/fields/cartographics_spec.rb +39 -0
  39. data/spec/fields/collection_spec.rb +31 -0
  40. data/spec/fields/contents_spec.rb +21 -0
  41. data/spec/fields/description_spec.rb +37 -0
  42. data/spec/fields/format_spec.rb +35 -0
  43. data/spec/fields/identifier_spec.rb +49 -0
  44. data/spec/fields/imprint_spec.rb +78 -0
  45. data/spec/fields/language_spec.rb +55 -0
  46. data/spec/fields/location_spec.rb +25 -0
  47. data/spec/fields/name_spec.rb +88 -0
  48. data/spec/fields/note_spec.rb +53 -0
  49. data/spec/fields/related_item_spec.rb +37 -0
  50. data/spec/fields/related_location_spec.rb +31 -0
  51. data/spec/fields/subject_spec.rb +89 -0
  52. data/spec/fields/title_spec.rb +47 -0
  53. data/spec/fixtures/cartographics_fixtures.rb +52 -0
  54. data/spec/fixtures/imprint_fixtures.rb +89 -0
  55. data/spec/fixtures/name_fixtures.rb +3 -0
  56. data/spec/fixtures/subjects_fixtures.rb +70 -0
  57. data/spec/integration/configuration_spec.rb +37 -0
  58. data/spec/integration/installation_spec.rb +26 -0
  59. data/spec/spec_helper.rb +35 -0
  60. metadata +182 -0
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .rvmrc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ .rvmrc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
@@ -0,0 +1,5 @@
1
+ notifications:
2
+ email: false
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mods_display.gemspec
4
+ gemspec
@@ -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.
@@ -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
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
@@ -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 &note
47
+ @note ||= ModsDisplay::Configuration::Base.new(&note || 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,11 @@
1
+ class ModsDisplay::Configuration::Subject < ModsDisplay::Configuration::Base
2
+
3
+ def hierarchical_link hierarchical_link=false
4
+ @hierarchical_link ||= hierarchical_link
5
+ end
6
+
7
+ def delimiter delimiter=" &gt; "
8
+ @delimiter ||= delimiter
9
+ end
10
+
11
+ 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,7 @@
1
+ class ModsDisplay::Audience < ModsDisplay::Field
2
+
3
+ def label
4
+ super || "Target audience"
5
+ end
6
+
7
+ 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