comfy_middle_seat 3.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/coveralls.yml +4 -0
- data/CHANGELOG.md +56 -3
- data/CONTRIBUTING.md +8 -5
- data/Gemfile +1 -1
- data/README.md +66 -29
- data/Rakefile +3 -3
- data/app/assets/javascripts/comfy/admin/cms/application.js +2 -0
- data/app/assets/javascripts/comfy/admin/cms/base.js +6 -1
- data/app/assets/javascripts/comfy/admin/cms/codemirror.js +17 -0
- data/app/assets/javascripts/comfy/admin/cms/dirty_forms.js +201 -0
- data/app/assets/javascripts/comfy/admin/cms/draft_forms.js +468 -0
- data/app/assets/javascripts/comfy/admin/cms/page_fragments.js +393 -22
- data/app/assets/javascripts/comfy/admin/cms/wysiwyg.js +21 -0
- data/app/assets/javascripts/comfy/vendor/redactor/filemanager.js +48 -30
- data/app/assets/javascripts/comfy/vendor/redactor/imagemanager.js +43 -25
- data/app/assets/stylesheets/comfy/admin/cms/base.sass +23 -0
- data/app/controllers/comfy/admin/base_controller.rb +3 -3
- data/app/controllers/comfy/admin/cms/base_controller.rb +12 -7
- data/app/controllers/comfy/admin/cms/files_controller.rb +1 -1
- data/app/controllers/comfy/admin/cms/pages_controller.rb +76 -16
- data/app/controllers/comfy/admin/cms/revisions/base_controller.rb +39 -1
- data/app/controllers/comfy/admin/cms/revisions/page_controller.rb +9 -8
- data/app/controllers/comfy/admin/cms/revisions/translation_controller.rb +14 -8
- data/app/controllers/comfy/admin/cms/sites_controller.rb +1 -1
- data/app/controllers/comfy/admin/cms/translations_controller.rb +3 -1
- data/app/controllers/comfy/cms/base_controller.rb +1 -1
- data/app/controllers/comfy/cms/content_controller.rb +5 -5
- data/app/controllers/concerns/comfy/reorder_action.rb +24 -4
- data/app/helpers/comfy/admin/cms_helper.rb +28 -3
- data/app/helpers/comfy/cms_helper.rb +1 -1
- data/app/models/comfy/cms/file.rb +25 -3
- data/app/models/comfy/cms/layout.rb +8 -6
- data/app/models/comfy/cms/page.rb +22 -0
- data/app/models/comfy/cms/site.rb +3 -3
- data/app/models/comfy/cms/snippet.rb +8 -3
- data/app/models/concerns/comfy/cms/with_fragments.rb +2 -2
- data/app/views/comfy/admin/cms/categories/_index.html.haml +1 -1
- data/app/views/comfy/admin/cms/categories/_show.html.haml +1 -1
- data/app/views/comfy/admin/cms/files/_file.html.haml +1 -1
- data/app/views/comfy/admin/cms/files/index.html.haml +9 -2
- data/app/views/comfy/admin/cms/fragments/_form_fragments.html.haml +2 -2
- data/app/views/comfy/admin/cms/pages/_form.html.haml +2 -1
- data/app/views/comfy/admin/cms/pages/_index_branch.html.haml +11 -10
- data/app/views/comfy/admin/cms/pages/edit.html.haml +3 -1
- data/app/views/comfy/admin/cms/pages/index.html.haml +9 -2
- data/app/views/comfy/admin/cms/pages/new.html.haml +3 -1
- data/app/views/comfy/admin/cms/pages/toggle_branch.js.erb +2 -2
- data/app/views/comfy/admin/cms/revisions/show.html.haml +25 -7
- data/app/views/comfy/admin/cms/shared/_search.html.haml +9 -0
- data/app/views/comfy/admin/cms/sites/_form.html.haml +1 -1
- data/app/views/comfy/admin/cms/translations/_form.html.haml +2 -1
- data/app/views/comfy/admin/cms/translations/edit.html.haml +3 -1
- data/app/views/comfy/admin/cms/translations/new.html.haml +3 -1
- data/app/views/layouts/comfy/admin/cms/_flash.html.haml +1 -1
- data/app/views/layouts/comfy/admin/cms/_head.html.haml +3 -1
- data/app/views/layouts/comfy/admin/cms/_left.html.haml +2 -2
- data/comfy_middle_seat.gemspec +10 -5
- data/config/application.rb +3 -2
- data/config/cms_routes.rb +1 -1
- data/config/environment.rb +1 -1
- data/config/environments/development.rb +1 -1
- data/config/environments/production.rb +1 -1
- data/config/environments/test.rb +1 -1
- data/config/initializers/{comfortable_media_surfer.rb → comfy_middle_seat.rb} +4 -4
- data/config/locales/ar.yml +14 -0
- data/config/locales/ca.yml +14 -0
- data/config/locales/cs.yml +14 -0
- data/config/locales/da.yml +14 -0
- data/config/locales/de.yml +14 -0
- data/config/locales/en.yml +14 -0
- data/config/locales/es.yml +14 -0
- data/config/locales/fi.yml +14 -0
- data/config/locales/fr.yml +14 -0
- data/config/locales/gr.yml +14 -0
- data/config/locales/hr.yml +14 -0
- data/config/locales/it.yml +14 -0
- data/config/locales/ja.yml +14 -0
- data/config/locales/nb.yml +14 -0
- data/config/locales/nl.yml +14 -0
- data/config/locales/pl.yml +14 -0
- data/config/locales/pt-BR.yml +14 -0
- data/config/locales/ru.yml +14 -0
- data/config/locales/sk.yml +14 -0
- data/config/locales/sv.yml +14 -0
- data/config/locales/tr.yml +14 -0
- data/config/locales/uk.yml +14 -0
- data/config/locales/zh-CN.yml +14 -0
- data/config/locales/zh-TW.yml +14 -0
- data/config.ru +1 -1
- data/exe/comfy-middle-seat-upgrade +34 -0
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/admin_authentication.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/admin_authorization.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/public_authentication.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/access_control/public_authorization.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/configuration.rb +7 -7
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/block.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/params_parser.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/renderer.rb +10 -10
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tag.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/asset.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/audio.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/breadcrumbs.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/checkbox.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/children.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/date.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/datetime.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/file.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/file_link.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/files.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/fragment.rb +2 -2
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/helper.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/image.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/markdown.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/mixins/file_content.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/number.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/page_file_link.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/partial.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/siblings.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/snippet.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/template.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/text.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/textarea.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags/wysiwyg.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content/tags.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/content.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/engine.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/error.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/extensions/acts_as_tree.rb +3 -3
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/extensions/has_revisions.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/extensions.rb +1 -1
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/form_builder.rb +2 -2
- data/lib/comfy_middle_seat/initializer_upgrader.rb +115 -0
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/render_methods.rb +7 -7
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/routing.rb +3 -2
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/file/exporter.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/file/importer.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/layout/exporter.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/layout/importer.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/page/exporter.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/page/importer.rb +7 -7
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/snippet/exporter.rb +4 -4
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds/snippet/importer.rb +5 -5
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/seeds.rb +4 -4
- data/lib/comfy_middle_seat/version.rb +2 -2
- data/lib/{comfortable_media_surfer → comfy_middle_seat}/view_hooks.rb +2 -2
- data/lib/comfy_middle_seat.rb +54 -1
- data/lib/generators/comfy/cms/README +3 -11
- data/lib/generators/comfy/cms/cms_generator.rb +2 -2
- data/lib/generators/comfy/scaffold/templates/tests/controller.rb.tt +2 -2
- data/lib/tasks/cms_seeds.rake +8 -8
- data/package-lock.json +2 -2
- data/package.json +1 -1
- metadata +68 -62
- data/lib/comfortable_media_surfer/version.rb +0 -3
- data/lib/comfortable_media_surfer.rb +0 -56
|
@@ -8,12 +8,12 @@ class Comfy::Admin::Cms::BaseController < Comfy::Admin::BaseController
|
|
|
8
8
|
|
|
9
9
|
layout :infer_layout
|
|
10
10
|
|
|
11
|
-
if
|
|
12
|
-
cache_sweeper(*
|
|
11
|
+
if ComfyMiddleSeat.config.admin_cache_sweeper.present?
|
|
12
|
+
cache_sweeper(*ComfyMiddleSeat.config.admin_cache_sweeper)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def jump
|
|
16
|
-
path =
|
|
16
|
+
path = ComfyMiddleSeat.config.admin_route_redirect
|
|
17
17
|
return redirect_to(path) unless path.blank?
|
|
18
18
|
|
|
19
19
|
load_admin_site
|
|
@@ -27,24 +27,29 @@ protected
|
|
|
27
27
|
if (@site = ::Comfy::Cms::Site.find_by(id: id_param) || ::Comfy::Cms::Site.first)
|
|
28
28
|
session[:site_id] = @site.id
|
|
29
29
|
else
|
|
30
|
-
I18n.locale =
|
|
30
|
+
I18n.locale = ComfyMiddleSeat.config.admin_locale || I18n.default_locale
|
|
31
31
|
flash[:danger] = I18n.t('comfy.admin.cms.base.site_not_found')
|
|
32
32
|
redirect_to(new_comfy_admin_cms_site_path)
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def set_locale?
|
|
37
|
-
I18n.locale =
|
|
37
|
+
I18n.locale = ComfyMiddleSeat.config.admin_locale || @site&.locale
|
|
38
38
|
true
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
def acknowledge_draft_save
|
|
42
|
+
key = params[:cms_draft_key].to_s
|
|
43
|
+
flash[:cms_saved_draft_key] = key if key.start_with?('comfy-cms:draft:v1:')
|
|
44
|
+
end
|
|
45
|
+
|
|
41
46
|
def load_seeds
|
|
42
|
-
return unless
|
|
47
|
+
return unless ComfyMiddleSeat.config.enable_seeds
|
|
43
48
|
|
|
44
49
|
controllers = %w[layouts pages snippets files].collect { |c| "comfy/admin/cms/#{c}" }
|
|
45
50
|
return unless controllers.member?(params[:controller]) && params[:action] == 'index'
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
ComfyMiddleSeat::Seeds::Importer.new(@site.identifier).import!
|
|
48
53
|
flash.now[:warning] = I18n.t('comfy.admin.cms.base.seeds_enabled')
|
|
49
54
|
end
|
|
50
55
|
|
|
@@ -12,7 +12,7 @@ class Comfy::Admin::Cms::FilesController < Comfy::Admin::Cms::BaseController
|
|
|
12
12
|
before_action :authorize
|
|
13
13
|
|
|
14
14
|
def index
|
|
15
|
-
files_scope = @site.files.with_attached_attachment
|
|
15
|
+
files_scope = @site.files.with_attached_attachment.search(params[:q])
|
|
16
16
|
|
|
17
17
|
case params[:source]
|
|
18
18
|
|
|
@@ -8,6 +8,8 @@ class Comfy::Admin::Cms::PagesController < Comfy::Admin::Cms::BaseController
|
|
|
8
8
|
|
|
9
9
|
include ::Comfy::ReorderAction
|
|
10
10
|
|
|
11
|
+
helper_method :page_branch_open?
|
|
12
|
+
|
|
11
13
|
self.reorder_action_resource = ::Comfy::Cms::Page
|
|
12
14
|
|
|
13
15
|
before_action :check_for_layouts, only: %i[new edit]
|
|
@@ -23,14 +25,18 @@ class Comfy::Admin::Cms::PagesController < Comfy::Admin::Cms::BaseController
|
|
|
23
25
|
|
|
24
26
|
return index_for_redactor if params[:source] == 'redactor'
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
if page_filters?
|
|
29
|
+
@pages_by_parent = {}
|
|
30
|
+
@pages = @site.pages
|
|
31
|
+
.includes(:categories)
|
|
32
|
+
.for_category(params[:categories])
|
|
33
|
+
.search(params[:q])
|
|
34
|
+
.order(:label)
|
|
35
|
+
else
|
|
36
|
+
root = @site.pages.roots.includes(:categories).first
|
|
37
|
+
@pages = [root].compact
|
|
38
|
+
@pages_by_parent = pages_grouped_for_open_tree(root)
|
|
39
|
+
end
|
|
34
40
|
end
|
|
35
41
|
|
|
36
42
|
def new
|
|
@@ -49,6 +55,7 @@ class Comfy::Admin::Cms::PagesController < Comfy::Admin::Cms::BaseController
|
|
|
49
55
|
def create
|
|
50
56
|
@page.save!
|
|
51
57
|
update_family
|
|
58
|
+
acknowledge_draft_save
|
|
52
59
|
flash[:success] = I18n.t('comfy.admin.cms.pages.created')
|
|
53
60
|
redirect_to action: :edit, id: @page
|
|
54
61
|
rescue ActiveRecord::RecordInvalid
|
|
@@ -59,6 +66,7 @@ class Comfy::Admin::Cms::PagesController < Comfy::Admin::Cms::BaseController
|
|
|
59
66
|
def update
|
|
60
67
|
@page.save!
|
|
61
68
|
update_family
|
|
69
|
+
acknowledge_draft_save
|
|
62
70
|
flash[:success] = I18n.t('comfy.admin.cms.pages.updated')
|
|
63
71
|
redirect_to action: :edit, id: @page
|
|
64
72
|
rescue ActiveRecord::RecordInvalid
|
|
@@ -67,7 +75,15 @@ class Comfy::Admin::Cms::PagesController < Comfy::Admin::Cms::BaseController
|
|
|
67
75
|
end
|
|
68
76
|
|
|
69
77
|
def destroy
|
|
70
|
-
@page.
|
|
78
|
+
if @page.root?
|
|
79
|
+
flash[:danger] = I18n.t(
|
|
80
|
+
'comfy.admin.cms.pages.root_delete_failure',
|
|
81
|
+
default: 'The root page cannot be deleted.'
|
|
82
|
+
)
|
|
83
|
+
return redirect_to action: :index
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
@page.destroy!
|
|
71
87
|
update_family
|
|
72
88
|
flash[:success] = I18n.t('comfy.admin.cms.pages.deleted')
|
|
73
89
|
redirect_to action: :index
|
|
@@ -85,13 +101,21 @@ class Comfy::Admin::Cms::PagesController < Comfy::Admin::Cms::BaseController
|
|
|
85
101
|
end
|
|
86
102
|
|
|
87
103
|
def toggle_branch
|
|
88
|
-
@pages_by_parent = pages_grouped_by_parent
|
|
89
104
|
@page = @site.pages.find(params[:id])
|
|
90
|
-
|
|
91
|
-
id
|
|
92
|
-
|
|
105
|
+
tree = page_tree_session
|
|
106
|
+
id = @page.id.to_s
|
|
107
|
+
|
|
108
|
+
if tree.member?(id)
|
|
109
|
+
tree.delete(id)
|
|
110
|
+
@branch_open = false
|
|
111
|
+
@pages_by_parent = {}
|
|
112
|
+
else
|
|
113
|
+
tree << id
|
|
114
|
+
@branch_open = true
|
|
115
|
+
@pages_by_parent = pages_grouped_for_open_tree(@page)
|
|
116
|
+
end
|
|
93
117
|
rescue ActiveRecord::RecordNotFound
|
|
94
|
-
|
|
118
|
+
head :not_found
|
|
95
119
|
end
|
|
96
120
|
|
|
97
121
|
def publish_children
|
|
@@ -138,8 +162,44 @@ protected
|
|
|
138
162
|
@site.pages.none?
|
|
139
163
|
end
|
|
140
164
|
|
|
141
|
-
def
|
|
142
|
-
|
|
165
|
+
def pages_grouped_for_open_tree(parent)
|
|
166
|
+
return {} unless parent
|
|
167
|
+
|
|
168
|
+
pages_by_parent = {}
|
|
169
|
+
open_ids = session_open_page_ids
|
|
170
|
+
parent_ids = [parent.id]
|
|
171
|
+
|
|
172
|
+
while parent_ids.present?
|
|
173
|
+
children = @site.pages
|
|
174
|
+
.where(parent_id: parent_ids)
|
|
175
|
+
.includes(:categories)
|
|
176
|
+
.order(:parent_id, :position, :id)
|
|
177
|
+
.to_a
|
|
178
|
+
pages_by_parent.merge!(children.group_by(&:parent_id))
|
|
179
|
+
parent_ids = children.filter_map { |page| page.id if open_ids.include?(page.id) }
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
pages_by_parent
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def page_branch_open?(page)
|
|
186
|
+
page.root? || page_tree_session.member?(page.id.to_s)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def page_tree_session
|
|
190
|
+
trees = session[:cms_page_tree]
|
|
191
|
+
trees = session[:cms_page_tree] = {} unless trees.is_a?(Hash)
|
|
192
|
+
trees[@site.id.to_s] ||= []
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def session_open_page_ids
|
|
196
|
+
page_tree_session.filter_map do |id|
|
|
197
|
+
id.to_i if id.to_s.match?(%r{\A[1-9]\d*\z})
|
|
198
|
+
end.to_set
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def page_filters?
|
|
202
|
+
params[:categories].present? || params[:q].present?
|
|
143
203
|
end
|
|
144
204
|
|
|
145
205
|
def check_for_layouts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Comfy::Admin::Cms::Revisions::BaseController < Comfy::Admin::Cms::BaseController
|
|
4
|
-
helper_method :record_path
|
|
4
|
+
helper_method :record_path, :preview_path
|
|
5
5
|
|
|
6
6
|
before_action :load_record
|
|
7
7
|
before_action :load_revision, except: :index
|
|
@@ -31,6 +31,40 @@ class Comfy::Admin::Cms::Revisions::BaseController < Comfy::Admin::Cms::BaseCont
|
|
|
31
31
|
|
|
32
32
|
protected
|
|
33
33
|
|
|
34
|
+
def load_fragment_content
|
|
35
|
+
current_content = @record.fragments.to_h do |fragment|
|
|
36
|
+
[fragment.identifier, fragment.content]
|
|
37
|
+
end
|
|
38
|
+
versioned_content = @revision.data.fetch('fragments_attributes', []).to_h do |attributes|
|
|
39
|
+
attributes = attributes.with_indifferent_access
|
|
40
|
+
[attributes[:identifier], attributes[:content]]
|
|
41
|
+
end
|
|
42
|
+
identifiers = current_content.keys | versioned_content.keys
|
|
43
|
+
|
|
44
|
+
@current_content = identifiers.to_h { |identifier| [identifier, current_content[identifier]] }
|
|
45
|
+
@versioned_content = identifiers.to_h { |identifier| [identifier, versioned_content[identifier]] }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def render_fragment_preview(cms_page:, locale:)
|
|
49
|
+
apply_revision_in_memory
|
|
50
|
+
|
|
51
|
+
@cms_site = @record.site
|
|
52
|
+
@cms_layout = @record.layout
|
|
53
|
+
@cms_page = cms_page
|
|
54
|
+
|
|
55
|
+
I18n.locale = locale
|
|
56
|
+
response.headers['X-XSS-Protection'] = '0'
|
|
57
|
+
|
|
58
|
+
app_layout = @cms_layout.app_layout.presence || false
|
|
59
|
+
render inline: @record.render, layout: app_layout, content_type: 'text/html'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def apply_revision_in_memory
|
|
63
|
+
@record.fragments.load_target
|
|
64
|
+
@record.fragments.target.clear
|
|
65
|
+
@record.assign_attributes(@revision.data.deep_dup)
|
|
66
|
+
end
|
|
67
|
+
|
|
34
68
|
def load_record
|
|
35
69
|
raise 'not implemented'
|
|
36
70
|
end
|
|
@@ -45,4 +79,8 @@ protected
|
|
|
45
79
|
def record_path
|
|
46
80
|
raise 'not implemented'
|
|
47
81
|
end
|
|
82
|
+
|
|
83
|
+
def preview_path
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
48
86
|
end
|
|
@@ -2,17 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
class Comfy::Admin::Cms::Revisions::PageController < Comfy::Admin::Cms::Revisions::BaseController
|
|
4
4
|
def show
|
|
5
|
-
|
|
6
|
-
[fragment.identifier, fragment.content]
|
|
7
|
-
end
|
|
8
|
-
@versioned_content = @record.fragments.to_h do |fragment|
|
|
9
|
-
data = @revision.data['fragments_attributes'].detect { |item| item[:identifier] == fragment.identifier }
|
|
10
|
-
[fragment.identifier, data.try(:[], :content)]
|
|
11
|
-
end
|
|
12
|
-
|
|
5
|
+
load_fragment_content
|
|
13
6
|
render 'comfy/admin/cms/revisions/show'
|
|
14
7
|
end
|
|
15
8
|
|
|
9
|
+
def preview
|
|
10
|
+
render_fragment_preview(cms_page: @record, locale: @site.locale)
|
|
11
|
+
end
|
|
12
|
+
|
|
16
13
|
private
|
|
17
14
|
|
|
18
15
|
def load_record
|
|
@@ -25,4 +22,8 @@ private
|
|
|
25
22
|
def record_path
|
|
26
23
|
edit_comfy_admin_cms_site_page_path(@site, @record)
|
|
27
24
|
end
|
|
25
|
+
|
|
26
|
+
def preview_path
|
|
27
|
+
preview_comfy_admin_cms_site_page_revision_path(@site, @record, @revision)
|
|
28
|
+
end
|
|
28
29
|
end
|
|
@@ -2,17 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
class Comfy::Admin::Cms::Revisions::TranslationController < Comfy::Admin::Cms::Revisions::BaseController
|
|
4
4
|
def show
|
|
5
|
-
|
|
6
|
-
[fragment.identifier, fragment.content]
|
|
7
|
-
end
|
|
8
|
-
@versioned_content = @record.fragments.to_h do |fragment|
|
|
9
|
-
data = @revision.data['fragments_attributes'].detect { |item| item[:identifier] == fragment.identifier }
|
|
10
|
-
[fragment.identifier, data.try(:[], :content)]
|
|
11
|
-
end
|
|
12
|
-
|
|
5
|
+
load_fragment_content
|
|
13
6
|
render 'comfy/admin/cms/revisions/show'
|
|
14
7
|
end
|
|
15
8
|
|
|
9
|
+
def preview
|
|
10
|
+
render_fragment_preview(cms_page: @page, locale: @record.locale)
|
|
11
|
+
end
|
|
12
|
+
|
|
16
13
|
private
|
|
17
14
|
|
|
18
15
|
def load_record
|
|
@@ -26,4 +23,13 @@ private
|
|
|
26
23
|
def record_path
|
|
27
24
|
edit_comfy_admin_cms_site_page_translation_path(@site, @page, @record)
|
|
28
25
|
end
|
|
26
|
+
|
|
27
|
+
def preview_path
|
|
28
|
+
preview_comfy_admin_cms_site_page_translation_revision_path(
|
|
29
|
+
@site,
|
|
30
|
+
@page,
|
|
31
|
+
@record,
|
|
32
|
+
@revision
|
|
33
|
+
)
|
|
34
|
+
end
|
|
29
35
|
end
|
|
@@ -56,7 +56,7 @@ protected
|
|
|
56
56
|
|
|
57
57
|
def load_site
|
|
58
58
|
@site = ::Comfy::Cms::Site.find(params[:id])
|
|
59
|
-
I18n.locale =
|
|
59
|
+
I18n.locale = ComfyMiddleSeat.config.admin_locale || @site.locale
|
|
60
60
|
rescue ActiveRecord::RecordNotFound
|
|
61
61
|
flash[:danger] = I18n.t('comfy.admin.cms.sites.not_found')
|
|
62
62
|
redirect_to action: :index
|
|
@@ -25,6 +25,7 @@ class Comfy::Admin::Cms::TranslationsController < Comfy::Admin::Cms::BaseControl
|
|
|
25
25
|
|
|
26
26
|
def create
|
|
27
27
|
@translation.save!
|
|
28
|
+
acknowledge_draft_save
|
|
28
29
|
flash[:success] = I18n.t('comfy.admin.cms.translations.created')
|
|
29
30
|
redirect_to action: :edit, id: @translation
|
|
30
31
|
rescue ActiveRecord::RecordInvalid
|
|
@@ -34,6 +35,7 @@ class Comfy::Admin::Cms::TranslationsController < Comfy::Admin::Cms::BaseControl
|
|
|
34
35
|
|
|
35
36
|
def update
|
|
36
37
|
@translation.save!
|
|
38
|
+
acknowledge_draft_save
|
|
37
39
|
flash[:success] = I18n.t('comfy.admin.cms.translations.updated')
|
|
38
40
|
redirect_to action: :edit, id: @translation
|
|
39
41
|
rescue ActiveRecord::RecordInvalid
|
|
@@ -61,7 +63,7 @@ class Comfy::Admin::Cms::TranslationsController < Comfy::Admin::Cms::BaseControl
|
|
|
61
63
|
private
|
|
62
64
|
|
|
63
65
|
def translation_select_options
|
|
64
|
-
all =
|
|
66
|
+
all = ComfyMiddleSeat.config.locales
|
|
65
67
|
taken = @page.translations.pluck(:locale) + [@site.locale] - [@translation.locale]
|
|
66
68
|
all.except(*taken).map { |k, v| ["#{v} (#{k})", k] }
|
|
67
69
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class Comfy::Cms::BaseController <
|
|
3
|
+
class Comfy::Cms::BaseController < ComfyMiddleSeat.config.public_base_controller.to_s.constantize
|
|
4
4
|
before_action :load_cms_site
|
|
5
5
|
|
|
6
6
|
helper Comfy::CmsHelper
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
class Comfy::Cms::ContentController < Comfy::Cms::BaseController
|
|
4
4
|
# Authentication module must have `authenticate` method
|
|
5
|
-
include
|
|
5
|
+
include ComfyMiddleSeat.config.public_auth.to_s.constantize
|
|
6
6
|
|
|
7
7
|
# Authorization module must have `authorize` method
|
|
8
|
-
include
|
|
8
|
+
include ComfyMiddleSeat.config.public_authorization.to_s.constantize
|
|
9
9
|
|
|
10
10
|
before_action :load_seeds
|
|
11
11
|
before_action :load_cms_page,
|
|
@@ -24,7 +24,7 @@ class Comfy::Cms::ContentController < Comfy::Cms::BaseController
|
|
|
24
24
|
inline: @cms_page.content_cache,
|
|
25
25
|
layout: false
|
|
26
26
|
)
|
|
27
|
-
json_page = @cms_page.as_json(
|
|
27
|
+
json_page = @cms_page.as_json(ComfyMiddleSeat.config.page_to_json_options)
|
|
28
28
|
render json: json_page
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -53,9 +53,9 @@ protected
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def load_seeds
|
|
56
|
-
return unless
|
|
56
|
+
return unless ComfyMiddleSeat.config.enable_seeds
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
ComfyMiddleSeat::Seeds::Importer.new(@cms_site.identifier).import!
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
# Attempting to populate @cms_page and @cms_layout instance variables so they
|
|
@@ -9,11 +9,31 @@ module Comfy::ReorderAction
|
|
|
9
9
|
|
|
10
10
|
def reorder
|
|
11
11
|
resource_class = self.class.reorder_action_resource
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
positions = (params.permit(order: [])[:order] || []).each_with_index.to_h
|
|
13
|
+
|
|
14
|
+
if positions.present?
|
|
15
|
+
site_resources = resource_class.where(site_id: @site.id)
|
|
16
|
+
reordered_resources = site_resources.where(id: positions.keys)
|
|
17
|
+
position = Arel::Nodes::Case.new(resource_class.arel_table[:id])
|
|
18
|
+
positions.each do |id, index|
|
|
19
|
+
position.when(id).then(index)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
reordered_resources.update_all(position: position)
|
|
23
|
+
if resource_class == Comfy::Cms::Page
|
|
24
|
+
clear_reordered_page_content_cache(site_resources, reordered_resources)
|
|
25
|
+
end
|
|
15
26
|
end
|
|
16
|
-
|
|
27
|
+
|
|
17
28
|
head :ok
|
|
18
29
|
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def clear_reordered_page_content_cache(site_pages, reordered_pages)
|
|
34
|
+
affected_pages = site_pages.where(id: reordered_pages.select(:id)).or(
|
|
35
|
+
site_pages.where(id: reordered_pages.select(:parent_id))
|
|
36
|
+
)
|
|
37
|
+
affected_pages.update_all(content_cache: nil)
|
|
38
|
+
end
|
|
19
39
|
end
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
3
5
|
module Comfy
|
|
4
6
|
module Admin
|
|
5
7
|
module CmsHelper
|
|
6
8
|
# Wrapper around Comfy::FormBuilder
|
|
7
9
|
def comfy_form_with(**options, &)
|
|
8
|
-
form_options = options.merge(builder:
|
|
10
|
+
form_options = options.merge(builder: ComfyMiddleSeat::FormBuilder)
|
|
9
11
|
form_options[:bootstrap] = { layout: :horizontal }
|
|
10
12
|
form_options[:local] = true
|
|
11
13
|
bootstrap_form_with(**form_options, &)
|
|
@@ -14,16 +16,39 @@ module Comfy
|
|
|
14
16
|
def comfy_admin_partial(path, params = {})
|
|
15
17
|
render path, params
|
|
16
18
|
rescue ActionView::MissingTemplate
|
|
17
|
-
if
|
|
19
|
+
if ComfyMiddleSeat.config.reveal_cms_partials
|
|
18
20
|
content_tag(:div, class: 'comfy-admin-partial') do
|
|
19
21
|
path
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
|
|
26
|
+
def cms_draft_form_data(*key_parts, record:)
|
|
27
|
+
namespace = session[:comfy_cms_draft_namespace] ||= SecureRandom.hex(16)
|
|
28
|
+
{
|
|
29
|
+
cms_unsaved_message: t(
|
|
30
|
+
'comfy.admin.cms.forms.unsaved_changes',
|
|
31
|
+
default: 'You have unsaved changes. Are you sure you want to leave this page?'
|
|
32
|
+
),
|
|
33
|
+
cms_draft_key: ['comfy-cms:draft:v1', namespace, *key_parts].join(':'),
|
|
34
|
+
cms_draft_title: t('comfy.admin.cms.drafts.title', default: 'Unsaved draft found'),
|
|
35
|
+
cms_draft_message: t(
|
|
36
|
+
'comfy.admin.cms.drafts.message',
|
|
37
|
+
default: 'A locally saved draft is available. Restore it or discard it?'
|
|
38
|
+
),
|
|
39
|
+
cms_draft_files_message: t(
|
|
40
|
+
'comfy.admin.cms.drafts.files_message',
|
|
41
|
+
default: 'Selected files are not stored and must be selected again.'
|
|
42
|
+
),
|
|
43
|
+
cms_draft_restore: t('comfy.admin.cms.drafts.restore', default: 'Restore draft'),
|
|
44
|
+
cms_draft_discard: t('comfy.admin.cms.drafts.discard', default: 'Discard draft'),
|
|
45
|
+
cms_save_failed: record.errors.any?
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
24
49
|
# Injects some content somewhere inside cms admin area
|
|
25
50
|
def cms_hook(name, options = {})
|
|
26
|
-
|
|
51
|
+
ComfyMiddleSeat::ViewHooks.render(name, self, options)
|
|
27
52
|
end
|
|
28
53
|
|
|
29
54
|
# @param [String] fragment_id
|
|
@@ -52,7 +52,7 @@ module Comfy
|
|
|
52
52
|
snippet = cms_site&.snippets&.find_by_identifier(identifier)
|
|
53
53
|
return '' unless snippet
|
|
54
54
|
|
|
55
|
-
r =
|
|
55
|
+
r = ComfyMiddleSeat::Content::Renderer.new(snippet)
|
|
56
56
|
render inline: r.render(r.nodes(r.tokenize(snippet.content)))
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -24,7 +24,9 @@ class Comfy::Cms::File < ActiveRecord::Base
|
|
|
24
24
|
before_create :assign_position
|
|
25
25
|
# active_storage attachment behavior changed in rails 6
|
|
26
26
|
before_save :process_attachment
|
|
27
|
-
|
|
27
|
+
after_commit :clear_page_content_cache,
|
|
28
|
+
on: %i[create update destroy],
|
|
29
|
+
if: :page_content_cache_stale?
|
|
28
30
|
|
|
29
31
|
# -- Validations -------------------------------------------------------------
|
|
30
32
|
validates :label, presence: true
|
|
@@ -36,17 +38,37 @@ class Comfy::Cms::File < ActiveRecord::Base
|
|
|
36
38
|
scope :with_images, -> {
|
|
37
39
|
where("active_storage_blobs.content_type LIKE 'image/%'").references(:blob)
|
|
38
40
|
}
|
|
41
|
+
scope :search, ->(query) {
|
|
42
|
+
term = query.to_s.strip
|
|
43
|
+
if term.present?
|
|
44
|
+
pattern = "%#{sanitize_sql_like(term.downcase)}%"
|
|
45
|
+
left_joins(attachment_attachment: :blob)
|
|
46
|
+
.where(
|
|
47
|
+
<<~SQL.squish,
|
|
48
|
+
LOWER(comfy_cms_files.label) LIKE :pattern OR
|
|
49
|
+
LOWER(comfy_cms_files.description) LIKE :pattern OR
|
|
50
|
+
LOWER(active_storage_blobs.filename) LIKE :pattern
|
|
51
|
+
SQL
|
|
52
|
+
pattern: pattern
|
|
53
|
+
)
|
|
54
|
+
.distinct
|
|
55
|
+
end
|
|
56
|
+
}
|
|
39
57
|
|
|
40
58
|
private
|
|
41
59
|
|
|
42
60
|
def clear_page_content_cache
|
|
43
|
-
|
|
61
|
+
site.pages.update_all(content_cache: nil)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def page_content_cache_stale?
|
|
65
|
+
destroyed? || saved_changes? || @file.present?
|
|
44
66
|
end
|
|
45
67
|
|
|
46
68
|
protected
|
|
47
69
|
|
|
48
70
|
def assign_position
|
|
49
|
-
max =
|
|
71
|
+
max = site.files.maximum(:position)
|
|
50
72
|
self.position = max ? max + 1 : 0
|
|
51
73
|
end
|
|
52
74
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class Comfy::Cms::Layout < ActiveRecord::Base
|
|
4
4
|
self.table_name = 'comfy_cms_layouts'
|
|
5
5
|
|
|
6
|
-
require_relative '../../../../lib/
|
|
6
|
+
require_relative '../../../../lib/comfy_middle_seat/extensions/acts_as_tree'
|
|
7
7
|
|
|
8
8
|
cms_acts_as_tree
|
|
9
9
|
cms_has_revisions_for :content, :css, :js
|
|
@@ -15,7 +15,9 @@ class Comfy::Cms::Layout < ActiveRecord::Base
|
|
|
15
15
|
# -- Callbacks ---------------------------------------------------------------
|
|
16
16
|
before_validation :assign_label
|
|
17
17
|
before_create :assign_position
|
|
18
|
-
|
|
18
|
+
after_commit :clear_page_content_cache,
|
|
19
|
+
on: %i[create update],
|
|
20
|
+
if: :saved_changes?
|
|
19
21
|
after_destroy :clear_page_content_cache
|
|
20
22
|
|
|
21
23
|
# -- Validations -------------------------------------------------------------
|
|
@@ -66,12 +68,12 @@ class Comfy::Cms::Layout < ActiveRecord::Base
|
|
|
66
68
|
# and merges on the {{cms:tag_type content}} tag (if parent layout has that).
|
|
67
69
|
# Returns a list of tokens that can be fed into the renderer.
|
|
68
70
|
def content_tokens
|
|
69
|
-
renderer =
|
|
71
|
+
renderer = ComfyMiddleSeat::Content::Renderer.new(nil)
|
|
70
72
|
tokens = renderer.tokenize(content)
|
|
71
73
|
|
|
72
74
|
if parent
|
|
73
|
-
fragment_tags =
|
|
74
|
-
|
|
75
|
+
fragment_tags = ComfyMiddleSeat::Content::Tags::Fragment.subclasses.map do |c|
|
|
76
|
+
ComfyMiddleSeat::Content::Renderer.tags.key(c)
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
parent_tokens = parent.content_tokens
|
|
@@ -96,7 +98,7 @@ class Comfy::Cms::Layout < ActiveRecord::Base
|
|
|
96
98
|
|
|
97
99
|
# Forcing page content reload
|
|
98
100
|
def clear_page_content_cache
|
|
99
|
-
|
|
101
|
+
pages.update_all(content_cache: nil)
|
|
100
102
|
children.each(&:clear_page_content_cache)
|
|
101
103
|
end
|
|
102
104
|
|
|
@@ -44,6 +44,28 @@ class Comfy::Cms::Page < ActiveRecord::Base
|
|
|
44
44
|
|
|
45
45
|
# -- Scopes ------------------------------------------------------------------
|
|
46
46
|
scope :published, -> { where(is_published: true) }
|
|
47
|
+
scope :search, ->(query) {
|
|
48
|
+
term = query.to_s.strip
|
|
49
|
+
if term.present?
|
|
50
|
+
pattern = "%#{sanitize_sql_like(term.downcase)}%"
|
|
51
|
+
where(
|
|
52
|
+
<<~SQL.squish,
|
|
53
|
+
LOWER(comfy_cms_pages.label) LIKE :pattern OR
|
|
54
|
+
LOWER(comfy_cms_pages.slug) LIKE :pattern OR
|
|
55
|
+
LOWER(comfy_cms_pages.full_path) LIKE :pattern OR
|
|
56
|
+
EXISTS (
|
|
57
|
+
SELECT 1
|
|
58
|
+
FROM comfy_cms_fragments
|
|
59
|
+
WHERE comfy_cms_fragments.record_type = :record_type
|
|
60
|
+
AND comfy_cms_fragments.record_id = comfy_cms_pages.id
|
|
61
|
+
AND LOWER(comfy_cms_fragments.content) LIKE :pattern
|
|
62
|
+
)
|
|
63
|
+
SQL
|
|
64
|
+
pattern: pattern,
|
|
65
|
+
record_type: polymorphic_name
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
}
|
|
47
69
|
|
|
48
70
|
# -- Class Methods -----------------------------------------------------------
|
|
49
71
|
# Tree-like structure for pages
|
|
@@ -37,7 +37,7 @@ class Comfy::Cms::Site < ActiveRecord::Base
|
|
|
37
37
|
|
|
38
38
|
cms_site = nil
|
|
39
39
|
|
|
40
|
-
public_cms_path =
|
|
40
|
+
public_cms_path = ComfyMiddleSeat.configuration.public_cms_path
|
|
41
41
|
if path && public_cms_path != '/'
|
|
42
42
|
path = path.sub(%r{\A#{public_cms_path}}, '')
|
|
43
43
|
end
|
|
@@ -54,7 +54,7 @@ class Comfy::Cms::Site < ActiveRecord::Base
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def self.real_host_from_aliases(host)
|
|
57
|
-
if (aliases =
|
|
57
|
+
if (aliases = ComfyMiddleSeat.config.hostname_aliases)
|
|
58
58
|
aliases.each do |alias_host, hosts|
|
|
59
59
|
return alias_host if hosts.include?(host)
|
|
60
60
|
end
|
|
@@ -64,7 +64,7 @@ class Comfy::Cms::Site < ActiveRecord::Base
|
|
|
64
64
|
|
|
65
65
|
# -- Instance Methods --------------------------------------------------------
|
|
66
66
|
def url(relative: false)
|
|
67
|
-
public_cms_path =
|
|
67
|
+
public_cms_path = ComfyMiddleSeat.config.public_cms_path || '/'
|
|
68
68
|
host = "//#{hostname}"
|
|
69
69
|
path = ['/', public_cms_path, self.path].compact.join('/').squeeze('/').chomp('/')
|
|
70
70
|
relative ? path.presence : [host, path].join
|