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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arclight
2
- VERSION = '0.0.1'
4
+ VERSION = '0.1.0'
3
5
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'arclight/viewers/oembed'
4
+
5
+ module Arclight
6
+ ##
7
+ # Arclight::Viewer provides the ability to render a configured viewer
8
+ # The viewer class is configured through the Arclight::Engine configuration
9
+ # which allows an application to implement their own viewer class.
10
+ # This class will receive a SolrDocument and must implement to_partial_path.
11
+ # See Arclight::Viewers::OEmbed for an example implementation of a viewer.
12
+ class Viewer
13
+ def self.render(document)
14
+ new(document).render
15
+ end
16
+
17
+ def initialize(document)
18
+ @document = document
19
+ end
20
+
21
+ def render
22
+ renderer.render(
23
+ viewer_instance.to_partial_path,
24
+ layout: false,
25
+ locals: { viewer: viewer_instance }
26
+ )
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :document
32
+
33
+ def viewer_instance
34
+ viewer_class.new(document)
35
+ end
36
+
37
+ def viewer_class
38
+ Arclight::Engine.config.viewer_class
39
+ end
40
+
41
+ def renderer
42
+ ApplicationController.renderer
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ module Viewers
5
+ ##
6
+ # A class to represent and render an oEmbed viewer.
7
+ # This defines a partial to be rendered and can
8
+ # apply any required logic to help map necessary
9
+ # document attributes for viewer instantiation
10
+ #
11
+ # This viewer assumes that the resource itself is requestable
12
+ # according the CORS policy of the site. This is because we
13
+ # fetch the resource and look for a link[rel="alternate"] with
14
+ # a type="application/json+oembed". Th oEmbed endpoint described
15
+ # with that link tag should be an oEmbed RICH type, and return
16
+ # the viewer HTML in the html key of the JSON response.
17
+ class OEmbed
18
+ attr_reader :document
19
+
20
+ def initialize(document)
21
+ @document = document
22
+ end
23
+
24
+ def resources
25
+ document.digital_objects
26
+ end
27
+
28
+ def embeddable?(resource)
29
+ resource == resources.first && embeddable_resources.include?(resource)
30
+ end
31
+
32
+ def attributes_for(resource)
33
+ return {} unless embeddable?(resource)
34
+ { class: 'al-oembed-viewer', 'data-arclight-oembed': true, 'data-arclight-oembed-url': resource.href }
35
+ end
36
+
37
+ def to_partial_path
38
+ 'arclight/viewers/_oembed'
39
+ end
40
+
41
+ private
42
+
43
+ def exclude_patterns
44
+ Arclight::Engine.config.oembed_resource_exclude_patterns
45
+ end
46
+
47
+ def embeddable_resources
48
+ document.digital_objects.reject do |object|
49
+ exclude_patterns.any? do |pattern|
50
+ object.href =~ pattern
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arclight
4
+ # A range of years that handles gaps, such as [1999, 2000, 2002].
5
+ # Primary usage is:
6
+ # ```
7
+ # range = YearRange.new('1999/2004')
8
+ # range.years => [1999, 2000, 2001, 2002, 2003, 2004]
9
+ # range.to_s => '1999-2004'
10
+ # range << range.parse_ranges(['2010/2010'])
11
+ # range.years => [1999, 2000, 2001, 2002, 2003, 2004, 2010]
12
+ # range.to_s => '1999-2004, 2010'
13
+ # ```
14
+ class YearRange
15
+ attr_accessor :years
16
+
17
+ # @param [Array<String>] `dates` in the form YYYY/YYYY
18
+ def initialize(dates = nil)
19
+ @years = []
20
+ self << parse_ranges(dates) if dates.present?
21
+ self
22
+ end
23
+
24
+ # @return [String] a concise, human-readable version of the year range, including gaps
25
+ def to_s
26
+ return if years.empty?
27
+ return to_s_for_streak(years) unless gaps?
28
+ to_s_with_gaps
29
+ end
30
+
31
+ # @param [Array<Integer>] `other` the set of years to add
32
+ def <<(other)
33
+ return self if other.blank?
34
+ @years |= other # will remove duplicates
35
+ @years.sort!
36
+ self
37
+ end
38
+
39
+ # @param [String] `dates` in the form YYYY/YYYY
40
+ # @return [Array<Integer>] the set of years in the given range
41
+ def parse_range(dates)
42
+ return if dates.blank?
43
+ start_year, end_year = dates.split('/').map { |date| to_year_from_iso8601(date) }
44
+ return [start_year] if end_year.blank?
45
+ raise ArgumentError, "Range is too large: #{dates}" if (end_year - start_year) > 1000
46
+ raise ArgumentError, "Range is inverted: #{dates}" unless start_year <= end_year
47
+ (start_year..end_year).to_a
48
+ end
49
+
50
+ # @param [Array<String>] `dates` in the form YYYY/YYYY
51
+ # @return [Array<Integer>] the set of years in the given range
52
+ def parse_ranges(dates)
53
+ dates.map { |date| parse_range(date) }.flatten.sort.uniq
54
+ end
55
+
56
+ # @param [String] `date` a date in one of these formats:
57
+ # YYYY, YYYY-MM, YYYY-MM-DD, and YYYYMMDD
58
+ def to_year_from_iso8601(date)
59
+ return if date.blank?
60
+ date.split('-').first[0..3].to_i # Time.parse doesn't work here
61
+ end
62
+
63
+ # @return [Boolean] are there gaps between the years, such as 1999, 2000, 2002?
64
+ def gaps?
65
+ return false if years.blank?
66
+ (years.min..years.max).to_a != years
67
+ end
68
+
69
+ private
70
+
71
+ # Deals with making a human-readable range for years with 1 or more gaps.
72
+ # It involves detection of streaks between the gaps.
73
+ # @return [String] 1999-2000, 2002 for 1999, 2000, 2002
74
+ def to_s_with_gaps # rubocop: disable Metrics/AbcSize, Metrics/MethodLength
75
+ raise ArgumentError if years.blank? || years.length < 2
76
+ results = []
77
+ streak = [years[0]]
78
+ i = streak.first
79
+ years[1..-1].each do |j|
80
+ i += 1
81
+ if i == j
82
+ streak << j
83
+ else # we have a gap
84
+ results << if streak.length == 1
85
+ streak.first.to_s
86
+ else
87
+ to_s_for_streak(streak)
88
+ end
89
+ streak = [j]
90
+ i = j
91
+ end
92
+ end
93
+ results << to_s_for_streak(streak)
94
+ results.join(', ')
95
+ end
96
+
97
+ def to_s_for_streak(streak)
98
+ return streak.min.to_s if streak.min == streak.max
99
+ [streak.min, streak.max].map(&:to_s).join('-')
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ module Arclight
6
+ ##
7
+ # Arclight install generator
8
+ class Install < Rails::Generators::Base
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ def create_blacklight_catalog
12
+ remove_file 'app/controllers/catalog_controller.rb'
13
+ copy_file 'catalog_controller.rb', 'app/controllers/catalog_controller.rb'
14
+ end
15
+
16
+ def include_arclight_solrdocument
17
+ inject_into_file 'app/models/solr_document.rb', after: 'include Blacklight::Solr::Document' do
18
+ "\n include Arclight::SolrDocument"
19
+ end
20
+ end
21
+
22
+ def install_blacklight_range_limit
23
+ generate 'blacklight_range_limit:install'
24
+ end
25
+
26
+ def add_custom_routes
27
+ inject_into_file 'config/routes.rb', after: "mount Blacklight::Engine => '/'" do
28
+ "\n mount Arclight::Engine => '/'\n"
29
+ end
30
+ end
31
+
32
+ def assets
33
+ copy_file 'arclight.scss', 'app/assets/stylesheets/arclight.scss'
34
+ copy_file 'arclight.js', 'app/assets/javascripts/arclight.js'
35
+ inject_into_file 'app/assets/javascripts/application.js', after: '//= require blacklight/blacklight' do
36
+ "\n//= require bootstrap/scrollspy\n" \
37
+ "\n//= require bootstrap/tab\n"
38
+ end
39
+ end
40
+
41
+ def add_arclight_search_behavior
42
+ inject_into_file 'app/models/search_builder.rb', after: 'include Blacklight::Solr::SearchBuilderBehavior' do
43
+ "\n include Arclight::SearchBehavior"
44
+ end
45
+ end
46
+
47
+ def solr_config
48
+ directory '../../../../solr', 'solr', force: true
49
+ end
50
+
51
+ def add_repository_config
52
+ copy_file 'config/repositories.yml' unless File.exist?('config/repositories.yml')
53
+ end
54
+
55
+ def add_download_config
56
+ copy_file 'config/downloads.yml' unless File.exist?('config/downloads.yml')
57
+ end
58
+
59
+ def modify_blacklight_yml
60
+ gsub_file 'config/locales/blacklight.en.yml', "application_name: 'Blacklight'", "application_name: 'Arclight'"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,2 @@
1
+ //= require arclight/arclight
2
+ //= require stickyfill
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require arclight/application
3
+ */
@@ -0,0 +1,347 @@
1
+ # frozen_string_literal: true
2
+ class CatalogController < ApplicationController
3
+
4
+ include Blacklight::Catalog
5
+ include Arclight::Catalog
6
+ include Arclight::FieldConfigHelpers
7
+
8
+ configure_blacklight do |config|
9
+ ## Class for sending and receiving requests from a search index
10
+ # config.repository_class = Blacklight::Solr::Repository
11
+ #
12
+ ## Class for converting Blacklight's url parameters to into request parameters for the search index
13
+ # config.search_builder_class = ::SearchBuilder
14
+ #
15
+ ## Model that maps search index responses to the blacklight response model
16
+ # config.response_model = Blacklight::Solr::Response
17
+
18
+ ## Default parameters to send to solr for all search-like requests. See also SearchBuilder#processed_parameters
19
+ config.default_solr_params = {
20
+ rows: 10
21
+ }
22
+
23
+ # solr path which will be added to solr base url before the other solr params.
24
+ #config.solr_path = 'select'
25
+
26
+ # items to show per page, each number in the array represent another option to choose from.
27
+ #config.per_page = [10,20,50,100]
28
+
29
+ ## Default parameters to send on single-document requests to Solr. These settings are the Blackligt defaults (see SearchHelper#solr_doc_params) or
30
+ ## parameters included in the Blacklight-jetty document requestHandler.
31
+ #
32
+ #config.default_document_solr_params = {
33
+ # qt: 'document',
34
+ # ## These are hard-coded in the blacklight 'document' requestHandler
35
+ # # fl: '*',
36
+ # # rows: 1,
37
+ # # q: '{!term f=id v=$id}'
38
+ #}
39
+
40
+ # solr field configuration for search results/index views
41
+ config.index.title_field = 'normalized_title_ssm'
42
+ config.index.display_type_field = 'level_ssm'
43
+ #config.index.thumbnail_field = 'thumbnail_path_ss'
44
+
45
+ # solr field configuration for document/show views
46
+ #config.show.title_field = 'title_display'
47
+ #config.show.display_type_field = 'format'
48
+ #config.show.thumbnail_field = 'thumbnail_path_ss'
49
+
50
+ # solr fields that will be treated as facets by the blacklight application
51
+ # The ordering of the field names is the order of the display
52
+ #
53
+ # Setting a limit will trigger Blacklight's 'more' facet values link.
54
+ # * If left unset, then all facet values returned by solr will be displayed.
55
+ # * If set to an integer, then "f.somefield.facet.limit" will be added to
56
+ # solr request, with actual solr request being +1 your configured limit --
57
+ # you configure the number of items you actually want _displayed_ in a page.
58
+ # * If set to 'true', then no additional parameters will be sent to solr,
59
+ # but any 'sniffed' request limit parameters will be used for paging, with
60
+ # paging at requested limit -1. Can sniff from facet.limit or
61
+ # f.specific_field.facet.limit solr request params. This 'true' config
62
+ # can be used if you set limits in :default_solr_params, or as defaults
63
+ # on the solr side in the request handler itself. Request handler defaults
64
+ # sniffing requires solr requests to be made with "echoParams=all", for
65
+ # app code to actually have it echo'd back to see it.
66
+ #
67
+ # :show may be set to false if you don't want the facet to be drawn in the
68
+ # facet bar
69
+ #
70
+ # set :index_range to true if you want the facet pagination view to have facet prefix-based navigation
71
+ # (useful when user clicks "more" on a large facet and wants to navigate alphabetically across a large set of results)
72
+ # :index_range can be an array or range of prefixes that will be used to create the navigation (note: It is case sensitive when searching values)
73
+
74
+ config.add_facet_field 'collection_sim', label: 'Collection'
75
+ config.add_facet_field 'creator_ssim', label: 'Creator'
76
+ config.add_facet_field 'creators_ssim', label: 'Creator', show: false
77
+ config.add_facet_field 'date_range_sim', label: 'Date range', range: true
78
+ config.add_facet_field 'level_sim', label: 'Level'
79
+ config.add_facet_field 'names_ssim', label: 'Names'
80
+ config.add_facet_field 'repository_sim', label: 'Repository'
81
+ config.add_facet_field 'geogname_sim', label: 'Place'
82
+ config.add_facet_field 'places_ssim', label: 'Places', show:false
83
+ config.add_facet_field 'access_subjects_ssim', label: 'Subject'
84
+
85
+ # Have BL send all facet field names to Solr, which has been the default
86
+ # previously. Simply remove these lines if you'd rather use Solr request
87
+ # handler defaults, or have no facets.
88
+ config.add_facet_fields_to_solr_request!
89
+
90
+ # solr fields to be displayed in the index (search results) view
91
+ # The ordering of the field names is the order of the display
92
+ config.add_index_field 'unitid_ssm', label: 'Unit ID'
93
+ config.add_index_field 'repository_ssm', label: 'Repository'
94
+ config.add_index_field 'normalized_date_ssm', label: 'Date'
95
+ config.add_index_field 'creator_ssm', label: 'Creator'
96
+ config.add_index_field 'language_ssm', label: 'Language'
97
+ config.add_index_field 'scopecontent_ssm', label: 'Scope Content'
98
+ config.add_index_field 'extent_ssm', label: 'Physical Description'
99
+ config.add_index_field 'accessrestrict_ssm', label: 'Conditions Governing Access'
100
+ config.add_index_field 'collection_ssm', label: 'Collection Title'
101
+ config.add_index_field 'geogname_ssm', label: 'Place'
102
+
103
+ config.add_facet_field 'has_online_content_ssim', label: 'Access', query: {
104
+ online: { label: 'Online access', fq: 'has_online_content_ssim:true' }
105
+ }
106
+
107
+ # solr fields to be displayed in the show (single result) view
108
+ # The ordering of the field names is the order of the display
109
+
110
+ # "fielded" search configuration. Used by pulldown among other places.
111
+ # For supported keys in hash, see rdoc for Blacklight::SearchFields
112
+ #
113
+ # Search fields will inherit the :qt solr request handler from
114
+ # config[:default_solr_parameters], OR can specify a different one
115
+ # with a :qt key/value. Below examples inherit, except for subject
116
+ # that specifies the same :qt as default for our own internal
117
+ # testing purposes.
118
+ #
119
+ # The :key is what will be used to identify this BL search field internally,
120
+ # as well as in URLs -- so changing it after deployment may break bookmarked
121
+ # urls. A display label will be automatically calculated from the :key,
122
+ # or can be specified manually to be different.
123
+
124
+ # This one uses all the defaults set by the solr request handler. Which
125
+ # solr request handler? The one set in config[:default_solr_parameters][:qt],
126
+ # since we aren't specifying it otherwise.
127
+ config.add_search_field 'all_fields', label: 'All Fields' do |field|
128
+ field.include_in_simple_select = true
129
+ end
130
+
131
+ config.add_search_field 'within_collection' do |field|
132
+ field.include_in_simple_select = false
133
+ field.solr_parameters = {
134
+ fq: '-level_sim:Collection'
135
+ }
136
+ end
137
+
138
+ # Field-based searches. We have registered handlers in the Solr configuration
139
+ # so we have Blacklight use the `qt` parameter to invoke them
140
+ config.add_search_field 'keyword', label: 'Keyword' do |field|
141
+ field.qt = 'search' # default
142
+ end
143
+ config.add_search_field 'name', label: 'Name' do |field|
144
+ field.qt = 'name_search'
145
+ end
146
+ config.add_search_field 'place', label: 'Place' do |field|
147
+ field.qt = 'place_search'
148
+ end
149
+ config.add_search_field 'subject', label: 'Subject' do |field|
150
+ field.qt = 'subject_search'
151
+ end
152
+ config.add_search_field 'title', label: 'Title' do |field|
153
+ field.qt = 'title_search'
154
+ end
155
+
156
+ # "sort results by" select (pulldown)
157
+ # label in pulldown is followed by the name of the SOLR field to sort by and
158
+ # whether the sort is ascending or descending (it must be asc or desc
159
+ # except in the relevancy case).
160
+ config.add_sort_field 'score desc, title_sort asc', label: 'relevance'
161
+ config.add_sort_field 'date_sort asc', label: 'date (ascending)'
162
+ config.add_sort_field 'date_sort desc', label: 'date (descending)'
163
+ config.add_sort_field 'creator_sort asc', label: 'creator (A-Z)'
164
+ config.add_sort_field 'creator_sort desc', label: 'creator (Z-A)'
165
+ config.add_sort_field 'title_sort asc', label: 'title (A-Z)'
166
+ config.add_sort_field 'title_sort desc', label: 'title (Z-A)'
167
+
168
+ # If there are more than this many search results, no spelling ("did you
169
+ # mean") suggestion is offered.
170
+ config.spell_max = 5
171
+
172
+ # Configuration for autocomplete suggestor
173
+ config.autocomplete_enabled = true
174
+ config.autocomplete_path = 'suggest'
175
+
176
+ ##
177
+ # Arclight Configurations
178
+
179
+ config.show.document_presenter_class = Arclight::ShowPresenter
180
+ config.index.document_presenter_class = Arclight::IndexPresenter
181
+ ##
182
+ # Configuration for partials
183
+ config.index.partials.insert(0, :arclight_online_content_indicator)
184
+ config.index.partials.insert(0, :index_breadcrumb)
185
+ config.index.partials.insert(0, :arclight_document_index_header)
186
+
187
+ config.show.metadata_partials = [
188
+ :summary_field,
189
+ :access_field,
190
+ :background_field,
191
+ :related_field,
192
+ :indexed_terms_field
193
+ ]
194
+
195
+ config.show.context_sidebar_items = [
196
+ :in_person_field,
197
+ :terms_field,
198
+ :cite_field
199
+ ]
200
+
201
+ config.show.component_metadata_partials = [
202
+ :component_field,
203
+ :component_indexed_terms_field
204
+ ]
205
+
206
+ config.show.component_sidebar_items = [
207
+ :in_person_field,
208
+ :component_terms_field,
209
+ :cite_field
210
+ ]
211
+
212
+ # Component Show Page - Metadata Section
213
+ config.add_component_field 'containers', label: 'Containers', accessor: 'containers', separator_options: {
214
+ words_connector: ', ',
215
+ two_words_connector: ', ',
216
+ last_word_connector: ', '
217
+ }, if: lambda { |_context, _field_config, document|
218
+ document.containers.present?
219
+ }
220
+ config.add_component_field 'abstract_ssm', label: 'Abstract'
221
+ config.add_component_field 'extent_ssm', label: 'Extent'
222
+ config.add_component_field 'scopecontent_ssm', label: 'Scope and Content'
223
+ config.add_component_field 'accessrestrict_ssm', label: 'Restrictions'
224
+ config.add_component_field 'userestrict_ssm', label: 'Terms of Access'
225
+ config.add_component_field 'access_subjects_ssm', label: 'Subjects', separator_options: {
226
+ words_connector: '<br/>',
227
+ two_words_connector: '<br/>',
228
+ last_word_connector: '<br/>'
229
+ }
230
+
231
+ # Collection Show Page - Indexed Terms Section
232
+ config.add_component_indexed_terms_field 'access_subjects_ssim', label: 'Subjects', :link_to_facet => true, separator_options: {
233
+ words_connector: '<br/>',
234
+ two_words_connector: '<br/>',
235
+ last_word_connector: '<br/>'
236
+ }
237
+
238
+ config.add_component_indexed_terms_field 'names_ssim', label: 'Names', separator_options: {
239
+ words_connector: '<br/>',
240
+ two_words_connector: '<br/>',
241
+ last_word_connector: '<br/>'
242
+ }, helper_method: :link_to_name_facet
243
+
244
+ config.add_component_indexed_terms_field 'places_ssim', label: 'Places', :link_to_facet => true, separator_options: {
245
+ words_connector: '<br/>',
246
+ two_words_connector: '<br/>',
247
+ last_word_connector: '<br/>'
248
+ }
249
+
250
+ # Component Show Page Sidebar - Terms and Condition Section
251
+ config.add_component_terms_field 'parent_access_restrict_ssm', label: 'Restrictions'
252
+ config.add_component_terms_field 'parent_access_terms_ssm', label: 'Terms of Access'
253
+
254
+ # Collection Show Page - Summary Section
255
+ config.add_summary_field 'creators_ssim', label: 'Creator', :link_to_facet => true
256
+ config.add_summary_field 'abstract_ssm', label: 'Abstract'
257
+ config.add_summary_field 'extent_ssm', label: 'Extent'
258
+ config.add_summary_field 'language_ssm', label: 'Language'
259
+ config.add_summary_field 'prefercite_ssm', label: 'Preferred citation'
260
+
261
+ # Collection Show Page - In Person Section
262
+ config.add_in_person_field 'id', if: :before_you_visit_note_present, label: 'Before you visit', helper_method: :context_sidebar_visit_note # Using ID because we know it will always exist
263
+ config.add_in_person_field 'containers_ssim', if: :request_config_present, label: 'Request', helper_method: :context_sidebar_containers_request
264
+ config.add_in_person_field 'repository_ssm', if: :repository_config_present, label: 'Location of this collection', helper_method: :context_sidebar_repository
265
+
266
+ # Collection Show Page - Terms and Condition Section
267
+ config.add_terms_field 'accessrestrict_ssm', label: 'Restrictions'
268
+ config.add_terms_field 'userestrict_ssm', label: 'Terms of Access'
269
+
270
+ # Collection Show Page - How to Cite Section
271
+ config.add_cite_field 'prefercite_ssm', label: 'Preferred citation'
272
+
273
+ # Collection Show Page - Access Section
274
+ config.add_access_field 'accessrestrict_ssm', label: 'Conditions Governing Access', helper_method: :paragraph_separator
275
+ config.add_access_field 'userestrict_ssm', label: 'Terms Of Use', helper_method: :paragraph_separator
276
+
277
+ # Collection Show Page - Background Section
278
+ config.add_background_field 'scopecontent_ssm', label: 'Scope and Content', helper_method: :paragraph_separator
279
+ config.add_background_field 'bioghist_ssm', label: 'Biographical / Historical', helper_method: :paragraph_separator
280
+ config.add_background_field 'acqinfo_ssm', label: 'Acquisition information', helper_method: :paragraph_separator
281
+ config.add_background_field 'appraisal_ssm', label: 'Appraisal information', helper_method: :paragraph_separator
282
+ config.add_background_field 'custodhist_ssm', label: 'Custodial history', helper_method: :paragraph_separator
283
+ config.add_background_field 'processinfo_ssm', label: 'Processing information', helper_method: :paragraph_separator
284
+
285
+ # Collection Show Page - Related Section
286
+ config.add_related_field 'relatedmaterial_ssm', label: 'Related material', helper_method: :paragraph_separator
287
+ config.add_related_field 'separatedmaterial_ssm', label: 'Separated material', helper_method: :paragraph_separator
288
+ config.add_related_field 'otherfindaid_ssm', label: 'Other finding aids', helper_method: :paragraph_separator
289
+ config.add_related_field 'altformavail_ssm', label: 'Alternative form available', helper_method: :paragraph_separator
290
+ config.add_related_field 'originalsloc_ssm', label: 'Location of originals', helper_method: :paragraph_separator
291
+
292
+ # Collection Show Page - Indexed Terms Section
293
+ config.add_indexed_terms_field 'access_subjects_ssim', label: 'Subjects', :link_to_facet => true, separator_options: {
294
+ words_connector: '<br/>',
295
+ two_words_connector: '<br/>',
296
+ last_word_connector: '<br/>'
297
+ }
298
+
299
+ config.add_indexed_terms_field 'names_coll_ssim', label: 'Names', separator_options: {
300
+ words_connector: '<br/>',
301
+ two_words_connector: '<br/>',
302
+ last_word_connector: '<br/>'
303
+ }, helper_method: :link_to_name_facet
304
+
305
+ config.add_indexed_terms_field 'places_ssim', label: 'Places', :link_to_facet => true, separator_options: {
306
+ words_connector: '<br/>',
307
+ two_words_connector: '<br/>',
308
+ last_word_connector: '<br/>'
309
+ }
310
+
311
+ # Collection Show Page - Administrative Information Section
312
+ config.add_admin_info_field 'acqinfo_ssm', label: 'Acquisition information'
313
+ config.add_admin_info_field 'appraisal_ssm', label: 'Appraisal information'
314
+ config.add_admin_info_field 'custodhist_ssm', label: 'Custodial history'
315
+ config.add_admin_info_field 'processinfo_ssm', label: 'Processing information'
316
+
317
+ # Remove unused show document actions
318
+ %i[citation email sms].each do |action|
319
+ config.view_config(:show).document_actions.delete(action)
320
+ end
321
+
322
+ # Insert the breadcrumbs at the beginning
323
+ config.show.partials.unshift(:show_breadcrumbs)
324
+
325
+ ##
326
+ # Hierarchy Index View
327
+ config.view.hierarchy
328
+ config.view.hierarchy.display_control = false
329
+ config.view.hierarchy.partials = config.index.partials.dup
330
+ config.view.hierarchy.partials.delete(:index_breadcrumb)
331
+
332
+ ##
333
+ # Hierarchy Index View
334
+ config.view.online_contents
335
+ config.view.online_contents.display_control = false
336
+ config.view.online_contents.partials = config.view.hierarchy.partials.dup
337
+
338
+ # #
339
+ # Compact index view
340
+ config.view.compact
341
+ config.view.compact.partials = %i[arclight_index_compact]
342
+
343
+ ##
344
+ # Extra actions
345
+ config.add_results_document_tool :google_form, partial: 'arclight/requests/google_form', if: :item_requestable?
346
+ end
347
+ end