blacklight-spotlight 1.5.1 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -3
- data/app/assets/javascripts/spotlight/translation_progress.js +23 -0
- data/app/assets/stylesheets/spotlight/_spotlight.scss +2 -0
- data/app/assets/stylesheets/spotlight/_translations.scss +47 -0
- data/app/assets/stylesheets/spotlight/_utilities.scss +3 -0
- data/app/assets/stylesheets/spotlight/_variables.scss +5 -0
- data/app/controllers/concerns/spotlight/controller.rb +12 -1
- data/app/controllers/spotlight/about_pages_controller.rb +6 -0
- data/app/controllers/spotlight/browse_controller.rb +1 -1
- data/app/controllers/spotlight/catalog_controller.rb +6 -1
- data/app/controllers/spotlight/exhibits_controller.rb +10 -2
- data/app/controllers/spotlight/feature_pages_controller.rb +6 -0
- data/app/controllers/spotlight/filters_controller.rb +2 -2
- data/app/controllers/spotlight/home_pages_controller.rb +10 -0
- data/app/controllers/spotlight/languages_controller.rb +46 -0
- data/app/controllers/spotlight/pages_controller.rb +57 -3
- data/app/controllers/spotlight/solr_controller.rb +3 -3
- data/app/controllers/spotlight/translations_controller.rb +34 -0
- data/app/helpers/spotlight/application_helper.rb +1 -0
- data/app/helpers/spotlight/languages_helper.rb +33 -0
- data/app/helpers/spotlight/translations_helper.rb +13 -0
- data/app/models/concerns/spotlight/custom_translation_extension.rb +4 -0
- data/app/models/concerns/spotlight/translatables.rb +30 -0
- data/app/models/spotlight/ability.rb +5 -2
- data/app/models/spotlight/about_page.rb +1 -1
- data/app/models/spotlight/exhibit.rb +14 -6
- data/app/models/spotlight/feature_page.rb +1 -2
- data/app/models/spotlight/home_page.rb +1 -3
- data/app/models/spotlight/language.rb +24 -0
- data/app/models/spotlight/main_navigation.rb +12 -0
- data/app/models/spotlight/page.rb +53 -1
- data/app/models/spotlight/resources/upload.rb +6 -1
- data/app/models/spotlight/search.rb +4 -0
- data/app/services/spotlight/clone_translated_page_from_locale.rb +32 -0
- data/app/views/_user_util_links.html.erb +1 -0
- data/app/views/devise/mailer/invitation_instructions.html.erb +2 -2
- data/app/views/layouts/spotlight/spotlight.html.erb +2 -2
- data/app/views/shared/_curated_features_navbar.html.erb +2 -2
- data/app/views/spotlight/about_pages/_sidebar.html.erb +1 -1
- data/app/views/spotlight/admin_users/index.html.erb +1 -1
- data/app/views/spotlight/catalog/_edit_default.html.erb +1 -1
- data/app/views/spotlight/exhibits/_export.html.erb +1 -1
- data/app/views/spotlight/exhibits/_form.html.erb +1 -1
- data/app/views/spotlight/exhibits/_import.html.erb +2 -1
- data/app/views/spotlight/exhibits/_languages.html.erb +56 -0
- data/app/views/spotlight/exhibits/edit.html.erb +11 -5
- data/app/views/spotlight/feature_pages/_sidebar.html.erb +1 -1
- data/app/views/spotlight/filters/_form.html.erb +2 -1
- data/app/views/spotlight/resources/upload/_form.html.erb +1 -1
- data/app/views/spotlight/shared/_curation_sidebar.html.erb +5 -0
- data/app/views/spotlight/shared/_locale_picker.html.erb +14 -0
- data/app/views/spotlight/translations/_browse_categories.html.erb +67 -0
- data/app/views/spotlight/translations/_general.html.erb +176 -0
- data/app/views/spotlight/translations/_metadata.html.erb +67 -0
- data/app/views/spotlight/translations/_page.html.erb +45 -0
- data/app/views/spotlight/translations/_pages.html.erb +37 -0
- data/app/views/spotlight/translations/_pages_table.html.erb +15 -0
- data/app/views/spotlight/translations/_search_fields.html.erb +97 -0
- data/app/views/spotlight/translations/edit.html.erb +55 -0
- data/config/i18n-tasks.yml +81 -0
- data/config/locales/devise.en.yml +2 -1
- data/config/locales/spotlight.en.yml +657 -614
- data/config/routes.rb +19 -1
- data/db/migrate/20180308203409_create_spotlight_languages.rb +12 -0
- data/db/migrate/20180403130857_translation_uniqueness.rb +5 -0
- data/db/migrate/20180405044000_add_locale_to_pages.rb +6 -0
- data/db/migrate/20180406212516_add_default_locale_reference_to_spotlight_pages.rb +7 -0
- data/lib/generators/spotlight/templates/catalog_controller.rb +2 -2
- data/lib/generators/spotlight/templates/config/initializers/spotlight_initializer.rb +14 -4
- data/lib/generators/spotlight/templates/config/initializers/translation.rb +4 -2
- data/lib/migration/page_language.rb +27 -0
- data/lib/spotlight/engine.rb +32 -4
- data/lib/spotlight/upload_field_config.rb +27 -0
- data/lib/spotlight/version.rb +1 -1
- data/lib/tasks/spotlight_tasks.rake +6 -0
- data/spec/controllers/spotlight/about_pages_controller_spec.rb +67 -1
- data/spec/controllers/spotlight/feature_pages_controller_spec.rb +50 -0
- data/spec/controllers/spotlight/filters_controller_spec.rb +4 -4
- data/spec/controllers/spotlight/home_pages_controller_spec.rb +25 -0
- data/spec/controllers/spotlight/languages_controller_spec.rb +66 -0
- data/spec/controllers/spotlight/pages_controller_spec.rb +45 -0
- data/spec/controllers/spotlight/solr_controller_spec.rb +1 -1
- data/spec/controllers/spotlight/translations_controller_spec.rb +67 -0
- data/spec/examples.txt +1171 -1281
- data/spec/factories/exhibits.rb +1 -1
- data/spec/factories/language.rb +6 -0
- data/spec/factories/main_navigation.rb +7 -0
- data/spec/factories/searches.rb +1 -0
- data/spec/factories/tags.rb +1 -0
- data/spec/features/exhibits/language_create_edit_spec.rb +53 -0
- data/spec/features/exhibits/translation_editing_spec.rb +397 -0
- data/spec/features/javascript/locale_selector_spec.rb +61 -0
- data/spec/helpers/spotlight/languages_helper_spec.rb +73 -0
- data/spec/helpers/spotlight/translations_helper_spec.rb +16 -0
- data/spec/i18n_spec.rb +29 -0
- data/spec/lib/migration/page_language_spec.rb +21 -0
- data/spec/lib/spotlight/upload_field_config_spec.rb +24 -0
- data/spec/models/spotlight/ability_spec.rb +17 -4
- data/spec/models/spotlight/exhibit_spec.rb +49 -0
- data/spec/models/spotlight/language_spec.rb +41 -0
- data/spec/models/spotlight/page_spec.rb +109 -0
- data/spec/models/translation_spec.rb +11 -0
- data/spec/services/spotlight/clone_translated_page_from_locale_spec.rb +29 -0
- data/spec/spec_helper.rb +1 -13
- data/spec/support/disable_friendly_id_deprecation_warnings.rb +7 -6
- data/spec/test_app_templates/Gemfile.extra +3 -0
- data/spec/test_app_templates/catalog_controller.rb +31 -31
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +9 -6
- data/spec/views/spotlight/contacts/edit.html.erb_spec.rb +13 -0
- data/spec/views/spotlight/exhibits/_form.html.erb_spec.rb +33 -0
- data/spec/views/spotlight/exhibits/edit.html.erb_spec.rb +4 -1
- data/spec/views/spotlight/resources/_external_resources_form.html.erb_spec.rb +13 -0
- data/spec/views/spotlight/resources/new.html.erb_spec.rb +10 -4
- data/spec/views/spotlight/translations/_page.html.erb_spec.rb +75 -0
- metadata +88 -28
- data/app/assets/javascripts/spotlight/sir-trevor.js +0 -0
- data/app/views/shared/_share_follow.html.erb +0 -5
- data/config/locales/social_share_button.en.yml +0 -18
@@ -21,10 +21,10 @@ module Spotlight
|
|
21
21
|
|
22
22
|
repository.connection.update params: { commitWithin: 500 }, data: data.to_json, headers: { 'Content-Type' => 'application/json' } unless data.empty?
|
23
23
|
|
24
|
-
if
|
25
|
-
|
24
|
+
if params[:resources_json_upload]
|
25
|
+
redirect_back fallback_location: exhibit_resources_path(@exhibit)
|
26
26
|
else
|
27
|
-
|
27
|
+
head :ok
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Spotlight
|
2
|
+
##
|
3
|
+
# Base CRUD controller for translations
|
4
|
+
class TranslationsController < Spotlight::ApplicationController
|
5
|
+
before_action :authenticate_user!, :set_language, :set_tab
|
6
|
+
load_and_authorize_resource :exhibit, class: Spotlight::Exhibit
|
7
|
+
|
8
|
+
def edit; end
|
9
|
+
|
10
|
+
def update
|
11
|
+
if current_exhibit.update(exhibit_params)
|
12
|
+
I18n.reload! # reload since we're memoizing
|
13
|
+
notice = t(:'helpers.submit.spotlight_default.updated', model: current_exhibit.class.model_name.human.downcase)
|
14
|
+
redirect_to edit_exhibit_translations_path(current_exhibit, language: @language, tab: @tab), notice: notice
|
15
|
+
else
|
16
|
+
render 'edit'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def exhibit_params
|
23
|
+
params.require(:exhibit).permit(translations_attributes: [:id, :locale, :key, :value])
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_language
|
27
|
+
@language = params[:language] || current_exhibit.available_locales.first
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_tab
|
31
|
+
@tab = params[:tab]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Spotlight
|
2
|
+
##
|
3
|
+
# Helpers for the Language form and UI elements
|
4
|
+
module LanguagesHelper
|
5
|
+
def add_exhibit_language_dropdown_options
|
6
|
+
non_default_or_current_exhibit_languages = I18n.available_locales.reject do |locale|
|
7
|
+
locale == I18n.default_locale || current_exhibit.available_locales.include?(locale.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
non_default_or_current_exhibit_languages_with_labels = non_default_or_current_exhibit_languages.map do |locale|
|
11
|
+
[t("locales.#{locale.downcase}"), locale]
|
12
|
+
end
|
13
|
+
|
14
|
+
non_default_or_current_exhibit_languages_with_labels.sort_by { |label, _locale| label }
|
15
|
+
end
|
16
|
+
|
17
|
+
def locale_selecter_dropown_options
|
18
|
+
languages = current_exhibit.languages.accessible_by(current_ability).to_a << Spotlight::Language.default_instance
|
19
|
+
|
20
|
+
# String#casecmp returns 0 when the two strings compared are identical (ignoring case)
|
21
|
+
languages.reject { |language| language.locale.to_s.casecmp(I18n.locale.to_s).zero? }.sort_by(&:to_native)
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Can determine whether the current page is using the application's default
|
26
|
+
# locale
|
27
|
+
# @return [Boolean]
|
28
|
+
def default_language?
|
29
|
+
return true unless params[:locale]
|
30
|
+
params[:locale].to_s == I18n.default_locale.to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Spotlight
|
2
|
+
##
|
3
|
+
# Helper module for the Translations admin UI
|
4
|
+
module TranslationsHelper
|
5
|
+
def non_custom_metadata_fields
|
6
|
+
custom_field_keys = current_exhibit.custom_fields.pluck(:field)
|
7
|
+
|
8
|
+
current_exhibit.blacklight_config.show_fields.reject do |key, _|
|
9
|
+
custom_field_keys.include?(key)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -8,6 +8,10 @@ module Spotlight
|
|
8
8
|
included do
|
9
9
|
default_scope { where(exhibit: current_exhibit) }
|
10
10
|
belongs_to :exhibit, class_name: 'Spotlight::Exhibit', inverse_of: :translations
|
11
|
+
|
12
|
+
before_validation do
|
13
|
+
mark_for_destruction if value.blank?
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
class_methods do
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Spotlight
|
2
|
+
# Mixin for adding translatable ActiveRecord accessors
|
3
|
+
module Translatables
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
class_methods do
|
7
|
+
def translates(*attr_names)
|
8
|
+
attr_names.map(&:to_sym)
|
9
|
+
attr_names.map(&method(:define_translated_attr_reader))
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Set up a reader for the specified attribute that uses the I18n backend,
|
14
|
+
# and defaults to the ActiveRecord value
|
15
|
+
def define_translated_attr_reader(attr_name)
|
16
|
+
define_method(:"#{attr_name}") do
|
17
|
+
I18n.translate(attr_name, scope: slug, default: attr_translation(attr_name))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
##
|
25
|
+
# Will return the default ActiveRecord value for the value
|
26
|
+
def attr_translation(attr_name)
|
27
|
+
self[attr_name]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -14,7 +14,7 @@ module Spotlight
|
|
14
14
|
|
15
15
|
# exhibit admin
|
16
16
|
can [:update, :import, :export, :destroy], Spotlight::Exhibit, id: user.admin_roles.pluck(:resource_id)
|
17
|
-
can :manage, [Spotlight::BlacklightConfiguration, Spotlight::ContactEmail], exhibit_id: user.admin_roles.pluck(:resource_id)
|
17
|
+
can :manage, [Spotlight::BlacklightConfiguration, Spotlight::ContactEmail, Spotlight::Language], exhibit_id: user.admin_roles.pluck(:resource_id)
|
18
18
|
can :manage, Spotlight::Role, resource_id: user.admin_roles.pluck(:resource_id), resource_type: 'Spotlight::Exhibit'
|
19
19
|
|
20
20
|
can :manage, PaperTrail::Version if user.roles.any?
|
@@ -26,11 +26,13 @@ module Spotlight
|
|
26
26
|
Spotlight::Resource,
|
27
27
|
Spotlight::Page,
|
28
28
|
Spotlight::Contact,
|
29
|
-
Spotlight::CustomField
|
29
|
+
Spotlight::CustomField,
|
30
|
+
Translation
|
30
31
|
], exhibit_id: user.exhibit_roles.pluck(:resource_id)
|
31
32
|
|
32
33
|
can :manage, Spotlight::Lock, by: user
|
33
34
|
|
35
|
+
can :read, Spotlight::Language, exhibit_id: user.exhibit_roles.pluck(:resource_id)
|
34
36
|
can [:read, :curate, :tag], Spotlight::Exhibit, id: user.exhibit_roles.pluck(:resource_id)
|
35
37
|
|
36
38
|
# public
|
@@ -38,6 +40,7 @@ module Spotlight
|
|
38
40
|
can :read, Spotlight::Exhibit, published: true
|
39
41
|
can :read, Spotlight::Page, published: true
|
40
42
|
can :read, Spotlight::Search, published: true
|
43
|
+
can :read, Spotlight::Language, public: true
|
41
44
|
end
|
42
45
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
43
46
|
end
|
@@ -3,6 +3,6 @@ module Spotlight
|
|
3
3
|
# About pages
|
4
4
|
class AboutPage < Spotlight::Page
|
5
5
|
extend FriendlyId
|
6
|
-
friendly_id :title, use: [:slugged, :scoped, :finders, :history], scope: :exhibit
|
6
|
+
friendly_id :title, use: [:slugged, :scoped, :finders, :history], scope: [:exhibit, :locale]
|
7
7
|
end
|
8
8
|
end
|
@@ -6,6 +6,9 @@ module Spotlight
|
|
6
6
|
include Spotlight::ExhibitAnalytics
|
7
7
|
include Spotlight::ExhibitDefaults
|
8
8
|
include Spotlight::ExhibitDocuments
|
9
|
+
include Spotlight::Translatables
|
10
|
+
|
11
|
+
translates :title, :subtitle, :description
|
9
12
|
|
10
13
|
has_paper_trail
|
11
14
|
|
@@ -17,7 +20,7 @@ module Spotlight
|
|
17
20
|
|
18
21
|
extend FriendlyId
|
19
22
|
friendly_id :title, use: [:slugged, :finders]
|
20
|
-
validates :title, presence: true
|
23
|
+
validates :title, presence: true, if: -> { I18n.locale == I18n.default_locale }
|
21
24
|
validates :slug, uniqueness: true
|
22
25
|
validates :theme, inclusion: { in: Spotlight::Engine.config.exhibit_themes }, allow_blank: true
|
23
26
|
|
@@ -27,12 +30,12 @@ module Spotlight
|
|
27
30
|
serialize :facets, Array
|
28
31
|
|
29
32
|
# Note: friendly id associations need to be 'destroy'ed to reap the slug history
|
30
|
-
has_many :about_pages, extend: FriendlyId::FinderMethods
|
33
|
+
has_many :about_pages, -> { for_default_locale }, extend: FriendlyId::FinderMethods
|
31
34
|
has_many :attachments, dependent: :destroy
|
32
35
|
has_many :contact_emails, dependent: :delete_all # These are the contacts who get "Contact us" emails
|
33
36
|
has_many :contacts, dependent: :delete_all # These are the contacts who appear in the sidebar
|
34
37
|
has_many :custom_fields, dependent: :delete_all
|
35
|
-
has_many :feature_pages, extend: FriendlyId::FinderMethods
|
38
|
+
has_many :feature_pages, -> { for_default_locale }, extend: FriendlyId::FinderMethods
|
36
39
|
has_many :main_navigations, dependent: :delete_all
|
37
40
|
has_many :reindexing_log_entries, dependent: :destroy
|
38
41
|
has_many :resources
|
@@ -43,16 +46,17 @@ module Spotlight
|
|
43
46
|
has_many :pages, dependent: :destroy
|
44
47
|
has_many :filters, dependent: :delete_all
|
45
48
|
has_many :translations, class_name: 'I18n::Backend::ActiveRecord::Translation', dependent: :destroy, inverse_of: :exhibit
|
49
|
+
has_many :languages, dependent: :destroy
|
46
50
|
|
47
51
|
has_one :blacklight_configuration, class_name: 'Spotlight::BlacklightConfiguration', dependent: :delete
|
48
|
-
has_one :home_page
|
52
|
+
has_one :home_page, -> { for_default_locale }
|
49
53
|
|
50
54
|
belongs_to :site, optional: true
|
51
55
|
belongs_to :masthead, dependent: :destroy, optional: true
|
52
56
|
belongs_to :thumbnail, class_name: 'Spotlight::ExhibitThumbnail', dependent: :destroy, optional: true
|
53
57
|
|
54
|
-
accepts_nested_attributes_for :about_pages, :attachments, :contacts, :custom_fields, :feature_pages,
|
55
|
-
:main_navigations, :owned_taggings, :resources, :searches, :solr_document_sidecars
|
58
|
+
accepts_nested_attributes_for :about_pages, :attachments, :contacts, :custom_fields, :feature_pages, :languages,
|
59
|
+
:main_navigations, :owned_taggings, :pages, :resources, :searches, :solr_document_sidecars, :translations
|
56
60
|
accepts_nested_attributes_for :blacklight_configuration, :home_page, :filters, update_only: true
|
57
61
|
accepts_nested_attributes_for :masthead, :thumbnail, update_only: true, reject_if: proc { |attr| attr['iiif_tilesource'].blank? }
|
58
62
|
accepts_nested_attributes_for :contact_emails, reject_if: proc { |attr| attr['email'].blank? }
|
@@ -103,6 +107,10 @@ module Spotlight
|
|
103
107
|
@reindex_progress ||= ReindexProgress.new(current_reindexing_log_entry)
|
104
108
|
end
|
105
109
|
|
110
|
+
def available_locales
|
111
|
+
@available_locales ||= languages.pluck(:locale)
|
112
|
+
end
|
113
|
+
|
106
114
|
protected
|
107
115
|
|
108
116
|
def sanitize_description
|
@@ -3,7 +3,7 @@ module Spotlight
|
|
3
3
|
# Feature pages
|
4
4
|
class FeaturePage < Spotlight::Page
|
5
5
|
extend FriendlyId
|
6
|
-
friendly_id :title, use: [:slugged, :scoped, :finders, :history], scope: :exhibit
|
6
|
+
friendly_id :title, use: [:slugged, :scoped, :finders, :history], scope: [:exhibit, :locale]
|
7
7
|
|
8
8
|
has_many :child_pages, class_name: 'Spotlight::FeaturePage', inverse_of: :parent_page, foreign_key: 'parent_page_id'
|
9
9
|
belongs_to :parent_page, class_name: 'Spotlight::FeaturePage', optional: true
|
@@ -11,7 +11,6 @@ module Spotlight
|
|
11
11
|
accepts_nested_attributes_for :child_pages
|
12
12
|
|
13
13
|
belongs_to :thumbnail, class_name: 'Spotlight::FeaturedImage', dependent: :destroy, optional: true
|
14
|
-
accepts_nested_attributes_for :thumbnail, update_only: true, reject_if: proc { |attr| attr['iiif_tilesource'].blank? }
|
15
14
|
|
16
15
|
before_validation unless: :top_level_page? do
|
17
16
|
self.exhibit = top_level_page_or_self.exhibit
|
@@ -3,13 +3,11 @@ module Spotlight
|
|
3
3
|
# Exhibit home page
|
4
4
|
class HomePage < Spotlight::Page
|
5
5
|
extend FriendlyId
|
6
|
-
friendly_id :title, use: [:slugged, :scoped, :finders], scope: :exhibit
|
6
|
+
friendly_id :title, use: [:slugged, :scoped, :finders], scope: [:exhibit, :locale]
|
7
7
|
|
8
8
|
before_save :publish
|
9
9
|
before_create :default_content
|
10
10
|
|
11
|
-
accepts_nested_attributes_for :thumbnail, update_only: true, reject_if: proc { |attr| attr['iiif_tilesource'].blank? }
|
12
|
-
|
13
11
|
class << self
|
14
12
|
def default_title_text
|
15
13
|
I18n.t('spotlight.pages.index.home_pages.title')
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Spotlight
|
2
|
+
# A language for an exhibit
|
3
|
+
class Language < ActiveRecord::Base
|
4
|
+
belongs_to :exhibit
|
5
|
+
has_many :pages, ->(page) { where(locale: page.locale) }, through: :exhibit
|
6
|
+
has_many :translations, ->(translation) { where(locale: translation.locale) }, through: :exhibit
|
7
|
+
validates :locale, presence: true
|
8
|
+
|
9
|
+
# Doing this instead of dependent: :destroy because
|
10
|
+
# has_many :through can't associate a has_many reflection
|
11
|
+
after_destroy do
|
12
|
+
pages.map(&:destroy)
|
13
|
+
translations.map(&:destroy)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_native
|
17
|
+
Spotlight::Engine.config.i18n_locales[locale.downcase.to_sym] || ''
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.default_instance
|
21
|
+
new(locale: I18n.default_locale)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -2,11 +2,15 @@ module Spotlight
|
|
2
2
|
##
|
3
3
|
# Exhibit navbar links
|
4
4
|
class MainNavigation < ActiveRecord::Base
|
5
|
+
include Spotlight::Translatables
|
6
|
+
|
5
7
|
belongs_to :exhibit, touch: true
|
6
8
|
default_scope { order('weight ASC') }
|
7
9
|
scope :browse, -> { find_by(nav_type: 'browse') }
|
8
10
|
scope :about, -> { find_by(nav_type: 'about') }
|
11
|
+
scope :curated_features, -> { find_by(nav_type: 'curated_features') }
|
9
12
|
scope :displayable, -> { where(display: true) }
|
13
|
+
translates :label
|
10
14
|
|
11
15
|
def displayable?
|
12
16
|
display?
|
@@ -23,5 +27,13 @@ module Spotlight
|
|
23
27
|
def default_label
|
24
28
|
I18n.t(:"spotlight.main_navigation.#{nav_type}")
|
25
29
|
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
##
|
34
|
+
# Allows us to scope translations namespace.
|
35
|
+
def slug
|
36
|
+
['main_navigation', nav_type].join('.')
|
37
|
+
end
|
26
38
|
end
|
27
39
|
end
|
@@ -1,16 +1,23 @@
|
|
1
1
|
module Spotlight
|
2
2
|
##
|
3
3
|
# Base page class. See {Spotlight::AboutPage}, {Spotlight::FeaturePage}, {Spotlight::HomePage}
|
4
|
+
# rubocop:disable Metrics/ClassLength
|
4
5
|
class Page < ActiveRecord::Base
|
5
6
|
MAX_PAGES = 50
|
6
7
|
|
7
8
|
extend FriendlyId
|
8
|
-
friendly_id :title, use: [:slugged, :scoped, :finders, :history], scope: :exhibit
|
9
|
+
friendly_id :title, use: [:slugged, :scoped, :finders, :history], scope: [:exhibit, :locale]
|
9
10
|
|
10
11
|
belongs_to :exhibit, touch: true
|
11
12
|
belongs_to :created_by, class_name: Spotlight::Engine.config.user_class, optional: true
|
12
13
|
belongs_to :last_edited_by, class_name: Spotlight::Engine.config.user_class, optional: true
|
13
14
|
belongs_to :thumbnail, class_name: 'Spotlight::FeaturedImage', dependent: :destroy, optional: true
|
15
|
+
belongs_to :default_locale_page, class_name: 'Spotlight::Page', optional: true, inverse_of: :translated_pages
|
16
|
+
has_many :translated_pages,
|
17
|
+
class_name: 'Spotlight::Page',
|
18
|
+
foreign_key: :default_locale_page_id,
|
19
|
+
dependent: :destroy,
|
20
|
+
inverse_of: :default_locale_page
|
14
21
|
|
15
22
|
validates :weight, inclusion: { in: proc { 0..Spotlight::Page::MAX_PAGES } }
|
16
23
|
|
@@ -18,17 +25,23 @@ module Spotlight
|
|
18
25
|
scope :at_top_level, -> { where(parent_page_id: nil) }
|
19
26
|
scope :published, -> { where(published: true) }
|
20
27
|
scope :recent, -> { order('updated_at DESC').limit(10) }
|
28
|
+
scope :for_locale, ->(locale = I18n.locale) { unscope(where: :locale).where(locale: locale) }
|
29
|
+
scope :for_default_locale, -> { for_locale(I18n.default_locale) }
|
21
30
|
|
22
31
|
has_one :lock, as: :on, dependent: :destroy
|
23
32
|
sir_trevor_content :content
|
24
33
|
has_paper_trail
|
25
34
|
|
35
|
+
accepts_nested_attributes_for :thumbnail, update_only: true, reject_if: proc { |attr| attr['iiif_tilesource'].blank? }
|
36
|
+
|
26
37
|
# display_sidebar should be set to true by default
|
27
38
|
before_create do
|
28
39
|
self.content ||= [].to_json
|
29
40
|
self.display_sidebar = true
|
30
41
|
end
|
31
42
|
|
43
|
+
after_update :update_translated_pages_weights_and_parent_page
|
44
|
+
|
32
45
|
def content_changed!
|
33
46
|
@content = nil
|
34
47
|
end
|
@@ -74,6 +87,10 @@ module Spotlight
|
|
74
87
|
is_a? AboutPage
|
75
88
|
end
|
76
89
|
|
90
|
+
def home_page?
|
91
|
+
is_a? HomePage
|
92
|
+
end
|
93
|
+
|
77
94
|
def top_level_page?
|
78
95
|
try(:parent_page).blank?
|
79
96
|
end
|
@@ -93,5 +110,40 @@ module Spotlight
|
|
93
110
|
def lock!(user)
|
94
111
|
create_lock(by: user).tap(&:current_session!) unless lock.present?
|
95
112
|
end
|
113
|
+
|
114
|
+
def updated_after?(other_page)
|
115
|
+
return false unless other_page
|
116
|
+
updated_at > other_page.updated_at
|
117
|
+
end
|
118
|
+
|
119
|
+
def translated_page_for(locale)
|
120
|
+
translated_pages.for_locale(locale).first
|
121
|
+
end
|
122
|
+
|
123
|
+
def clone_for_locale(locale)
|
124
|
+
dup.tap do |np|
|
125
|
+
np.locale = locale
|
126
|
+
np.default_locale_page = self
|
127
|
+
np.published = false
|
128
|
+
|
129
|
+
if !top_level_page? && (parent_translation = parent_page.translated_page_for(locale)).present?
|
130
|
+
np.parent_page = parent_translation
|
131
|
+
end
|
132
|
+
|
133
|
+
child_pages.for_locale(locale).update(parent_page: np) if top_level_page? && respond_to?(:child_pages)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def update_translated_pages_weights_and_parent_page
|
140
|
+
return unless locale.to_sym == I18n.default_locale
|
141
|
+
return unless saved_change_to_weight? || saved_change_to_parent_page_id?
|
142
|
+
update_params = {}
|
143
|
+
update_params[:weight] = weight if saved_change_to_weight?
|
144
|
+
update_params[:parent_page_id] = parent_page_id if saved_change_to_parent_page_id?
|
145
|
+
translated_pages.update(update_params)
|
146
|
+
end
|
96
147
|
end
|
148
|
+
# rubocop:enable Metrics/ClassLength
|
97
149
|
end
|