arclight 0.0.1 → 0.1.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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc +12 -0
  3. data/.gitignore +5 -0
  4. data/.rubocop.yml +66 -0
  5. data/.solr_wrapper +5 -0
  6. data/.travis.yml +30 -2
  7. data/CONTRIBUTING.md +43 -0
  8. data/Gemfile +36 -0
  9. data/LICENSE.txt +1 -0
  10. data/README.md +85 -12
  11. data/Rakefile +14 -3
  12. data/app/assets/images/blacklight/compact.svg +25 -0
  13. data/app/assets/images/blacklight/logo.png +0 -0
  14. data/app/assets/javascripts/arclight/arclight.js +9 -0
  15. data/app/assets/javascripts/arclight/collection_context.js +18 -0
  16. data/app/assets/javascripts/arclight/collection_navigation.js +114 -0
  17. data/app/assets/javascripts/arclight/collection_scrollspy.js +6 -0
  18. data/app/assets/javascripts/arclight/component_ancestors.js +56 -0
  19. data/app/assets/javascripts/arclight/oembed_viewer.js +39 -0
  20. data/app/assets/javascripts/arclight/truncator.js.erb +23 -0
  21. data/app/assets/stylesheets/arclight/application.scss +13 -0
  22. data/app/assets/stylesheets/arclight/bootstrap_overrides.scss +3 -0
  23. data/app/assets/stylesheets/arclight/modules/collection_search.scss +3 -0
  24. data/app/assets/stylesheets/arclight/modules/hierarchy_and_online_contents.scss +174 -0
  25. data/app/assets/stylesheets/arclight/modules/highlights.scss +10 -0
  26. data/app/assets/stylesheets/arclight/modules/layout.scss +33 -0
  27. data/app/assets/stylesheets/arclight/modules/mastheads.scss +60 -0
  28. data/app/assets/stylesheets/arclight/modules/repositories.scss +29 -0
  29. data/app/assets/stylesheets/arclight/modules/repository_card.scss +54 -0
  30. data/app/assets/stylesheets/arclight/modules/search_results.scss +75 -0
  31. data/app/assets/stylesheets/arclight/modules/show_collection.scss +78 -0
  32. data/app/assets/stylesheets/arclight/modules/sidebar.scss +16 -0
  33. data/app/assets/stylesheets/arclight/variables.scss +2 -0
  34. data/app/controllers/arclight/repositories_controller.rb +40 -0
  35. data/app/controllers/concerns/arclight/field_config_helpers.rb +86 -0
  36. data/app/factories/blacklight_field_configuration_factory.rb +29 -0
  37. data/app/helpers/arclight_helper.rb +173 -0
  38. data/app/models/arclight/parent.rb +24 -0
  39. data/app/models/arclight/parents.rb +34 -0
  40. data/app/models/arclight/requests/google_form.rb +44 -0
  41. data/app/models/concerns/arclight/catalog.rb +22 -0
  42. data/app/models/concerns/arclight/search_behavior.rb +46 -0
  43. data/app/models/concerns/arclight/solr_document.rb +131 -0
  44. data/app/presenters/arclight/index_presenter.rb +10 -0
  45. data/app/presenters/arclight/show_presenter.rb +27 -0
  46. data/app/views/arclight/.keep +0 -0
  47. data/app/views/arclight/repositories/_in_person_repository.html.erb +19 -0
  48. data/app/views/arclight/repositories/_repository.html.erb +62 -0
  49. data/app/views/arclight/repositories/index.html.erb +4 -0
  50. data/app/views/arclight/repositories/show.html.erb +38 -0
  51. data/app/views/arclight/requests/_google_form.html.erb +11 -0
  52. data/app/views/arclight/viewers/_oembed.html.erb +7 -0
  53. data/app/views/catalog/_arclight_document_index_header.html.erb +13 -0
  54. data/app/views/catalog/_arclight_document_index_header_hierarchy_default.html.erb +0 -0
  55. data/app/views/catalog/_arclight_document_index_header_online_contents_default.html.erb +0 -0
  56. data/app/views/catalog/_arclight_document_show_header.html.erb +15 -0
  57. data/app/views/catalog/_arclight_document_show_header_collection.html.erb +12 -0
  58. data/app/views/catalog/_arclight_index_compact_default.html.erb +15 -0
  59. data/app/views/catalog/_arclight_online_content_indicator.html.erb +5 -0
  60. data/app/views/catalog/_arclight_rangelimit.html.erb +24 -0
  61. data/app/views/catalog/_arclight_viewer_default.html.erb +1 -0
  62. data/app/views/catalog/_collection_contents.html.erb +12 -0
  63. data/app/views/catalog/_collection_count.html.erb +7 -0
  64. data/app/views/catalog/_collection_downloads.html.erb +17 -0
  65. data/app/views/catalog/_collection_online_contents.html.erb +17 -0
  66. data/app/views/catalog/_collection_overview.html.erb +7 -0
  67. data/app/views/catalog/_component_overview.html.erb +46 -0
  68. data/app/views/catalog/_context_card.html.erb +27 -0
  69. data/app/views/catalog/_context_sidebar.html.erb +8 -0
  70. data/app/views/catalog/_custom_metadata.html.erb +16 -0
  71. data/app/views/catalog/_home.html.erb +1 -0
  72. data/app/views/catalog/_index_breadcrumb_default.html.erb +3 -0
  73. data/app/views/catalog/_index_default.html.erb +17 -0
  74. data/app/views/catalog/_index_header.html.erb +7 -0
  75. data/app/views/catalog/_index_header_hierarchy_default.html.erb +42 -0
  76. data/app/views/catalog/_index_header_online_contents_default.html.erb +1 -0
  77. data/app/views/catalog/_index_hierarchy_default.html.erb +28 -0
  78. data/app/views/catalog/_index_online_contents_default.html.erb +6 -0
  79. data/app/views/catalog/_results_histogram.html.erb +10 -0
  80. data/app/views/catalog/_search_results.html.erb +31 -0
  81. data/app/views/catalog/_search_results_repository.html.erb +6 -0
  82. data/app/views/catalog/_search_within_form.html.erb +16 -0
  83. data/app/views/catalog/_show_breadcrumbs_default.html.erb +7 -0
  84. data/app/views/catalog/_show_collection.html.erb +40 -0
  85. data/app/views/catalog/_show_component_sidebar.html.erb +12 -0
  86. data/app/views/catalog/_show_default.html.erb +32 -0
  87. data/app/views/catalog/_show_header.html.erb +5 -0
  88. data/app/views/catalog/_show_sidebar.html.erb +30 -0
  89. data/app/views/catalog/index.html.erb +8 -0
  90. data/app/views/layouts/catalog_result.html.erb +7 -0
  91. data/app/views/shared/_breadcrumbs.html.erb +15 -0
  92. data/app/views/shared/_context_sidebar.html.erb +8 -0
  93. data/app/views/shared/_header_navbar.html.erb +54 -0
  94. data/app/views/shared/_main_menu_links.html.erb +6 -0
  95. data/arclight.gemspec +17 -4
  96. data/bin/rails +13 -0
  97. data/config/locales/arclight.en.yml +65 -0
  98. data/config/routes.rb +6 -0
  99. data/lib/arclight.rb +5 -0
  100. data/lib/arclight/custom_component.rb +98 -0
  101. data/lib/arclight/custom_document.rb +93 -0
  102. data/lib/arclight/digital_object.rb +26 -0
  103. data/lib/arclight/engine.rb +55 -0
  104. data/lib/arclight/exceptions.rb +18 -0
  105. data/lib/arclight/indexer.rb +9 -0
  106. data/lib/arclight/normalized_date.rb +45 -0
  107. data/lib/arclight/normalized_id.rb +25 -0
  108. data/lib/arclight/normalized_title.rb +30 -0
  109. data/lib/arclight/repository.rb +91 -0
  110. data/lib/arclight/shared_indexing_behavior.rb +97 -0
  111. data/lib/arclight/shared_terminology_behavior.rb +65 -0
  112. data/lib/arclight/solr_ead_indexer_ext.rb +159 -0
  113. data/lib/arclight/version.rb +3 -1
  114. data/lib/arclight/viewer.rb +45 -0
  115. data/lib/arclight/viewers/oembed.rb +56 -0
  116. data/lib/arclight/year_range.rb +102 -0
  117. data/lib/generators/arclight/install_generator.rb +63 -0
  118. data/lib/generators/arclight/templates/arclight.js +2 -0
  119. data/lib/generators/arclight/templates/arclight.scss +3 -0
  120. data/lib/generators/arclight/templates/catalog_controller.rb +347 -0
  121. data/lib/generators/arclight/templates/config/downloads.yml +13 -0
  122. data/lib/generators/arclight/templates/config/repositories.yml +42 -0
  123. data/lib/generators/arclight/update_generator.rb +22 -0
  124. data/lib/tasks/index.rake +87 -0
  125. data/package.json +24 -0
  126. data/solr/conf/_rest_managed.json +3 -0
  127. data/solr/conf/admin-extra.html +31 -0
  128. data/solr/conf/elevate.xml +36 -0
  129. data/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  130. data/solr/conf/protwords.txt +21 -0
  131. data/solr/conf/schema.xml +631 -0
  132. data/solr/conf/scripts.conf +24 -0
  133. data/solr/conf/solrconfig.xml +393 -0
  134. data/solr/conf/spellings.txt +2 -0
  135. data/solr/conf/stopwords.txt +58 -0
  136. data/solr/conf/stopwords_en.txt +58 -0
  137. data/solr/conf/synonyms.txt +31 -0
  138. data/solr/conf/xslt/example.xsl +132 -0
  139. data/solr/conf/xslt/example_atom.xsl +67 -0
  140. data/solr/conf/xslt/example_rss.xsl +66 -0
  141. data/solr/conf/xslt/luke.xsl +337 -0
  142. data/tasks/arclight.rake +68 -0
  143. data/template.rb +15 -0
  144. data/vendor/assets/javascripts/responsiveTruncator.js +69 -0
  145. data/vendor/assets/javascripts/stickyfill.js +480 -0
  146. metadata +301 -6
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # A factory to return blacklight field configurations given a field key
5
+ # that represents a field group (e.g. summary_fields, access_fields, etc)
6
+ class BlacklightFieldConfigurationFactory
7
+ def self.for(config:, field:, field_group:)
8
+ new(config: config, field: field, field_group: field_group).field_config
9
+ end
10
+
11
+ def initialize(config:, field:, field_group:)
12
+ @config = config
13
+ @field = field
14
+ @field_group = field_group
15
+ end
16
+
17
+ def field_config
18
+ return null_field unless config.respond_to?(:"#{field_group}s")
19
+ config.send(:"#{field_group}s").fetch(field) { null_field }
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :config, :field, :field_group
25
+
26
+ def null_field
27
+ Blacklight::Configuration::NullField.new(field)
28
+ end
29
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Generic Helpers used in Arclight
5
+ module ArclightHelper
6
+ ##
7
+ # @param [SolrDocument]
8
+ def parents_to_links(document)
9
+ safe_join(Arclight::Parents.from_solr_document(document).as_parents.map do |parent|
10
+ link_to parent.label, solr_document_path(parent.global_id)
11
+ end, t('arclight.breadcrumb_separator'))
12
+ end
13
+
14
+ def repository_collections_path(repository)
15
+ search_action_url(
16
+ f: {
17
+ repository_sim: [repository.name],
18
+ level_sim: ['Collection']
19
+ }
20
+ )
21
+ end
22
+
23
+ ##
24
+ # Classes used for customized show page in arclight
25
+ def custom_show_content_classes
26
+ 'col-md-12 show-document'
27
+ end
28
+
29
+ def normalize_id(id)
30
+ Arclight::NormalizedId.new(id).to_s
31
+ end
32
+
33
+ def collection_active?
34
+ try(:search_state) && search_state.params_for_search.try(:[], 'f').try(:[], 'level_sim') == ['Collection']
35
+ end
36
+
37
+ def collection_active_class
38
+ 'active' if collection_active?
39
+ end
40
+
41
+ def collection_count
42
+ facets_from_request.find { |f| f.name == 'collection_sim' }.try(:items).try(:count)
43
+ end
44
+
45
+ ##
46
+ # Looks for `document.unitid` in the downloads configuration
47
+ # @param [SolrDocument] `document`
48
+ # @param [Hash] `config` metadata for downloadable files
49
+ # @return [Hash] with `:href` and `:size` keys
50
+ def collection_downloads(document, config = load_download_config)
51
+ config = config[document.unitid] if config.present?
52
+ return {} if config.blank?
53
+ parse_collection_downloads(config)
54
+ end
55
+
56
+ def on_repositories_show?
57
+ controller_name == 'repositories' && action_name == 'show'
58
+ end
59
+
60
+ def on_repositories_index?
61
+ controller_name == 'repositories' && action_name == 'index'
62
+ end
63
+
64
+ # the Repositories menu item is only active on the Repositories index page
65
+ def repositories_active_class
66
+ 'active' if on_repositories_index?
67
+ end
68
+
69
+ def fields_have_content?(document, field_accessor)
70
+ generic_document_fields(field_accessor).any? do |_, field|
71
+ generic_should_render_field?(field_accessor, document, field)
72
+ end
73
+ end
74
+
75
+ # If we have a facet on the repository, then return the Repository object for it
76
+ #
77
+ # @return [Repository]
78
+ def repository_faceted_on
79
+ return unless try(:search_state)
80
+ repos = facets_from_request.find { |f| f.name == 'repository_sim' }.try(:items)
81
+ faceted = repos && repos.length == 1 && repos.first.value
82
+ Arclight::Repository.find_by(name: repos.first.value) if faceted
83
+ end
84
+
85
+ def hierarchy_component_context?
86
+ params[:hierarchy_context] == 'component'
87
+ end
88
+
89
+ # @return [Hash] loaded from config/downloads.yml, or `{}` if missing file
90
+ def load_download_config(filename = Rails.root.join('config', 'downloads.yml'))
91
+ YAML.safe_load(File.read(filename))
92
+ rescue Errno::ENOENT
93
+ {}
94
+ end
95
+
96
+ # @return [Hash] the downloads for the given configuration using Hash symbols
97
+ # @example `{ pdf: { href: 'http://...', size: '123 KB' } }`
98
+ def parse_collection_downloads(config, results = {})
99
+ %w[pdf ead].each do |type|
100
+ next if config[type].blank?
101
+ results[type.to_sym] = {
102
+ href: config[type]['href'],
103
+ size: display_size(config[type]['size'])
104
+ }
105
+ end
106
+ results
107
+ end
108
+
109
+ # Show a human readable size, or if it's already a string, show that
110
+ # @return [String] human readable siz
111
+ def display_size(size)
112
+ size = number_to_human_size(size.to_i + 1) if size.is_a?(Numeric) || size =~ /^[0-9]+$/ # assumes bytes
113
+ size.to_s
114
+ end
115
+
116
+ ##
117
+ # Defines custom helpers used for creating unique metadata blocks to render
118
+ Arclight::Engine.config.catalog_controller_field_accessors.each do |config_field|
119
+ ##
120
+ # Mimics what document_show_fields from Blacklight does
121
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/configuration_helper_behavior.rb#L35-L38
122
+ define_method(:"document_#{config_field}s") do |_document = nil|
123
+ blacklight_config.send(:"#{config_field}s")
124
+ end
125
+
126
+ ##
127
+ # Mimics what render_document_show_field_label from Blacklight does
128
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/blacklight_helper_behavior.rb#L136-L156
129
+ define_method(:"render_document_#{config_field}_label") do |*args|
130
+ options = args.extract_options!
131
+ document = args.first
132
+
133
+ field = options[:field]
134
+
135
+ t(:'blacklight.search.show.label', label: send(:"document_#{config_field}_label", document, field))
136
+ end
137
+
138
+ ##
139
+ # Mimics what document_show_field_label from Blacklight does
140
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/configuration_helper_behavior.rb#L67-L74
141
+ define_method(:"document_#{config_field}_label") do |document, field|
142
+ field_config = send(:"document_#{config_field}s", document)[field]
143
+ field_config ||= Blacklight::Configuration::NullField.new(key: field)
144
+
145
+ field_config.display_label('show')
146
+ end
147
+
148
+ ##
149
+ # Mimics what should_render_show_field? from Blacklight does
150
+ # https://github.com/projectblacklight/blacklight/blob/dee8d794125306ec8d4ab834a6a45bcf9671c791/app/helpers/blacklight/blacklight_helper_behavior.rb#L84-L92
151
+ define_method(:"should_render_#{config_field}?") do |document, field_config|
152
+ should_render_field?(field_config, document) && document_has_value?(document, field_config)
153
+ end
154
+ end
155
+
156
+ ##
157
+ # Calls the method for a configured field
158
+ def generic_document_fields(config_field)
159
+ send(:"document_#{config_field}s")
160
+ end
161
+
162
+ ##
163
+ # Calls the method for a configured field
164
+ def generic_should_render_field?(config_field, document, field)
165
+ send(:"should_render_#{config_field}?", document, field)
166
+ end
167
+
168
+ ##
169
+ # Calls the method for a configured field
170
+ def generic_render_document_field_label(config_field, document, field: field_name)
171
+ send(:"render_document_#{config_field}_label", document, field: field)
172
+ end
173
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Logic containing information about Solr_Ead "Parent"
6
+ # https://github.com/awead/solr_ead/blob/8cf7ffaa66e0e4c9c0b12f5646d6c2e20984cd99/lib/solr_ead/behaviors.rb#L54-L57
7
+ class Parent
8
+ attr_reader :id, :label, :eadid
9
+ def initialize(id:, label:, eadid:)
10
+ @id = id
11
+ @label = label
12
+ @eadid = eadid
13
+ end
14
+
15
+ ##
16
+ # Concatenates the eadid and the id, to return an "id" in the context of
17
+ # Blacklight and Solr
18
+ # @return [String]
19
+ def global_id
20
+ return id if eadid == id
21
+ "#{eadid}#{id}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Object for parsing and formalizing Solr_Ead "Parents"
6
+ # https://github.com/awead/solr_ead/blob/8cf7ffaa66e0e4c9c0b12f5646d6c2e20984cd99/lib/solr_ead/behaviors.rb#L54-L57
7
+ class Parents
8
+ attr_reader :ids, :labels
9
+ def initialize(ids:, labels:, eadid:)
10
+ @ids = ids
11
+ @labels = labels
12
+ @eadid = eadid
13
+ end
14
+
15
+ def eadid
16
+ Arclight::NormalizedId.new(@eadid).to_s
17
+ end
18
+
19
+ ##
20
+ # @return [Array[Arclight::Parent]]
21
+ def as_parents
22
+ Hash[ids.zip(labels)].map { |k, v| Arclight::Parent.new(id: k, label: v, eadid: eadid) }
23
+ end
24
+
25
+ ##
26
+ # @param [SolrDocument] document
27
+ def self.from_solr_document(document)
28
+ ids = document.parent_ids
29
+ labels = document.parent_labels
30
+ eadid = document.eadid
31
+ new(ids: ids, labels: labels, eadid: eadid)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ module Requests
5
+ ##
6
+ # This object relies on the ability to respond to attributes passed in as
7
+ # query parameters from the form mapping configuratino
8
+ class GoogleForm
9
+ attr_reader :document, :presenter, :document_url
10
+ delegate :collection_name, :collection_creator, :eadid, :containers, to: :document
11
+
12
+ ##
13
+ # @param [Blacklight::SolrDocument] document
14
+ # @param [Arclight::ShowPresenter] presenter
15
+ # @param [String] document_url
16
+ def initialize(document, presenter, document_url)
17
+ @document = document
18
+ @presenter = presenter
19
+ @document_url = document_url
20
+ end
21
+
22
+ ##
23
+ # Url of form to fill
24
+ def url
25
+ document.repository_config.google_request_url
26
+ end
27
+
28
+ ##
29
+ # Converts mappings as a query url param into a Hash used for sending
30
+ # messages and providing pre-filled form fields
31
+ # "collection_name=entry.123" => { "collection_name" => "entry.123" }
32
+ # @return [Hash]
33
+ def form_mapping
34
+ Rack::Utils.parse_nested_query(
35
+ document.repository_config.google_request_mappings
36
+ )
37
+ end
38
+
39
+ def title
40
+ presenter.heading
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Arclight specific methods for the Catalog
6
+ module Catalog
7
+ ##
8
+ # Overriding the Blacklight method so that the hierarchy view does not start
9
+ # a new search session
10
+ def start_new_search_session?
11
+ !%w[hierarchy online_contents].include?(params[:view]) && super
12
+ end
13
+
14
+ ##
15
+ # Overriding the Blacklight method so that hierarchy does not get stored as
16
+ # the preferred view
17
+ def store_preferred_view
18
+ return if %w[hierarchy online_contents].include?(params[:view])
19
+ super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Customized Search Behavior for Arclight
6
+ module SearchBehavior
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ self.default_processor_chain += %i[
11
+ add_hierarchy_max_rows
12
+ add_hierarchy_sort
13
+ add_highlighting
14
+ ]
15
+ end
16
+
17
+ ##
18
+ # For the hierarchy view, set a higher (unlimited) maximum document return
19
+ def add_hierarchy_max_rows(solr_params)
20
+ if blacklight_params[:view] == 'hierarchy'
21
+ solr_params[:rows] = 999_999_999
22
+ end
23
+ solr_params
24
+ end
25
+
26
+ ##
27
+ # For the hierarchy view, set the sort order to preserve the order of components
28
+ def add_hierarchy_sort(solr_params)
29
+ solr_params[:sort] = 'sort_ii asc' if blacklight_params[:view] == 'hierarchy'
30
+ solr_params
31
+ end
32
+
33
+ ##
34
+ # Disable highlighting for hiearchy, and enable it for all other searches
35
+ def add_highlighting(solr_params)
36
+ if blacklight_params[:view] == 'hierarchy'
37
+ solr_params['hl'] = false
38
+ else
39
+ solr_params['hl'] = true
40
+ solr_params['hl.fl'] = 'text'
41
+ solr_params['hl.snippets'] = 3
42
+ end
43
+ solr_params
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ ##
5
+ # Extends Blacklight::Solr::Document to provide Arclight specific behavior
6
+ module SolrDocument
7
+ extend Blacklight::Solr::Document
8
+
9
+ def repository_config
10
+ return unless repository
11
+ @repository_config ||= Arclight::Repository.find_by(name: repository)
12
+ end
13
+
14
+ def parent_ids
15
+ fetch('parent_ssm', [])
16
+ end
17
+
18
+ def parent_labels
19
+ fetch('parent_unittitles_ssm', [])
20
+ end
21
+
22
+ def eadid
23
+ fetch('ead_ssi', nil)
24
+ end
25
+
26
+ def unitid
27
+ first('unitid_ssm')
28
+ end
29
+
30
+ def repository
31
+ first('repository_ssm')
32
+ end
33
+
34
+ def repository_and_unitid
35
+ [repository, unitid].compact.join(': ')
36
+ end
37
+
38
+ def collection_name
39
+ first('collection_ssm')
40
+ end
41
+
42
+ def extent
43
+ first('extent_ssm')
44
+ end
45
+
46
+ def abstract_or_scope
47
+ first('abstract_ssm') || first('scopecontent_ssm')
48
+ end
49
+
50
+ def creator
51
+ first('creator_ssm')
52
+ end
53
+
54
+ def collection_creator
55
+ first('collection_creator_ssm')
56
+ end
57
+
58
+ def online_content?
59
+ first('has_online_content_ssim') == 'true'
60
+ end
61
+
62
+ def number_of_children
63
+ first('child_component_count_isim') || 0
64
+ end
65
+
66
+ def children?
67
+ number_of_children.positive?
68
+ end
69
+
70
+ def reference
71
+ first('ref_ssm')
72
+ end
73
+
74
+ def component_level
75
+ first('component_level_isim')
76
+ end
77
+
78
+ def level
79
+ first('level_ssm')
80
+ end
81
+
82
+ def digital_object_viewer
83
+ @digital_object_viewer ||= Arclight::Viewer.render(self)
84
+ end
85
+
86
+ def terms
87
+ first('userestrict_ssm')
88
+ end
89
+
90
+ # Restrictions for component sidebar
91
+ def parent_restrictions
92
+ first('parent_access_restrict_ssm')
93
+ end
94
+
95
+ # Terms for component sidebar
96
+ def parent_terms
97
+ first('parent_access_terms_ssm')
98
+ end
99
+
100
+ def digital_objects
101
+ digital_objects_field = fetch('digital_objects_ssm', [])
102
+ return [] if digital_objects_field.blank?
103
+
104
+ digital_objects_field.map do |object|
105
+ Arclight::DigitalObject.from_json(object)
106
+ end
107
+ end
108
+
109
+ def containers
110
+ # note that .titlecase strips punctuation, like hyphens, we want to keep
111
+ fetch('containers_ssim', []).map(&:capitalize)
112
+ end
113
+
114
+ def normalized_title
115
+ first('normalized_title_ssm')
116
+ end
117
+
118
+ def normalized_date
119
+ first('normalized_date_ssm')
120
+ end
121
+
122
+ # @return [Array<String>] with embedded highlights using <em>...</em>
123
+ def highlights
124
+ highlight_response = response[:highlighting]
125
+ return if highlight_response.blank? ||
126
+ highlight_response[id].blank? ||
127
+ highlight_response[id][:text].blank?
128
+ highlight_response[id][:text]
129
+ end
130
+ end
131
+ end