comfortable_mexican_sofa 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +95 -4
- data/.travis.yml +2 -1
- data/CONTRIBUTING.md +8 -5
- data/Gemfile +9 -9
- data/Rakefile +1 -1
- data/app/assets/javascripts/comfy/admin/cms/base.js.coffee +1 -0
- data/app/assets/stylesheets/comfy/admin/cms/base.sass +14 -4
- data/app/controllers/application_controller.rb +2 -2
- data/app/controllers/comfy/admin/base_controller.rb +1 -1
- data/app/controllers/comfy/admin/cms/base_controller.rb +7 -6
- data/app/controllers/comfy/admin/cms/categories_controller.rb +2 -1
- data/app/controllers/comfy/admin/cms/files_controller.rb +32 -29
- data/app/controllers/comfy/admin/cms/layouts_controller.rb +10 -9
- data/app/controllers/comfy/admin/cms/pages_controller.rb +31 -27
- data/app/controllers/comfy/admin/cms/revisions/base_controller.rb +5 -4
- data/app/controllers/comfy/admin/cms/revisions/layout_controller.rb +2 -1
- data/app/controllers/comfy/admin/cms/revisions/page_controller.rb +9 -3
- data/app/controllers/comfy/admin/cms/revisions/snippet_controller.rb +2 -1
- data/app/controllers/comfy/admin/cms/revisions/translation_controller.rb +9 -3
- data/app/controllers/comfy/admin/cms/sites_controller.rb +10 -9
- data/app/controllers/comfy/admin/cms/snippets_controller.rb +10 -9
- data/app/controllers/comfy/admin/cms/translations_controller.rb +15 -14
- data/app/controllers/comfy/cms/assets_controller.rb +4 -3
- data/app/controllers/comfy/cms/base_controller.rb +12 -11
- data/app/controllers/comfy/cms/content_controller.rb +8 -7
- data/app/controllers/concerns/comfy/paginate.rb +2 -1
- data/app/helpers/comfy/cms_helper.rb +6 -3
- data/app/models/comfy/cms/categorization.rb +2 -1
- data/app/models/comfy/cms/category.rb +3 -2
- data/app/models/comfy/cms/file.rb +9 -7
- data/app/models/comfy/cms/fragment.rb +8 -6
- data/app/models/comfy/cms/layout.rb +24 -24
- data/app/models/comfy/cms/page.rb +51 -32
- data/app/models/comfy/cms/revision.rb +2 -1
- data/app/models/comfy/cms/site.rb +27 -26
- data/app/models/comfy/cms/snippet.rb +7 -5
- data/app/models/comfy/cms/translation.rb +6 -4
- data/app/models/concerns/comfy/cms/with_categories.rb +9 -7
- data/app/models/concerns/comfy/cms/with_fragments.rb +15 -13
- data/app/views/comfy/admin/cms/categories/_categories.html.haml +1 -1
- data/app/views/comfy/admin/cms/files/_file.html.haml +3 -3
- data/app/views/comfy/admin/cms/files/_modal.html.haml +2 -2
- data/app/views/comfy/admin/cms/{pages/_fragment_attachments.html.haml → fragments/_form_fragment_attachments.html.haml} +0 -0
- data/app/views/comfy/admin/cms/{pages → fragments}/_form_fragments.html.haml +0 -0
- data/app/views/comfy/admin/cms/layouts/_index_branch.html.haml +2 -2
- data/app/views/comfy/admin/cms/pages/_form.html.haml +7 -7
- data/app/views/comfy/admin/cms/pages/_index_branch.html.haml +16 -15
- data/app/views/comfy/admin/cms/pages/form_fragments.js.erb +1 -1
- data/app/views/comfy/admin/cms/pages/toggle_branch.js.erb +1 -1
- data/app/views/comfy/admin/cms/snippets/index.html.haml +3 -3
- data/app/views/comfy/admin/cms/translations/_form.html.haml +1 -1
- data/app/views/comfy/admin/cms/translations/form_fragments.js.erb +1 -1
- data/app/views/layouts/comfy/admin/cms/_body.html.haml +1 -4
- data/app/views/layouts/comfy/admin/cms.html.haml +1 -1
- data/bin/bundle +3 -0
- data/bin/rails +4 -0
- data/bin/rake +4 -0
- data/bin/setup +36 -0
- data/bin/update +31 -0
- data/bin/yarn +11 -0
- data/comfortable_mexican_sofa.gemspec +14 -14
- data/config/application.rb +4 -3
- data/config/boot.rb +3 -3
- data/config/cms_routes.rb +1 -1
- data/config/environment.rb +1 -1
- data/config/environments/development.rb +2 -2
- data/config/environments/test.rb +1 -1
- data/config/initializers/comfortable_mexican_sofa.rb +2 -5
- data/config/locales/cs.yml +2 -1
- data/config/locales/da.yml +2 -1
- data/config/locales/de.yml +2 -1
- data/config/locales/en.yml +2 -1
- data/config/locales/es.yml +2 -1
- data/config/locales/fr.yml +2 -1
- data/config/locales/it.yml +2 -1
- data/config/locales/ja.yml +2 -1
- data/config/locales/nb.yml +2 -1
- data/config/locales/nl.yml +2 -1
- data/config/locales/pl.yml +2 -1
- data/config/locales/pt-BR.yml +2 -1
- data/config/locales/ru.yml +2 -1
- data/config/locales/sk.yml +2 -1
- data/config/locales/sv.yml +2 -1
- data/config/locales/tr.yml +2 -1
- data/config/locales/uk.yml +2 -1
- data/config/locales/zh-CN.yml +2 -1
- data/config/locales/zh-TW.yml +2 -1
- data/config.ru +1 -1
- data/lib/comfortable_mexican_sofa/access_control/admin_authentication.rb +2 -1
- data/lib/comfortable_mexican_sofa/access_control/admin_authorization.rb +2 -0
- data/lib/comfortable_mexican_sofa/access_control/public_authentication.rb +3 -1
- data/lib/comfortable_mexican_sofa/access_control/public_authorization.rb +2 -0
- data/lib/comfortable_mexican_sofa/configuration.rb +27 -29
- data/lib/comfortable_mexican_sofa/content/block.rb +2 -1
- data/lib/comfortable_mexican_sofa/content/params_parser.rb +22 -21
- data/lib/comfortable_mexican_sofa/content/renderer.rb +10 -8
- data/lib/comfortable_mexican_sofa/content/tag.rb +1 -0
- data/lib/comfortable_mexican_sofa/content/tags/asset.rb +4 -3
- data/lib/comfortable_mexican_sofa/content/tags/checkbox.rb +3 -2
- data/lib/comfortable_mexican_sofa/content/tags/date.rb +4 -3
- data/lib/comfortable_mexican_sofa/content/tags/datetime.rb +4 -3
- data/lib/comfortable_mexican_sofa/content/tags/file.rb +15 -13
- data/lib/comfortable_mexican_sofa/content/tags/file_link.rb +8 -7
- data/lib/comfortable_mexican_sofa/content/tags/files.rb +15 -13
- data/lib/comfortable_mexican_sofa/content/tags/fragment.rb +7 -6
- data/lib/comfortable_mexican_sofa/content/tags/helper.rb +2 -1
- data/lib/comfortable_mexican_sofa/content/tags/markdown.rb +5 -4
- data/lib/comfortable_mexican_sofa/content/tags/number.rb +4 -3
- data/lib/comfortable_mexican_sofa/content/tags/partial.rb +1 -0
- data/lib/comfortable_mexican_sofa/content/tags/snippet.rb +3 -2
- data/lib/comfortable_mexican_sofa/content/tags/template.rb +1 -0
- data/lib/comfortable_mexican_sofa/content/tags/text.rb +4 -3
- data/lib/comfortable_mexican_sofa/content/tags/textarea.rb +4 -3
- data/lib/comfortable_mexican_sofa/content/tags/wysiwyg.rb +4 -3
- data/lib/comfortable_mexican_sofa/content.rb +21 -21
- data/lib/comfortable_mexican_sofa/engine.rb +17 -15
- data/lib/comfortable_mexican_sofa/error.rb +12 -6
- data/lib/comfortable_mexican_sofa/extensions/acts_as_tree.rb +17 -11
- data/lib/comfortable_mexican_sofa/extensions/has_revisions.rb +14 -13
- data/lib/comfortable_mexican_sofa/form_builder.rb +2 -2
- data/lib/comfortable_mexican_sofa/render_methods.rb +74 -76
- data/lib/comfortable_mexican_sofa/routes/cms.rb +4 -4
- data/lib/comfortable_mexican_sofa/routes/cms_admin.rb +2 -1
- data/lib/comfortable_mexican_sofa/routing.rb +4 -2
- data/lib/comfortable_mexican_sofa/seeds/file/exporter.rb +7 -6
- data/lib/comfortable_mexican_sofa/seeds/file/importer.rb +9 -9
- data/lib/comfortable_mexican_sofa/seeds/layout/exporter.rb +8 -7
- data/lib/comfortable_mexican_sofa/seeds/layout/importer.rb +11 -10
- data/lib/comfortable_mexican_sofa/seeds/page/exporter.rb +25 -23
- data/lib/comfortable_mexican_sofa/seeds/page/importer.rb +47 -43
- data/lib/comfortable_mexican_sofa/seeds/snippet/exporter.rb +7 -6
- data/lib/comfortable_mexican_sofa/seeds/snippet/importer.rb +7 -6
- data/lib/comfortable_mexican_sofa/seeds.rb +16 -9
- data/lib/comfortable_mexican_sofa/version.rb +4 -2
- data/lib/comfortable_mexican_sofa/view_hooks.rb +10 -9
- data/lib/comfortable_mexican_sofa.rb +30 -30
- data/lib/generators/comfy/cms/assets_generator.rb +6 -4
- data/lib/generators/comfy/cms/cms_generator.rb +14 -14
- data/lib/generators/comfy/cms/controllers_generator.rb +5 -3
- data/lib/generators/comfy/cms/models_generator.rb +5 -3
- data/lib/generators/comfy/cms/views_generator.rb +5 -3
- data/lib/generators/comfy/scaffold/scaffold_generator.rb +19 -18
- data/lib/tasks/cms_seeds.rake +4 -5
- data/test/controllers/comfy/admin/cms/base_controller_test.rb +4 -3
- data/test/controllers/comfy/admin/cms/categories_controller_test.rb +19 -18
- data/test/controllers/comfy/admin/cms/files_controller_test.rb +19 -19
- data/test/controllers/comfy/admin/cms/layouts_controller_test.rb +33 -32
- data/test/controllers/comfy/admin/cms/pages_controller_test.rb +99 -98
- data/test/controllers/comfy/admin/cms/revisions/layout_controller_test.rb +9 -9
- data/test/controllers/comfy/admin/cms/revisions/page_controller_test.rb +6 -6
- data/test/controllers/comfy/admin/cms/revisions/snippet_controller_test.rb +9 -8
- data/test/controllers/comfy/admin/cms/revisions/translation_controller_test.rb +6 -7
- data/test/controllers/comfy/admin/cms/sites_controller_test.rb +31 -30
- data/test/controllers/comfy/admin/cms/snippets_controller_test.rb +38 -37
- data/test/controllers/comfy/admin/cms/translations_controller_test.rb +21 -20
- data/test/controllers/comfy/cms/assets_controller_test.rb +14 -13
- data/test/controllers/comfy/cms/content_controller_test.rb +58 -57
- data/test/gemfiles/Gemfile.rails.5.2 +5 -4
- data/test/generators/cms_assets_generator_test.rb +6 -4
- data/test/generators/cms_controllers_generator_test.rb +7 -5
- data/test/generators/cms_generator_test.rb +12 -10
- data/test/generators/cms_models_generator_test.rb +7 -5
- data/test/generators/cms_views_generator_test.rb +6 -4
- data/test/generators/scaffold_generator_test.rb +18 -16
- data/test/helpers/cms_helper_test.rb +5 -2
- data/test/integration/access_control_test.rb +29 -20
- data/test/integration/i18n_test.rb +8 -7
- data/test/integration/js_variables_test.rb +2 -1
- data/test/integration/render_cms_test.rb +93 -88
- data/test/integration/routing_test.rb +4 -3
- data/test/integration/seeds_test.rb +21 -22
- data/test/integration/sites_test.rb +26 -25
- data/test/integration/view_hooks_test.rb +15 -14
- data/test/lib/configuration_test.rb +13 -15
- data/test/lib/content/block_test.rb +1 -1
- data/test/lib/content/params_parser_test.rb +11 -10
- data/test/lib/content/renderer_test.rb +16 -11
- data/test/lib/content/tag_test.rb +7 -3
- data/test/lib/content/tags/asset_test.rb +4 -3
- data/test/lib/content/tags/checkbox_test.rb +2 -1
- data/test/lib/content/tags/date_test.rb +2 -1
- data/test/lib/content/tags/datetime_test.rb +2 -1
- data/test/lib/content/tags/file_link_test.rb +3 -2
- data/test/lib/content/tags/file_test.rb +3 -2
- data/test/lib/content/tags/files_test.rb +4 -3
- data/test/lib/content/tags/fragment_test.rb +2 -1
- data/test/lib/content/tags/helper_test.rb +4 -3
- data/test/lib/content/tags/markdown_test.rb +2 -1
- data/test/lib/content/tags/number_test.rb +2 -1
- data/test/lib/content/tags/partial_test.rb +4 -3
- data/test/lib/content/tags/snippet_test.rb +2 -1
- data/test/lib/content/tags/template_test.rb +2 -1
- data/test/lib/content/tags/text_test.rb +2 -1
- data/test/lib/content/tags/textarea_test.rb +2 -1
- data/test/lib/content/tags/wysiwyg_test.rb +2 -1
- data/test/lib/revisions_test.rb +44 -42
- data/test/lib/seeds/files_test.rb +30 -29
- data/test/lib/seeds/layouts_test.rb +13 -12
- data/test/lib/seeds/pages_test.rb +32 -29
- data/test/lib/seeds/snippets_test.rb +21 -20
- data/test/lib/seeds_test.rb +9 -8
- data/test/models/categorization_test.rb +10 -9
- data/test/models/category_test.rb +1 -1
- data/test/models/file_test.rb +1 -1
- data/test/models/fragment_test.rb +11 -10
- data/test/models/layout_test.rb +71 -70
- data/test/models/page_test.rb +170 -159
- data/test/models/site_test.rb +17 -16
- data/test/models/snippet_test.rb +1 -0
- data/test/models/translation_test.rb +2 -1
- data/test/tasks/cms_seeds_test.rb +3 -2
- data/test/test_helper.rb +42 -40
- metadata +55 -51
- data/.rubocop_todo.yml +0 -974
- data/script/rails +0 -6
@@ -1,7 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
class Comfy::Cms::Layout < ActiveRecord::Base
|
4
|
-
|
2
|
+
|
3
|
+
self.table_name = "comfy_cms_layouts"
|
5
4
|
|
6
5
|
cms_acts_as_tree
|
7
6
|
cms_has_revisions_for :content, :css, :js
|
@@ -23,29 +22,29 @@ class Comfy::Cms::Layout < ActiveRecord::Base
|
|
23
22
|
presence: true
|
24
23
|
validates :identifier,
|
25
24
|
presence: true,
|
26
|
-
uniqueness: {scope: :site_id},
|
27
|
-
format: {with:
|
25
|
+
uniqueness: { scope: :site_id },
|
26
|
+
format: { with: %r{\A\w[a-z0-9_-]*\z}i }
|
28
27
|
|
29
28
|
# -- Class Methods -----------------------------------------------------------
|
30
29
|
# Tree-like structure for layouts
|
31
|
-
def self.options_for_select(site, layout = nil, current_layout = nil, depth = 0, spacer =
|
30
|
+
def self.options_for_select(site, layout = nil, current_layout = nil, depth = 0, spacer = ". . ")
|
32
31
|
out = []
|
33
|
-
[current_layout || site.layouts.roots].flatten.each do |l|
|
32
|
+
[current_layout || site.layouts.roots.order(:position)].flatten.each do |l|
|
34
33
|
next if layout == l
|
35
|
-
out << [
|
36
|
-
l.children.each do |child|
|
34
|
+
out << ["#{spacer * depth}#{l.label}", l.id]
|
35
|
+
l.children.order(:position).each do |child|
|
37
36
|
out += options_for_select(site, layout, child, depth + 1, spacer)
|
38
37
|
end
|
39
38
|
end
|
40
|
-
|
39
|
+
out.compact
|
41
40
|
end
|
42
41
|
|
43
42
|
# List of available application layouts
|
44
43
|
def self.app_layouts_for_select(view_paths)
|
45
44
|
view_paths.map(&:to_s).select { |path| path.start_with?(Rails.root.to_s) }.flat_map do |full_path|
|
46
45
|
Dir.glob("#{full_path}/layouts/**/*.html.*").collect do |filename|
|
47
|
-
filename.gsub!("#{full_path}/layouts/",
|
48
|
-
filename.split(
|
46
|
+
filename.gsub!("#{full_path}/layouts/", "")
|
47
|
+
filename.split("/").last[0...1] == "_" ? nil : filename.split(".").first
|
49
48
|
end.compact.sort
|
50
49
|
end.compact.uniq.sort
|
51
50
|
end
|
@@ -55,9 +54,9 @@ class Comfy::Cms::Layout < ActiveRecord::Base
|
|
55
54
|
# and merges on the {{cms:fragment content}} tag (if parent layout has that).
|
56
55
|
# Returns a list of tokens that can be fed into the renderer.
|
57
56
|
def content_tokens
|
57
|
+
renderer = ComfortableMexicanSofa::Content::Renderer.new(nil)
|
58
|
+
tokens = renderer.tokenize(content)
|
58
59
|
|
59
|
-
renderer = ComfortableMexicanSofa::Content::Renderer.new(nil)
|
60
|
-
tokens = renderer.tokenize(self.content)
|
61
60
|
if parent
|
62
61
|
fragment_tags = ComfortableMexicanSofa::Content::Tag::Fragment.subclasses.map do |c|
|
63
62
|
c.to_s.demodulize.underscore
|
@@ -66,7 +65,7 @@ class Comfy::Cms::Layout < ActiveRecord::Base
|
|
66
65
|
replacement_position = parent_tokens.index do |n|
|
67
66
|
n.is_a?(Hash) &&
|
68
67
|
fragment_tags.member?(n[:tag_class]) &&
|
69
|
-
n[:tag_params].split(
|
68
|
+
n[:tag_params].split(%r{\s}).first == "content"
|
70
69
|
end
|
71
70
|
if replacement_position
|
72
71
|
parent_tokens[replacement_position] = tokens
|
@@ -74,28 +73,29 @@ class Comfy::Cms::Layout < ActiveRecord::Base
|
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
77
|
-
|
76
|
+
tokens
|
78
77
|
end
|
79
78
|
|
80
79
|
def cache_buster
|
81
80
|
updated_at.to_i
|
82
81
|
end
|
83
82
|
|
83
|
+
# Forcing page content reload
|
84
|
+
def clear_page_content_cache
|
85
|
+
Comfy::Cms::Page.where(id: pages.pluck(:id)).update_all(content_cache: nil)
|
86
|
+
children.each(&:clear_page_content_cache)
|
87
|
+
end
|
88
|
+
|
84
89
|
protected
|
85
90
|
|
86
91
|
def assign_label
|
87
|
-
self.label =
|
92
|
+
self.label = label.blank? ? identifier.try(:titleize) : label
|
88
93
|
end
|
89
94
|
|
90
95
|
def assign_position
|
91
|
-
return if
|
92
|
-
max =
|
96
|
+
return if position.to_i > 0
|
97
|
+
max = site.layouts.where(parent_id: parent_id).maximum(:position)
|
93
98
|
self.position = max ? max + 1 : 0
|
94
99
|
end
|
95
100
|
|
96
|
-
# Forcing page content reload
|
97
|
-
def clear_page_content_cache
|
98
|
-
Comfy::Cms::Page.where(id: self.pages.pluck(:id)).update_all(content_cache: nil)
|
99
|
-
self.children.each{ |child_layout| child_layout.clear_page_content_cache }
|
100
|
-
end
|
101
101
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Comfy::Cms::Page < ActiveRecord::Base
|
2
|
-
|
2
|
+
|
3
|
+
self.table_name = "comfy_cms_pages"
|
3
4
|
|
4
5
|
include Comfy::Cms::WithFragments
|
5
6
|
include Comfy::Cms::WithCategories
|
@@ -10,7 +11,7 @@ class Comfy::Cms::Page < ActiveRecord::Base
|
|
10
11
|
# -- Relationships -----------------------------------------------------------
|
11
12
|
belongs_to :site
|
12
13
|
belongs_to :target_page,
|
13
|
-
class_name:
|
14
|
+
class_name: "Comfy::Cms::Page",
|
14
15
|
optional: true
|
15
16
|
|
16
17
|
has_many :translations,
|
@@ -30,9 +31,9 @@ class Comfy::Cms::Page < ActiveRecord::Base
|
|
30
31
|
presence: true
|
31
32
|
validates :slug,
|
32
33
|
presence: true,
|
33
|
-
uniqueness: {scope: :parent_id},
|
34
|
-
unless: ->
|
35
|
-
p.site && (p.site.pages.count
|
34
|
+
uniqueness: { scope: :parent_id },
|
35
|
+
unless: ->(p) {
|
36
|
+
p.site && (p.site.pages.count.zero? || p.site.pages.root == self)
|
36
37
|
}
|
37
38
|
validate :validate_target_page
|
38
39
|
validate :validate_format_of_unescaped_slug
|
@@ -42,37 +43,51 @@ class Comfy::Cms::Page < ActiveRecord::Base
|
|
42
43
|
|
43
44
|
# -- Class Methods -----------------------------------------------------------
|
44
45
|
# Tree-like structure for pages
|
45
|
-
def self.options_for_select(site
|
46
|
+
def self.options_for_select(site:, page: nil, current_page: nil, depth: 0, exclude_self: true, spacer: ". . ")
|
46
47
|
return [] if (current_page ||= site.pages.root) == page && exclude_self || !current_page
|
47
48
|
out = []
|
48
|
-
|
49
|
-
current_page
|
50
|
-
out
|
51
|
-
end
|
52
|
-
|
49
|
+
|
50
|
+
unless current_page == page
|
51
|
+
out << ["#{spacer * depth}#{current_page.label}", current_page.id]
|
52
|
+
end
|
53
|
+
|
54
|
+
if current_page.children_count.nonzero?
|
55
|
+
current_page.children.each do |child|
|
56
|
+
out += options_for_select(
|
57
|
+
site: site,
|
58
|
+
page: page,
|
59
|
+
current_page: child,
|
60
|
+
depth: depth + 1,
|
61
|
+
exclude_self: exclude_self,
|
62
|
+
spacer: spacer
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
out.compact
|
53
68
|
end
|
54
69
|
|
55
70
|
# -- Instance Methods --------------------------------------------------------
|
56
71
|
# For previewing purposes sometimes we need to have full_path set. This
|
57
72
|
# full path take care of the pages and its childs but not of the site path
|
58
73
|
def full_path
|
59
|
-
|
74
|
+
read_attribute(:full_path) || assign_full_path
|
60
75
|
end
|
61
76
|
|
62
77
|
# Somewhat unique method of identifying a page that is not a full_path
|
63
78
|
def identifier
|
64
|
-
|
79
|
+
parent_id.blank? ? "index" : full_path[1..-1].parameterize
|
65
80
|
end
|
66
81
|
|
67
82
|
# Full url for a page
|
68
83
|
def url(relative: false)
|
69
|
-
[
|
84
|
+
[site.url(relative: relative), full_path].compact.join
|
70
85
|
end
|
71
86
|
|
72
87
|
# This method will mutate page object by transfering attributes from translation
|
73
88
|
# for a given locale.
|
74
89
|
def translate!(locale)
|
75
|
-
translation =
|
90
|
+
translation = translations.published.find_by!(locale: locale)
|
76
91
|
self.layout = translation.layout
|
77
92
|
self.label = translation.label
|
78
93
|
self.content_cache = translation.content_cache
|
@@ -81,54 +96,57 @@ class Comfy::Cms::Page < ActiveRecord::Base
|
|
81
96
|
# This has odd side-effect of preserving page's fragments and just replacing
|
82
97
|
# them from the translation. Not an issue if all fragments match.
|
83
98
|
self.fragments_attributes = translation.fragments_attributes
|
84
|
-
|
99
|
+
readonly!
|
85
100
|
|
86
|
-
|
101
|
+
self
|
87
102
|
end
|
88
103
|
|
89
104
|
protected
|
90
105
|
|
91
106
|
def assigns_label
|
92
|
-
self.label =
|
107
|
+
self.label = label.blank? ? slug.try(:titleize) : label
|
93
108
|
end
|
94
109
|
|
95
110
|
def assign_parent
|
96
111
|
return unless site
|
97
|
-
self.parent ||= site.pages.root unless self == site.pages.root || site.pages.count
|
112
|
+
self.parent ||= site.pages.root unless self == site.pages.root || site.pages.count.zero?
|
98
113
|
end
|
99
114
|
|
100
115
|
def assign_full_path
|
101
|
-
self.full_path =
|
102
|
-
|
103
|
-
|
116
|
+
self.full_path =
|
117
|
+
if self.parent
|
118
|
+
[CGI.escape(self.parent.full_path).gsub("%2F", "/"), slug].join("/").squeeze("/")
|
119
|
+
else
|
120
|
+
"/"
|
121
|
+
end
|
104
122
|
end
|
105
123
|
|
106
124
|
def assign_position
|
107
125
|
return unless self.parent
|
108
|
-
return if
|
126
|
+
return if position.to_i > 0
|
109
127
|
max = self.parent.children.maximum(:position)
|
110
128
|
self.position = max ? max + 1 : 0
|
111
129
|
end
|
112
130
|
|
113
131
|
def validate_target_page
|
114
|
-
return unless
|
132
|
+
return unless target_page
|
115
133
|
p = self
|
116
|
-
while p.target_page
|
134
|
+
while p.target_page
|
117
135
|
if (p = p.target_page) == self
|
118
|
-
return
|
136
|
+
return errors.add(:target_page_id, "Invalid Redirect")
|
119
137
|
end
|
120
138
|
end
|
121
139
|
end
|
122
140
|
|
123
141
|
def validate_format_of_unescaped_slug
|
124
142
|
return unless slug.present?
|
125
|
-
unescaped_slug = CGI
|
126
|
-
errors.add(:slug, :invalid) unless unescaped_slug =~
|
143
|
+
unescaped_slug = CGI.unescape(slug)
|
144
|
+
errors.add(:slug, :invalid) unless unescaped_slug =~ %r{^\p{Alnum}[\.\p{Alnum}\p{Mark}_-]*$}i
|
127
145
|
end
|
128
146
|
|
129
147
|
# Forcing re-saves for child pages so they can update full_paths
|
130
148
|
def sync_child_full_paths!
|
131
|
-
return unless
|
149
|
+
return unless full_path_previously_changed?
|
132
150
|
children.each do |p|
|
133
151
|
p.update_attribute(:full_path, p.send(:assign_full_path))
|
134
152
|
end
|
@@ -136,12 +154,13 @@ protected
|
|
136
154
|
|
137
155
|
# Escape slug unless it's nonexistent (root)
|
138
156
|
def escape_slug
|
139
|
-
self.slug = CGI
|
157
|
+
self.slug = CGI.escape(slug) unless slug.nil?
|
140
158
|
end
|
141
159
|
|
142
160
|
# Unescape the slug and full path back into their original forms unless they're nonexistent
|
143
161
|
def unescape_slug_and_path
|
144
|
-
self.slug = CGI
|
145
|
-
self.full_path = CGI
|
162
|
+
self.slug = CGI.unescape(slug) unless slug.nil?
|
163
|
+
self.full_path = CGI.unescape(full_path) unless full_path.nil?
|
146
164
|
end
|
165
|
+
|
147
166
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Comfy::Cms::Site < ActiveRecord::Base
|
2
|
-
|
2
|
+
|
3
|
+
self.table_name = "comfy_cms_sites"
|
3
4
|
|
4
5
|
# -- Relationships -----------------------------------------------------------
|
5
6
|
with_options dependent: :destroy do |site|
|
@@ -20,13 +21,13 @@ class Comfy::Cms::Site < ActiveRecord::Base
|
|
20
21
|
validates :identifier,
|
21
22
|
presence: true,
|
22
23
|
uniqueness: true,
|
23
|
-
format: {with:
|
24
|
+
format: { with: %r{\A\w[a-z0-9_-]*\z}i }
|
24
25
|
validates :label,
|
25
26
|
presence: true
|
26
27
|
validates :hostname,
|
27
28
|
presence: true,
|
28
|
-
uniqueness: {scope: :path},
|
29
|
-
format: {with:
|
29
|
+
uniqueness: { scope: :path },
|
30
|
+
format: { with: %r{\A[\w.-]+(?:\:\d+)?\z} }
|
30
31
|
|
31
32
|
# -- Class Methods -----------------------------------------------------------
|
32
33
|
# returning the Comfy::Cms::Site instance based on host and path
|
@@ -34,56 +35,56 @@ class Comfy::Cms::Site < ActiveRecord::Base
|
|
34
35
|
return Comfy::Cms::Site.first if Comfy::Cms::Site.count == 1
|
35
36
|
cms_site = nil
|
36
37
|
|
37
|
-
|
38
38
|
public_cms_path = ComfortableMexicanSofa.configuration.public_cms_path
|
39
|
-
path.gsub!(
|
39
|
+
path.gsub!(%r{\A#{public_cms_path}}, "") unless path.nil? || public_cms_path == "/"
|
40
40
|
|
41
41
|
Comfy::Cms::Site.where(hostname: real_host_from_aliases(host)).each do |site|
|
42
42
|
if site.path.blank?
|
43
43
|
cms_site = site
|
44
|
-
elsif "#{path.to_s.split('?')[0]}/"
|
44
|
+
elsif "#{path.to_s.split('?')[0]}/" =~ %r{^/#{Regexp.escape(site.path.to_s)}/}
|
45
45
|
cms_site = site
|
46
46
|
break
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
49
|
+
cms_site
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.real_host_from_aliases(host)
|
53
|
+
if (aliases = ComfortableMexicanSofa.config.hostname_aliases)
|
54
|
+
aliases.each do |alias_host, hosts|
|
55
|
+
return alias_host if hosts.include?(host)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
host
|
50
59
|
end
|
51
60
|
|
52
61
|
# -- Instance Methods --------------------------------------------------------
|
53
62
|
def url(relative: false)
|
54
|
-
public_cms_path = ComfortableMexicanSofa.config.public_cms_path ||
|
55
|
-
host = "//#{
|
56
|
-
path = [
|
63
|
+
public_cms_path = ComfortableMexicanSofa.config.public_cms_path || "/"
|
64
|
+
host = "//#{hostname}"
|
65
|
+
path = ["/", public_cms_path, self.path].compact.join("/").squeeze("/").chomp("/")
|
57
66
|
relative ? path.presence : [host, path].join
|
58
67
|
end
|
59
68
|
|
60
69
|
protected
|
61
70
|
|
62
|
-
def self.real_host_from_aliases(host)
|
63
|
-
if aliases = ComfortableMexicanSofa.config.hostname_aliases
|
64
|
-
aliases.each do |alias_host, aliases|
|
65
|
-
return alias_host if aliases.include?(host)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
host
|
69
|
-
end
|
70
|
-
|
71
71
|
def assign_identifier
|
72
|
-
self.identifier =
|
72
|
+
self.identifier = identifier.blank? ? hostname.try(:parameterize) : identifier
|
73
73
|
end
|
74
74
|
|
75
75
|
def assign_hostname
|
76
|
-
self.hostname ||=
|
76
|
+
self.hostname ||= identifier
|
77
77
|
end
|
78
78
|
|
79
79
|
def assign_label
|
80
|
-
self.label =
|
80
|
+
self.label = label.blank? ? identifier.try(:titleize) : label
|
81
81
|
end
|
82
82
|
|
83
83
|
def clean_path
|
84
|
-
self.path ||=
|
85
|
-
self.path.squeeze!(
|
86
|
-
self.path.gsub!(
|
84
|
+
self.path ||= ""
|
85
|
+
self.path.squeeze!("/")
|
86
|
+
self.path.gsub!(%r{/$}, "")
|
87
87
|
self.path = nil if self.path.blank?
|
88
88
|
end
|
89
|
+
|
89
90
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Comfy::Cms::Snippet < ActiveRecord::Base
|
2
|
-
|
2
|
+
|
3
|
+
self.table_name = "comfy_cms_snippets"
|
3
4
|
|
4
5
|
include Comfy::Cms::WithCategories
|
5
6
|
|
@@ -19,13 +20,13 @@ class Comfy::Cms::Snippet < ActiveRecord::Base
|
|
19
20
|
presence: true
|
20
21
|
validates :identifier,
|
21
22
|
presence: true,
|
22
|
-
uniqueness: {scope: :site_id},
|
23
|
-
format: {with:
|
23
|
+
uniqueness: { scope: :site_id },
|
24
|
+
format: { with: %r{\A\w[a-z0-9_-]*\z}i }
|
24
25
|
|
25
26
|
protected
|
26
27
|
|
27
28
|
def assign_label
|
28
|
-
self.label =
|
29
|
+
self.label = label.blank? ? identifier.try(:titleize) : label
|
29
30
|
end
|
30
31
|
|
31
32
|
# When snippet is changed or removed we need to blow away all page caches as
|
@@ -35,7 +36,8 @@ protected
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def assign_position
|
38
|
-
max =
|
39
|
+
max = site.snippets.maximum(:position)
|
39
40
|
self.position = max ? max + 1 : 0
|
40
41
|
end
|
42
|
+
|
41
43
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
class Comfy::Cms::Translation < ActiveRecord::Base
|
2
|
+
|
2
3
|
self.table_name = "comfy_cms_translations"
|
3
4
|
|
4
5
|
include Comfy::Cms::WithFragments
|
@@ -20,18 +21,19 @@ class Comfy::Cms::Translation < ActiveRecord::Base
|
|
20
21
|
|
21
22
|
validates :locale,
|
22
23
|
presence: true,
|
23
|
-
uniqueness: {scope: :page_id}
|
24
|
+
uniqueness: { scope: :page_id }
|
24
25
|
|
25
26
|
validate :validate_locale
|
26
27
|
|
27
28
|
private
|
28
29
|
|
29
30
|
def validate_locale
|
30
|
-
return unless
|
31
|
-
errors.add(:locale) if
|
31
|
+
return unless page
|
32
|
+
errors.add(:locale) if locale == page.site.locale
|
32
33
|
end
|
33
34
|
|
34
35
|
def assign_layout
|
35
|
-
self.layout ||=
|
36
|
+
self.layout ||= page.layout if page.present?
|
36
37
|
end
|
38
|
+
|
37
39
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Comfy::Cms::WithCategories
|
2
|
+
|
2
3
|
extend ActiveSupport::Concern
|
3
4
|
|
4
5
|
included do
|
@@ -14,25 +15,26 @@ module Comfy::Cms::WithCategories
|
|
14
15
|
|
15
16
|
after_save :sync_categories
|
16
17
|
|
17
|
-
scope :for_category, ->
|
18
|
+
scope :for_category, ->(*categories) {
|
18
19
|
if (categories = [categories].flatten.compact).present?
|
19
|
-
|
20
|
-
joins(categorizations: :category)
|
21
|
-
where("comfy_cms_categories.label" => categories)
|
20
|
+
distinct
|
21
|
+
.joins(categorizations: :category)
|
22
|
+
.where("comfy_cms_categories.label" => categories)
|
22
23
|
end
|
23
24
|
}
|
24
25
|
end
|
25
26
|
|
26
27
|
def sync_categories
|
27
|
-
(
|
28
|
+
(category_ids || {}).each do |category_id, flag|
|
28
29
|
case flag.to_i
|
29
30
|
when 1
|
30
|
-
if category = Comfy::Cms::Category.find_by_id(category_id)
|
31
|
+
if (category = Comfy::Cms::Category.find_by_id(category_id))
|
31
32
|
category.categorizations.create(categorized: self)
|
32
33
|
end
|
33
34
|
when 0
|
34
|
-
|
35
|
+
categorizations.where(category_id: category_id).destroy_all
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
39
|
+
|
38
40
|
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
module Comfy::Cms::WithFragments
|
2
|
+
|
2
3
|
extend ActiveSupport::Concern
|
3
4
|
|
4
5
|
included do
|
5
6
|
attr_accessor :fragments_attributes_changed
|
6
7
|
|
7
8
|
belongs_to :layout,
|
8
|
-
class_name:
|
9
|
+
class_name: "Comfy::Cms::Layout"
|
9
10
|
|
10
11
|
has_many :fragments,
|
11
|
-
class_name:
|
12
|
+
class_name: "Comfy::Cms::Fragment",
|
12
13
|
as: :record,
|
13
14
|
autosave: true,
|
14
15
|
dependent: :destroy
|
@@ -40,8 +41,8 @@ module Comfy::Cms::WithFragments
|
|
40
41
|
identifier = frag_attrs.delete(:identifier)
|
41
42
|
|
42
43
|
fragment =
|
43
|
-
|
44
|
-
|
44
|
+
fragments.detect { |f| f.identifier == identifier } ||
|
45
|
+
fragments.build(identifier: identifier)
|
45
46
|
|
46
47
|
fragment.attributes = frag_attrs
|
47
48
|
|
@@ -52,9 +53,9 @@ module Comfy::Cms::WithFragments
|
|
52
53
|
|
53
54
|
# Snapshop of page fragments data used primarily for saving revisions
|
54
55
|
def fragments_attributes(was = false)
|
55
|
-
|
56
|
+
fragments.collect do |frag|
|
56
57
|
attrs = {}
|
57
|
-
%i
|
58
|
+
%i[identifier tag content datetime boolean].each do |column|
|
58
59
|
attrs[column] = frag.send(was ? "#{column}_was" : column)
|
59
60
|
end
|
60
61
|
# TODO: save files against revision (not on db though)
|
@@ -75,8 +76,8 @@ module Comfy::Cms::WithFragments
|
|
75
76
|
# duplicate tags on the layout. That's wierd (but still works).
|
76
77
|
def fragment_nodes
|
77
78
|
nodes
|
78
|
-
.select{|n| n.is_a?(ComfortableMexicanSofa::Content::Tag::Fragment)}
|
79
|
-
.uniq
|
79
|
+
.select { |n| n.is_a?(ComfortableMexicanSofa::Content::Tag::Fragment) }
|
80
|
+
.uniq(&:identifier)
|
80
81
|
end
|
81
82
|
|
82
83
|
# Rendered content of the page. We grab whatever layout is associated with the
|
@@ -90,15 +91,15 @@ module Comfy::Cms::WithFragments
|
|
90
91
|
# page.
|
91
92
|
def content_cache
|
92
93
|
if (cache = read_attribute(:content_cache)).nil?
|
93
|
-
cache =
|
94
|
-
update_column(:content_cache, cache) unless
|
94
|
+
cache = render
|
95
|
+
update_column(:content_cache, cache) unless new_record?
|
95
96
|
end
|
96
97
|
cache
|
97
98
|
end
|
98
99
|
|
99
100
|
# Nuking content cache so it can be regenerated.
|
100
101
|
def clear_content_cache!
|
101
|
-
|
102
|
+
update_column(:content_cache, nil)
|
102
103
|
end
|
103
104
|
|
104
105
|
# Blanking cache on page saves so it can be regenerated on access
|
@@ -113,9 +114,10 @@ protected
|
|
113
114
|
end
|
114
115
|
|
115
116
|
def nodes
|
116
|
-
return [] unless
|
117
|
+
return [] unless layout.present?
|
117
118
|
|
118
|
-
tokens =
|
119
|
+
tokens = layout.content_tokens
|
119
120
|
renderer.nodes(tokens)
|
120
121
|
end
|
122
|
+
|
121
123
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
%li{id: dom_id(file)}
|
2
2
|
.row
|
3
|
-
.col-md-
|
3
|
+
.col-md-5.item
|
4
4
|
.item-controls.d-none.d-lg-block
|
5
5
|
- if !params[:categories].present? && @site.files.count > 1
|
6
6
|
.dragger
|
@@ -19,8 +19,8 @@
|
|
19
19
|
.file-size
|
20
20
|
= number_to_human_size(file.attachment.byte_size)
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
.col-md-2.item-categories.d-flex.align-items-center
|
23
|
+
= render partial: "comfy/admin/cms/categories/categories", object: file
|
24
24
|
|
25
25
|
.col-md-2.d-flex.align-items-center
|
26
26
|
- file_tag = "{{cms:file_link #{file.id} }}"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
.modal.fade.cms-files-modal{'aria-hidden' => 'true', 'data-iframe-src' => comfy_admin_cms_site_files_path(@site), :
|
1
|
+
.modal.fade.cms-files-modal{'aria-hidden' => 'true', 'data-iframe-src' => comfy_admin_cms_site_files_path(@site), role: 'dialog', tabindex: "-1"}
|
2
2
|
.modal-dialog.modal-lg
|
3
3
|
.modal-content
|
4
|
-
%iframe{:
|
4
|
+
%iframe{src: ''}
|
File without changes
|
File without changes
|
@@ -4,7 +4,7 @@
|
|
4
4
|
%li{id: dom_id(layout)}
|
5
5
|
.row
|
6
6
|
.col-md-8.item
|
7
|
-
.item-controls.d-none.d-
|
7
|
+
.item-controls.d-none.d-md-block
|
8
8
|
- if has_siblings
|
9
9
|
.dragger
|
10
10
|
= fa_icon("bars")
|
@@ -22,5 +22,5 @@
|
|
22
22
|
= link_to t('.delete'), comfy_admin_cms_site_layout_path(@site, layout), method: :delete, data: {confirm: t('.are_you_sure')}, class: "btn btn-danger"
|
23
23
|
|
24
24
|
- if layout.children.present?
|
25
|
-
%ul.list.children.sortable
|
25
|
+
%ul.list.children.sortable.pl-md-3
|
26
26
|
= render partial: "index_branch", collection: layout.children.order(:position)
|