spina 1.1.2 → 2.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of spina might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/fonts/spina/ics_spina.eot +0 -0
- data/app/assets/fonts/spina/ics_spina.svg +285 -267
- data/app/assets/fonts/spina/ics_spina.ttf +0 -0
- data/app/assets/fonts/spina/ics_spina.woff +0 -0
- data/app/assets/fonts/spina/ics_spina.woff2 +0 -0
- data/app/assets/icons/spina/bold.svg +1 -1
- data/app/assets/icons/spina/code.svg +1 -1
- data/app/assets/icons/spina/image.svg +1 -10
- data/app/assets/icons/spina/indent.svg +1 -0
- data/app/assets/icons/spina/italic.svg +1 -1
- data/app/assets/icons/spina/link.svg +1 -1
- data/app/assets/icons/spina/list-ol.svg +1 -0
- data/app/assets/icons/spina/list.svg +1 -0
- data/app/assets/icons/spina/outdent.svg +1 -0
- data/app/assets/icons/spina/preview/icons_spina-preview.html +0 -2
- data/app/assets/icons/spina/preview/ics_spina-preview.html +121 -3
- data/app/assets/icons/spina/quote-right.svg +1 -0
- data/app/assets/icons/spina/redo.svg +1 -0
- data/app/assets/icons/spina/strikethrough.svg +1 -0
- data/app/assets/icons/spina/undo.svg +1 -0
- data/app/assets/images/spina/favicon.png +0 -0
- data/app/assets/javascripts/spina/admin/application.js +1 -2
- data/app/assets/javascripts/spina/admin/controllers/attachment_picker_controller.js +15 -0
- data/app/assets/javascripts/spina/admin/controllers/image_form_controller.js +5 -4
- data/app/assets/javascripts/spina/admin/controllers/infinite_scroll_controller.js +20 -22
- data/app/assets/javascripts/spina/admin/controllers/media_picker_controller.js +171 -0
- data/app/assets/javascripts/spina/admin/controllers/modal_controller.js +18 -0
- data/app/assets/javascripts/spina/admin/controllers/repeater_form_controller.js +38 -0
- data/app/assets/javascripts/spina/admin/media_gallery.coffee +0 -3
- data/app/assets/javascripts/spina/admin/notifications.coffee +1 -1
- data/app/assets/javascripts/spina/admin/pages.coffee.erb +3 -20
- data/app/assets/javascripts/spina/admin/scaffold.coffee +1 -3
- data/app/assets/javascripts/spina/admin/trix.coffee.erb +14 -18
- data/app/assets/stylesheets/spina.sass +10 -8
- data/app/assets/stylesheets/spina/_buttons.sass +57 -31
- data/app/assets/stylesheets/spina/_configuration.sass.erb +1 -1
- data/app/assets/stylesheets/spina/_forms.sass +72 -77
- data/app/assets/stylesheets/spina/_gallery.sass +22 -4
- data/app/assets/stylesheets/spina/_ics_spina.scss +8 -0
- data/app/assets/stylesheets/spina/_media_picker.sass +133 -0
- data/app/assets/stylesheets/spina/_modal.sass +35 -2
- data/app/assets/stylesheets/spina/_notifications.sass +20 -14
- data/app/assets/stylesheets/spina/_pages.sass +131 -0
- data/app/assets/stylesheets/spina/_sortable_lists.sass +14 -8
- data/app/assets/stylesheets/spina/_tables.sass +7 -4
- data/app/assets/stylesheets/spina/_trix_custom.sass +29 -32
- data/app/controllers/concerns/spina/current_methods.rb +26 -0
- data/app/controllers/concerns/spina/frontend.rb +9 -0
- data/app/controllers/spina/admin/accounts_controller.rb +9 -13
- data/app/controllers/spina/admin/admin_controller.rb +5 -1
- data/app/controllers/spina/admin/attachments_controller.rb +0 -22
- data/app/controllers/spina/admin/images_controller.rb +1 -1
- data/app/controllers/spina/admin/media_picker_controller.rb +18 -19
- data/app/controllers/spina/admin/pages_controller.rb +3 -7
- data/app/controllers/spina/admin/resources_controller.rb +9 -4
- data/app/controllers/spina/application_controller.rb +6 -23
- data/app/controllers/spina/pages_controller.rb +11 -13
- data/app/controllers/spina/sitemaps_controller.rb +6 -6
- data/app/helpers/spina/admin/pages_helper.rb +22 -20
- data/app/helpers/spina/{files_helper.rb → attachments_helper.rb} +1 -1
- data/app/helpers/spina/images_helper.rb +9 -10
- data/app/helpers/spina/pages_helper.rb +23 -4
- data/app/models/concerns/spina/partable.rb +19 -7
- data/app/models/concerns/spina/translated_content.rb +19 -0
- data/app/models/spina/account.rb +3 -10
- data/app/models/spina/attachment.rb +0 -4
- data/app/models/spina/current.rb +1 -0
- data/app/models/spina/image.rb +0 -4
- data/app/models/spina/page.rb +31 -23
- data/app/models/spina/parts/attachment.rb +22 -0
- data/app/models/spina/parts/base.rb +12 -0
- data/app/models/spina/parts/image.rb +39 -0
- data/app/models/spina/parts/image_collection.rb +23 -0
- data/app/models/spina/parts/image_variant.rb +19 -0
- data/app/models/spina/parts/line.rb +7 -0
- data/app/models/spina/parts/multi_line.rb +7 -0
- data/app/models/spina/parts/option.rb +13 -0
- data/app/models/spina/parts/repeater.rb +10 -0
- data/app/models/spina/parts/repeater_content.rb +15 -0
- data/app/models/spina/parts/text.rb +7 -0
- data/app/models/spina/resource.rb +4 -12
- data/app/presenters/spina/content_presenter.rb +51 -0
- data/app/presenters/spina/menu_presenter.rb +2 -1
- data/app/views/layouts/spina/admin/admin.html.haml +3 -7
- data/app/views/layouts/spina/admin/pages.html.haml +5 -4
- data/app/views/layouts/spina/login.html.haml +0 -3
- data/app/views/spina/admin/accounts/_form.html.haml +13 -7
- data/app/views/spina/admin/accounts/analytics.html.haml +5 -3
- data/app/views/spina/admin/accounts/social.html.haml +13 -7
- data/app/views/spina/admin/accounts/style.html.haml +26 -21
- data/app/views/spina/admin/attachments/index.html.haml +1 -1
- data/app/views/spina/admin/images/_image.html.haml +1 -1
- data/app/views/spina/admin/images/index.html.haml +7 -5
- data/app/views/spina/admin/media_folders/_media_folder.html.haml +1 -1
- data/app/views/spina/admin/media_folders/show.html.haml +2 -2
- data/app/views/spina/admin/media_picker/_image.html.haml +3 -0
- data/app/views/spina/admin/media_picker/_media_picker.html.haml +32 -0
- data/app/views/spina/admin/media_picker/_media_picker_grid.html.haml +25 -0
- data/app/views/spina/admin/media_picker/_modal.html.haml +1 -1
- data/app/views/spina/admin/media_picker/infinite_scroll.js.erb +4 -4
- data/app/views/spina/admin/media_picker/select.js.erb +2 -0
- data/app/views/spina/admin/media_picker/show.html.haml +1 -0
- data/app/views/spina/admin/media_picker/show.js.erb +1 -1
- data/app/views/spina/admin/pages/_form.html.haml +9 -7
- data/app/views/spina/admin/pages/_form_advanced.html.haml +19 -17
- data/app/views/spina/admin/pages/_form_page_content.html.haml +14 -13
- data/app/views/spina/admin/pages/_form_page_seo.html.haml +15 -4
- data/app/views/spina/admin/pages/_page.html.haml +5 -3
- data/app/views/spina/admin/pages/_page_nested_list.html.haml +2 -3
- data/app/views/spina/admin/pages/index.html.haml +5 -4
- data/app/views/spina/admin/parts/attachments/_form.html.haml +6 -0
- data/app/views/spina/admin/parts/image_collections/_fields.html.haml +7 -0
- data/app/views/spina/admin/parts/image_collections/_form.html.haml +12 -0
- data/app/views/spina/admin/parts/images/_form.html.haml +18 -0
- data/app/views/spina/admin/parts/lines/_form.html.haml +2 -0
- data/app/views/spina/admin/parts/multi_lines/_form.html.haml +2 -0
- data/app/views/spina/admin/parts/options/_form.html.haml +3 -0
- data/app/views/spina/admin/parts/repeaters/_fields.html.haml +15 -0
- data/app/views/spina/admin/parts/repeaters/_form.html.haml +17 -0
- data/app/views/spina/admin/parts/texts/_form.html.haml +6 -0
- data/app/views/spina/admin/resources/edit.html.haml +28 -12
- data/app/views/spina/admin/resources/show.html.haml +6 -3
- data/app/views/spina/admin/shared/_notifications.html.haml +4 -4
- data/config/locales/TH.yml +10 -0
- data/config/locales/bg.yml +10 -0
- data/config/locales/de.yml +10 -0
- data/config/locales/en.yml +10 -0
- data/config/locales/es.yml +39 -29
- data/config/locales/fr.yml +10 -0
- data/config/locales/id.yml +10 -0
- data/config/locales/it.yml +10 -0
- data/config/locales/nl.yml +10 -0
- data/config/locales/pl.yml +24 -14
- data/config/locales/pt-BR.yml +10 -0
- data/config/locales/ro.yml +10 -0
- data/config/locales/ru.yml +10 -0
- data/config/locales/sv.yml +10 -0
- data/config/locales/tr.yml +10 -0
- data/config/locales/zh-CN.yml +10 -0
- data/config/routes.rb +13 -0
- data/db/migrate/11_create_spina_resources.rb +0 -2
- data/db/migrate/12_add_url_title_to_spina_page_translations.rb +5 -0
- data/db/migrate/13_add_json_attributes_to_spina_accounts.rb +5 -0
- data/db/migrate/14_add_json_attributes_to_spina_pages.rb +5 -0
- data/db/migrate/15_add_slug_to_spina_resources.rb +5 -0
- data/lib/generators/spina/templates/app/views/demo/pages/demo.html.haml +13 -21
- data/lib/generators/spina/templates/app/views/demo/pages/homepage.html.haml +1 -1
- data/lib/generators/spina/templates/config/initializers/mobility.rb +13 -4
- data/lib/generators/spina/templates/config/initializers/spina.rb +4 -0
- data/lib/generators/spina/templates/config/initializers/themes/default.rb +7 -7
- data/lib/generators/spina/templates/config/initializers/themes/demo.rb +32 -44
- data/lib/spina.rb +18 -3
- data/lib/spina/attr_json_spina_parts_model.rb +29 -0
- data/lib/spina/engine.rb +14 -6
- data/lib/spina/part.rb +19 -0
- data/lib/spina/theme.rb +1 -1
- data/lib/spina/version.rb +1 -1
- data/lib/tasks/spina_tasks.rake +1 -1
- data/vendor/assets/javascripts/spina/sortable.js +2 -2
- metadata +83 -53
- data/app/assets/javascripts/spina/admin/account.coffee +0 -16
- data/app/models/concerns/spina/image_collectable.rb +0 -23
- data/app/models/concerns/spina/optionable.rb +0 -12
- data/app/models/concerns/spina/part.rb +0 -38
- data/app/models/spina/attachment_collection.rb +0 -20
- data/app/models/spina/image_collection.rb +0 -23
- data/app/models/spina/image_collections_image.rb +0 -6
- data/app/models/spina/layout_part.rb +0 -22
- data/app/models/spina/line.rb +0 -10
- data/app/models/spina/option.rb +0 -17
- data/app/models/spina/page_part.rb +0 -22
- data/app/models/spina/structure.rb +0 -14
- data/app/models/spina/structure_item.rb +0 -22
- data/app/models/spina/structure_part.rb +0 -20
- data/app/models/spina/text.rb +0 -10
- data/app/views/dummy/show.html.haml +0 -1
- data/app/views/spina/admin/attachments/_attachment_collection.html.haml +0 -2
- data/app/views/spina/admin/attachments/_select.html.haml +0 -17
- data/app/views/spina/admin/attachments/_select_collection.html.haml +0 -18
- data/app/views/spina/admin/attachments/insert.js.erb +0 -5
- data/app/views/spina/admin/attachments/insert_collection.js.coffee +0 -7
- data/app/views/spina/admin/attachments/select.js.erb +0 -2
- data/app/views/spina/admin/attachments/select_collection.js.erb +0 -2
- data/app/views/spina/admin/image_collections/_image_collection.html.haml +0 -5
- data/app/views/spina/admin/layout_partables/lines/_form.html.haml +0 -2
- data/app/views/spina/admin/partables/attachment_collections/_form.html.haml +0 -14
- data/app/views/spina/admin/partables/attachments/_form.html.haml +0 -13
- data/app/views/spina/admin/partables/image_collections/_form.html.haml +0 -16
- data/app/views/spina/admin/partables/images/_form.html.haml +0 -21
- data/app/views/spina/admin/partables/lines/_form.html.haml +0 -5
- data/app/views/spina/admin/partables/options/_form.html.haml +0 -7
- data/app/views/spina/admin/partables/photo_collections/_form.html.haml +0 -4
- data/app/views/spina/admin/partables/photos/_form.html.haml +0 -4
- data/app/views/spina/admin/partables/structures/_form.html.haml +0 -21
- data/app/views/spina/admin/partables/texts/_form.html.haml +0 -8
- data/app/views/spina/admin/structure_items/_fields.html.haml +0 -15
- data/app/views/spina/admin/structure_partables/attachment_collections/_form.html.haml +0 -14
- data/app/views/spina/admin/structure_partables/attachments/_form.html.haml +0 -13
@@ -1,16 +1,15 @@
|
|
1
1
|
module Spina
|
2
2
|
module ImagesHelper
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def variant(image, options)
|
8
|
-
if image.attached? && image.variable?
|
9
|
-
variant = image.variant(options)
|
10
|
-
main_app.rails_blob_representation_path(variant.blob.signed_id, variant.variation.key, variant.blob.filename)
|
11
|
-
else
|
12
|
-
"https://placehold.it/100x100.png"
|
13
|
-
end
|
4
|
+
def thumbnail_url(image)
|
5
|
+
return "" if image.nil?
|
6
|
+
main_app.url_for(image.variant(resize: "400x300^", crop: "400x300+0+0"))
|
14
7
|
end
|
8
|
+
|
9
|
+
def embedded_image_url(image)
|
10
|
+
return "" if image.nil?
|
11
|
+
main_app.url_for(image.variant(resize: Spina.config.embedded_image_size))
|
12
|
+
end
|
13
|
+
|
15
14
|
end
|
16
15
|
end
|
@@ -1,17 +1,36 @@
|
|
1
1
|
module Spina
|
2
2
|
module PagesHelper
|
3
3
|
|
4
|
-
def content(part_name)
|
5
|
-
|
4
|
+
def content(part_name = nil)
|
5
|
+
Current.page.content(part_name)
|
6
6
|
end
|
7
7
|
|
8
8
|
def has_content?(part_name)
|
9
|
-
|
9
|
+
Current.page.has_content?(part_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def repeater(part)
|
13
|
+
part = Current.page.find_part(part)&.content unless part.is_a? Array
|
14
|
+
part&.each do |repeater_content|
|
15
|
+
repeater_content.view_context = self
|
16
|
+
yield(repeater_content)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def images(part)
|
21
|
+
part = Current.page.find_part(part)&.content unless part.is_a? Array
|
22
|
+
part&.each do |image|
|
23
|
+
yield(image)
|
24
|
+
end
|
10
25
|
end
|
11
26
|
|
12
27
|
def current_page
|
13
28
|
Current.page
|
14
29
|
end
|
15
30
|
|
31
|
+
def current_account
|
32
|
+
Current.account
|
33
|
+
end
|
34
|
+
|
16
35
|
end
|
17
|
-
end
|
36
|
+
end
|
@@ -2,23 +2,35 @@ module Spina
|
|
2
2
|
module Partable
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
+
attr_accessor :view_context
|
6
|
+
|
5
7
|
included do
|
8
|
+
|
6
9
|
def part(attributes)
|
7
|
-
part =
|
8
|
-
|
9
|
-
|
10
|
+
part = find_part(attributes[:name]) || attributes[:part_type].constantize.new
|
11
|
+
|
12
|
+
# Copy all attributes to part
|
13
|
+
%w(name title options).each do |attribute|
|
14
|
+
part.public_send("#{attribute}=", attributes[attribute.to_sym]) if part.respond_to?(attribute)
|
15
|
+
end
|
16
|
+
|
10
17
|
part
|
11
18
|
end
|
12
19
|
|
13
20
|
def has_content?(name)
|
14
|
-
|
21
|
+
find_part(name).present?
|
15
22
|
end
|
16
23
|
|
17
|
-
def content(name)
|
18
|
-
|
19
|
-
part.try(:content)
|
24
|
+
def content(name = nil)
|
25
|
+
name ? find_part(name)&.content : content_presenter
|
20
26
|
end
|
21
27
|
|
28
|
+
private
|
29
|
+
|
30
|
+
def content_presenter
|
31
|
+
@content_presenter ||= ContentPresenter.new(view_context, self)
|
32
|
+
end
|
33
|
+
|
22
34
|
end
|
23
35
|
end
|
24
36
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spina
|
2
|
+
module TranslatedContent
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
|
7
|
+
# Store each locale's content in [locale]_content as an array of parts
|
8
|
+
Spina.config.locales.each do |locale|
|
9
|
+
attr_json "#{locale}_content".to_sym, AttrJson::Type::SpinaPartsModel.new, array: true, default: -> { [] }
|
10
|
+
attr_json_accepts_nested_attributes_for "#{locale}_content".to_sym
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_part(name)
|
14
|
+
send("#{I18n.locale}_content").find{|part| part.name.to_s == name.to_s}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/app/models/spina/account.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
module Spina
|
2
2
|
class Account < ApplicationRecord
|
3
|
+
include AttrJson::Record
|
4
|
+
include AttrJson::NestedAttributes
|
3
5
|
include Partable
|
6
|
+
include TranslatedContent
|
4
7
|
|
5
8
|
serialize :preferences
|
6
9
|
|
7
|
-
has_many :layout_parts, dependent: :destroy
|
8
|
-
accepts_nested_attributes_for :layout_parts, allow_destroy: true
|
9
|
-
|
10
|
-
alias_attribute :layout_part, :part
|
11
|
-
alias_attribute :parts, :layout_parts
|
12
|
-
|
13
10
|
after_save :bootstrap_website
|
14
11
|
|
15
12
|
def to_s
|
16
13
|
name
|
17
14
|
end
|
18
15
|
|
19
|
-
def content(layout_part)
|
20
|
-
layout_parts.find_by(name: layout_part).try(:content)
|
21
|
-
end
|
22
|
-
|
23
16
|
def self.serialized_attr_accessor(*args)
|
24
17
|
args.each do |method_name|
|
25
18
|
define_method method_name do
|
@@ -2,10 +2,6 @@ module Spina
|
|
2
2
|
class Attachment < ApplicationRecord
|
3
3
|
has_one_attached :file
|
4
4
|
|
5
|
-
has_one :page_part, as: :page_partable
|
6
|
-
has_many :structure_parts, as: :structure_partable
|
7
|
-
has_and_belongs_to_many :attachment_collections, join_table: 'spina_attachment_collections_attachments'
|
8
|
-
|
9
5
|
attr_accessor :_destroy
|
10
6
|
|
11
7
|
scope :sorted, -> { order('file ASC') }
|
data/app/models/spina/current.rb
CHANGED
data/app/models/spina/image.rb
CHANGED
@@ -4,11 +4,7 @@ module Spina
|
|
4
4
|
|
5
5
|
has_one_attached :file
|
6
6
|
|
7
|
-
has_many :page_parts, as: :page_partable
|
8
|
-
has_many :structure_parts, as: :structure_partable
|
9
|
-
|
10
7
|
scope :sorted, -> { order('created_at DESC') }
|
11
|
-
scope :sorted_by_image_collection, -> { order('position') }
|
12
8
|
|
13
9
|
def name
|
14
10
|
file.try(:filename).to_s
|
data/app/models/spina/page.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
module Spina
|
2
2
|
class Page < ApplicationRecord
|
3
3
|
extend Mobility
|
4
|
+
include AttrJson::Record
|
5
|
+
include AttrJson::NestedAttributes
|
4
6
|
include Partable
|
7
|
+
include TranslatedContent
|
5
8
|
|
6
9
|
# Stores the old path when generating a new materialized_path
|
7
10
|
attr_accessor :old_path
|
8
11
|
|
9
|
-
# Page contains multiple parts called PageParts
|
10
|
-
has_many :page_parts, dependent: :destroy, inverse_of: :page
|
11
|
-
alias_attribute :parts, :page_parts
|
12
|
-
accepts_nested_attributes_for :page_parts, allow_destroy: true
|
13
|
-
|
14
12
|
# Orphaned pages are adopted by parent pages if available, otherwise become root
|
15
13
|
has_ancestry orphan_strategy: :adopt
|
16
14
|
|
@@ -28,10 +26,12 @@ module Spina
|
|
28
26
|
scope :live, -> { active.where(draft: false) }
|
29
27
|
scope :in_menu, -> { where(show_in_menu: true) }
|
30
28
|
|
29
|
+
# Copy resource from parent
|
30
|
+
before_save :set_resource_from_parent, if: -> { parent.present? }
|
31
|
+
|
31
32
|
# Save children to update all materialized_paths
|
32
33
|
after_save :save_children
|
33
34
|
after_save :touch_navigations
|
34
|
-
after_save -> { page_parts.each(&:save) }
|
35
35
|
|
36
36
|
# Create a 301 redirect if materialized_path changed
|
37
37
|
after_save :rewrite_rule
|
@@ -41,7 +41,7 @@ module Spina
|
|
41
41
|
|
42
42
|
translates :title, fallbacks: true
|
43
43
|
translates :description, :materialized_path
|
44
|
-
translates :menu_title, :seo_title, default: -> { title }
|
44
|
+
translates :menu_title, :seo_title, :url_title, default: -> { title }
|
45
45
|
|
46
46
|
def to_s
|
47
47
|
name
|
@@ -51,8 +51,8 @@ module Spina
|
|
51
51
|
id
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
|
54
|
+
def slug
|
55
|
+
url_title&.parameterize
|
56
56
|
end
|
57
57
|
|
58
58
|
def custom_page?
|
@@ -74,12 +74,17 @@ module Spina
|
|
74
74
|
def next_sibling
|
75
75
|
siblings.where('position > ?', position).sorted.first
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
def set_materialized_path
|
79
79
|
self.old_path = materialized_path
|
80
80
|
self.materialized_path = localized_materialized_path
|
81
|
-
|
82
|
-
materialized_path
|
81
|
+
|
82
|
+
# Append counter to duplicate materialized_path
|
83
|
+
i = 0
|
84
|
+
while duplicate_materialized_path?
|
85
|
+
i += 1
|
86
|
+
self.materialized_path = localized_materialized_path.concat("-#{i}")
|
87
|
+
end
|
83
88
|
end
|
84
89
|
|
85
90
|
def cache_key
|
@@ -91,12 +96,12 @@ module Spina
|
|
91
96
|
theme.view_templates.find { |template| template[:name] == view_template_name }
|
92
97
|
end
|
93
98
|
|
94
|
-
def view_template_page_parts(theme)
|
95
|
-
theme.page_parts.select { |page_part| page_part[:name].in? view_template_config(theme)[:page_parts] }
|
96
|
-
end
|
97
|
-
|
98
99
|
private
|
99
100
|
|
101
|
+
def set_resource_from_parent
|
102
|
+
self.resource_id = parent.resource_id
|
103
|
+
end
|
104
|
+
|
100
105
|
def touch_navigations
|
101
106
|
navigations.update_all(updated_at: Time.zone.now)
|
102
107
|
end
|
@@ -106,19 +111,22 @@ module Spina
|
|
106
111
|
end
|
107
112
|
|
108
113
|
def localized_materialized_path
|
109
|
-
if
|
114
|
+
if Mobility.locale == I18n.default_locale
|
110
115
|
generate_materialized_path.prepend('/')
|
111
116
|
else
|
112
|
-
generate_materialized_path.prepend("/#{
|
117
|
+
generate_materialized_path.prepend("/#{Mobility.locale}/").gsub(/\/\z/, "")
|
113
118
|
end
|
114
119
|
end
|
115
120
|
|
116
121
|
def generate_materialized_path
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
+
path_fragments = [resource&.slug]
|
123
|
+
path_fragments.append *ancestors.collect(&:slug)
|
124
|
+
path_fragments.append(slug) unless name == 'homepage'
|
125
|
+
path_fragments.compact.map(&:parameterize).join('/')
|
126
|
+
end
|
127
|
+
|
128
|
+
def duplicate_materialized_path?
|
129
|
+
self.class.where.not(id: id).i18n.where(materialized_path: materialized_path).exists?
|
122
130
|
end
|
123
131
|
|
124
132
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Spina
|
2
|
+
module Parts
|
3
|
+
class Attachment < Base
|
4
|
+
attr_json :attachment_id, :integer, default: nil
|
5
|
+
attr_json :signed_blob_id, :string, default: nil
|
6
|
+
attr_json :filename, :string, default: ""
|
7
|
+
|
8
|
+
def content
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def present?
|
13
|
+
signed_blob_id.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
def signed_id
|
17
|
+
signed_blob_id
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Spina
|
2
|
+
module Parts
|
3
|
+
class Image < Base
|
4
|
+
attr_json :image_id, :integer, default: nil
|
5
|
+
attr_json :signed_blob_id, :string, default: nil
|
6
|
+
attr_json :alt, :string, default: ""
|
7
|
+
attr_json :filename, :string, default: ""
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
alt.presence || filename.presence || Spina::Image.model_name.human
|
11
|
+
end
|
12
|
+
|
13
|
+
def content
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def svg?
|
18
|
+
filename =~ /\.svg\z/
|
19
|
+
end
|
20
|
+
|
21
|
+
def spina_image
|
22
|
+
Spina::Image.find_by(id: image_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def present?
|
26
|
+
signed_blob_id.present?
|
27
|
+
end
|
28
|
+
|
29
|
+
def signed_id
|
30
|
+
signed_blob_id
|
31
|
+
end
|
32
|
+
|
33
|
+
def variant(options)
|
34
|
+
Spina::Parts::ImageVariant.new(self, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Spina
|
2
|
+
module Parts
|
3
|
+
class ImageCollection < Base
|
4
|
+
include AttrJson::NestedAttributes
|
5
|
+
|
6
|
+
attr_json :images, Image.to_type, array: true
|
7
|
+
attr_json_accepts_nested_attributes_for :images
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
Spina::Parts::ImageCollection.model_name.human
|
11
|
+
end
|
12
|
+
|
13
|
+
def content
|
14
|
+
(images || [])
|
15
|
+
end
|
16
|
+
|
17
|
+
def image_ids
|
18
|
+
content.map(&:image_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spina
|
2
|
+
module Parts
|
3
|
+
class ImageVariant
|
4
|
+
attr_reader :blob
|
5
|
+
|
6
|
+
def initialize(image, options)
|
7
|
+
@blob = image
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def variation
|
12
|
+
OpenStruct.new({
|
13
|
+
key: ActiveStorage::Variation.encode(@options)
|
14
|
+
})
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|