spina 1.1.1 → 2.0.0.alpha
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/README.md +23 -244
- data/app/assets/fonts/spina/Metropolis-Black.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-BlackItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-Bold.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-BoldItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-ExtraBold.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-ExtraBoldItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-ExtraLight.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-ExtraLightItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-Light.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-LightItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-Medium.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-MediumItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-Regular.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-RegularItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-SemiBold.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-SemiBoldItalic.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-Thin.woff2 +0 -0
- data/app/assets/fonts/spina/Metropolis-ThinItalic.woff2 +0 -0
- 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/ics_spina-preview.html +121 -1
- 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 +0 -3
- data/app/assets/javascripts/spina/admin/trix.coffee.erb +14 -18
- data/app/assets/stylesheets/spina.sass +10 -10
- data/app/assets/stylesheets/spina/_buttons.sass +58 -32
- data/app/assets/stylesheets/spina/_configuration.sass.erb +2 -2
- data/app/assets/stylesheets/spina/_fonts.sass +32 -0
- data/app/assets/stylesheets/spina/_forms.sass +65 -76
- 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 +15 -28
- data/app/controllers/concerns/spina/frontend.rb +9 -0
- data/app/controllers/spina/admin/accounts_controller.rb +9 -13
- 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_folders_controller.rb +10 -0
- 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 +1 -1
- 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 +14 -0
- 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 +19 -20
- data/app/models/spina/parts/attachment.rb +17 -0
- data/app/models/spina/parts/base.rb +12 -0
- data/app/models/spina/parts/image.rb +30 -0
- data/app/models/spina/parts/image_collection.rb +23 -0
- data/app/models/spina/parts/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 +58 -0
- data/app/presenters/spina/menu_presenter.rb +2 -1
- data/app/views/layouts/spina/admin/admin.html.haml +3 -4
- data/app/views/layouts/spina/admin/pages.html.haml +5 -4
- 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/style.html.haml +26 -21
- data/app/views/spina/admin/images/index.html.haml +7 -5
- data/app/views/spina/admin/media_folders/_form.html.haml +5 -2
- data/app/views/spina/admin/media_folders/edit.js.erb +1 -0
- data/app/views/spina/admin/media_folders/show.html.haml +2 -1
- 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/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 +10 -8
- 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/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 +18 -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 +220 -205
- data/config/locales/bg.yml +219 -211
- data/config/locales/de.yml +218 -190
- data/config/locales/en.yml +218 -208
- data/config/locales/es.yml +219 -206
- data/config/locales/fr.yml +219 -190
- data/config/locales/id.yml +219 -189
- data/config/locales/it.yml +225 -152
- data/config/locales/nl.yml +220 -197
- data/config/locales/pl.yml +218 -185
- data/config/locales/pt-BR.yml +218 -205
- data/config/locales/ro.yml +258 -225
- data/config/locales/ru.yml +231 -171
- data/config/locales/sv.yml +218 -183
- data/config/locales/tr.yml +224 -151
- data/config/locales/zh-CN.yml +225 -175
- 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/themes/default.rb +4 -4
- data/lib/generators/spina/templates/config/initializers/themes/demo.rb +32 -44
- data/lib/spina.rb +2 -0
- data/lib/spina/attr_json_spina_parts_model.rb +29 -0
- data/lib/spina/engine.rb +13 -3
- data/lib/spina/part.rb +19 -0
- data/lib/spina/theme.rb +1 -1
- data/lib/spina/version.rb +1 -1
- data/vendor/assets/javascripts/spina/sortable.js +2 -2
- metadata +71 -45
- 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
@@ -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?
|
@@ -91,12 +91,12 @@ module Spina
|
|
91
91
|
theme.view_templates.find { |template| template[:name] == view_template_name }
|
92
92
|
end
|
93
93
|
|
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
94
|
private
|
99
95
|
|
96
|
+
def set_resource_from_parent
|
97
|
+
self.resource_id = parent.resource_id
|
98
|
+
end
|
99
|
+
|
100
100
|
def touch_navigations
|
101
101
|
navigations.update_all(updated_at: Time.zone.now)
|
102
102
|
end
|
@@ -106,19 +106,18 @@ module Spina
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def localized_materialized_path
|
109
|
-
if
|
109
|
+
if Mobility.locale == I18n.default_locale
|
110
110
|
generate_materialized_path.prepend('/')
|
111
111
|
else
|
112
|
-
generate_materialized_path.prepend("/#{
|
112
|
+
generate_materialized_path.prepend("/#{Mobility.locale}/").gsub(/\/\z/, "")
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
116
|
def generate_materialized_path
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
117
|
+
path_fragments = [resource&.slug]
|
118
|
+
path_fragments.append *ancestors.collect(&:slug)
|
119
|
+
path_fragments.append(slug) unless name == 'homepage'
|
120
|
+
path_fragments.compact.map(&:parameterize).join('/')
|
122
121
|
end
|
123
122
|
|
124
123
|
end
|
@@ -0,0 +1,17 @@
|
|
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
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
end
|
29
|
+
end
|
30
|
+
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,15 @@
|
|
1
|
+
module Spina
|
2
|
+
module Parts
|
3
|
+
class RepeaterContent < Base
|
4
|
+
include Partable
|
5
|
+
include AttrJson::NestedAttributes
|
6
|
+
|
7
|
+
attr_json :parts, AttrJson::Type::SpinaPartsModel.new, array: true
|
8
|
+
attr_json_accepts_nested_attributes_for :parts
|
9
|
+
|
10
|
+
def find_part(name)
|
11
|
+
(parts || []).find{|part| part.name.to_s == name.to_s}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Spina
|
2
2
|
class Resource < ApplicationRecord
|
3
|
-
|
3
|
+
extend Mobility
|
4
4
|
|
5
|
-
|
5
|
+
has_many :pages, dependent: :restrict_with_exception
|
6
6
|
|
7
|
-
|
7
|
+
translates :slug, backend: :jsonb
|
8
8
|
|
9
9
|
def pages
|
10
10
|
case order_by
|
@@ -14,14 +14,6 @@ module Spina
|
|
14
14
|
super.order(created_at: :desc)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def scope_pages_to_parent_page
|
21
|
-
pages.roots.each do |root_page|
|
22
|
-
root_page.update(parent: parent_page)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
17
|
+
|
26
18
|
end
|
27
19
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Spina
|
2
|
+
class ContentPresenter
|
3
|
+
attr_reader :view_context, :container
|
4
|
+
|
5
|
+
def initialize(view_context, container)
|
6
|
+
@view_context = view_context || Spina::Current.page&.view_context
|
7
|
+
@container = container
|
8
|
+
end
|
9
|
+
|
10
|
+
def text(name)
|
11
|
+
part = find_part(name)
|
12
|
+
part&.content.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def html(name)
|
16
|
+
html = find_part(name)&.content
|
17
|
+
ActiveSupport::SafeBuffer.new(html.to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
def image_tag(image, variant_options = {}, options = {})
|
21
|
+
image = find_part(image) unless image.is_a? Spina::Parts::Image
|
22
|
+
image_tag_options = {alt: image&.alt}
|
23
|
+
view_context.image_tag main_app_image_url(image, variant_options), options.merge(image_tag_options) if image.present?
|
24
|
+
end
|
25
|
+
|
26
|
+
def image_url(image, variant_options = {})
|
27
|
+
image = find_part(image) unless image.is_a? Spina::Parts::Image
|
28
|
+
main_app_image_url(image, variant_options) if image.present?
|
29
|
+
end
|
30
|
+
|
31
|
+
def attachment_url(attachment)
|
32
|
+
attachment = find_part(attachment) unless attachment.is_a? Spina::Parts::Attachment
|
33
|
+
rails_service_blob_url(attachment)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def main_app_image_url(image, variant_options = {})
|
39
|
+
# SVG's can't have variants,
|
40
|
+
# Render rails_service_blob_url directly instead
|
41
|
+
return rails_service_blob_url(image) if image.svg?
|
42
|
+
|
43
|
+
# Other images (like PNG & JPG) can have variants
|
44
|
+
variant_key = ActiveStorage::Variation.encode(variant_options)
|
45
|
+
view_context.main_app.rails_blob_representation_url(image.signed_blob_id, variant_key, image.filename.presence || "image")
|
46
|
+
end
|
47
|
+
|
48
|
+
def rails_service_blob_url(file)
|
49
|
+
return if file.blank?
|
50
|
+
view_context.main_app.rails_service_blob_url(file.signed_blob_id, filename: file.filename.presence || "file")
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_part(name)
|
54
|
+
container.find_part(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -50,6 +50,7 @@ module Spina
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def render_item(item)
|
53
|
+
return nil unless item.materialized_path
|
53
54
|
children = scoped_collection(item.children)
|
54
55
|
|
55
56
|
content_tag(list_item_tag, class: list_item_css, data: {page_id: item.page_id, draft: (true if item.draft?) }) do
|
@@ -71,4 +72,4 @@ module Spina
|
|
71
72
|
end
|
72
73
|
|
73
74
|
end
|
74
|
-
end
|
75
|
+
end
|
@@ -6,7 +6,9 @@
|
|
6
6
|
= csrf_meta_tags
|
7
7
|
%meta{name: 'turbolinks-cache-control', content: 'no-preview'}
|
8
8
|
|
9
|
-
%
|
9
|
+
%link{rel: 'icon', href: image_url("spina/favicon.png")}
|
10
|
+
|
11
|
+
%title Spina CMS
|
10
12
|
|
11
13
|
/ Stylesheet
|
12
14
|
= stylesheet_link_tag 'spina/admin/application', data: {turbolinks_track: true}
|
@@ -33,6 +35,3 @@
|
|
33
35
|
= render 'spina/admin/shared/notifications'
|
34
36
|
|
35
37
|
= content_for?(:application) ? yield(:application) : yield
|
36
|
-
|
37
|
-
= link_to 'http://www.spinacms.com', class: 'spina-logo', target: :blank do
|
38
|
-
= image_tag('spina/spina.svg', width: 32, height: 24)
|