alchemy_cms 4.1.2 → 4.2.0.rc1
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/ISSUE_TEMPLATE/Bug_report.md +0 -5
- data/.rubocop.yml +4 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +29 -10
- data/Gemfile +5 -7
- data/README.md +114 -62
- data/Rakefile +2 -2
- data/alchemy_cms.gemspec +5 -5
- data/app/assets/images/alchemy/icon.svg +1 -1
- data/app/assets/javascripts/alchemy/admin.js +2 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -24
- data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +11 -9
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +7 -24
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +9 -8
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +38 -0
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +2 -4
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +1 -1
- data/app/assets/stylesheets/alchemy/_mixins.scss +2 -1
- data/app/assets/stylesheets/alchemy/_variables.scss +7 -2
- data/app/assets/stylesheets/alchemy/admin.scss +2 -1
- data/app/assets/stylesheets/alchemy/archive.scss +18 -4
- data/app/assets/stylesheets/alchemy/buttons.scss +1 -1
- data/app/assets/stylesheets/alchemy/dialogs.scss +1 -1
- data/app/assets/stylesheets/alchemy/elements.scss +154 -90
- data/app/assets/stylesheets/alchemy/filter_field.scss +30 -0
- data/app/assets/stylesheets/alchemy/flatpickr.scss +839 -0
- data/app/assets/stylesheets/alchemy/forms.scss +5 -1
- data/app/assets/stylesheets/alchemy/frame.scss +6 -14
- data/app/assets/stylesheets/alchemy/navigation.scss +109 -98
- data/app/assets/stylesheets/alchemy/search.scss +11 -29
- data/app/assets/stylesheets/alchemy/tables.scss +0 -23
- data/app/assets/stylesheets/alchemy/tags.scss +4 -27
- data/app/assets/stylesheets/alchemy/toolbar.scss +12 -2
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +4 -33
- data/app/controllers/alchemy/admin/attachments_controller.rb +1 -12
- data/app/controllers/alchemy/admin/contents_controller.rb +2 -24
- data/app/controllers/alchemy/admin/elements_controller.rb +11 -49
- data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pictures_controller.rb +1 -14
- data/app/controllers/alchemy/api/contents_controller.rb +1 -1
- data/app/controllers/alchemy/api/elements_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +1 -1
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +20 -0
- data/app/helpers/alchemy/admin/base_helper.rb +8 -18
- data/app/helpers/alchemy/admin/elements_helper.rb +55 -85
- data/app/helpers/alchemy/admin/pictures_helper.rb +0 -23
- data/app/helpers/alchemy/elements_helper.rb +80 -120
- data/app/helpers/alchemy/pages_helper.rb +5 -24
- data/app/models/alchemy/content.rb +0 -1
- data/app/models/alchemy/content/factory.rb +33 -57
- data/app/models/alchemy/element.rb +46 -66
- data/app/models/alchemy/element/element_contents.rb +2 -2
- data/app/models/alchemy/page.rb +34 -4
- data/app/models/alchemy/page/page_elements.rb +30 -122
- data/app/serializers/alchemy/attachment_serializer.rb +0 -2
- data/app/serializers/alchemy/content_serializer.rb +0 -2
- data/app/serializers/alchemy/element_serializer.rb +0 -3
- data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_date_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_file_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_html_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_link_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_picture_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_select_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_text_serializer.rb +0 -2
- data/app/serializers/alchemy/legacy_element_serializer.rb +0 -3
- data/app/serializers/alchemy/page_serializer.rb +2 -8
- data/app/serializers/alchemy/page_tree_serializer.rb +1 -1
- data/app/serializers/alchemy/picture_serializer.rb +0 -2
- data/app/views/alchemy/admin/clipboard/index.html.erb +2 -2
- data/app/views/alchemy/admin/clipboard/insert.js.erb +9 -12
- data/app/views/alchemy/admin/contents/create.js.erb +4 -30
- data/app/views/alchemy/admin/elements/_element.html.erb +27 -12
- data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_new_element_form.html.erb +0 -10
- data/app/views/alchemy/admin/elements/create.js.erb +12 -12
- data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
- data/app/views/alchemy/admin/elements/index.html.erb +20 -19
- data/app/views/alchemy/admin/elements/publish.js.erb +5 -0
- data/app/views/alchemy/admin/elements/trash.js.erb +4 -1
- data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -7
- data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +0 -22
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +2 -4
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/index.html.erb +14 -10
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +7 -5
- data/app/views/alchemy/admin/partials/_routes.html.erb +0 -1
- data/app/views/alchemy/admin/partials/_search_form.html.erb +6 -4
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +6 -3
- data/app/views/alchemy/admin/pictures/index.html.erb +1 -1
- data/app/views/alchemy/admin/trash/index.html.erb +8 -7
- data/app/views/alchemy/elements/_editor_not_found.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +4 -19
- data/app/views/layouts/alchemy/admin.html.erb +1 -0
- data/bin/rspec +0 -5
- data/config/alchemy/config.yml +3 -0
- data/config/brakeman.ignore +1 -1
- data/config/locales/alchemy.en.yml +6 -12
- data/config/routes.rb +1 -5
- data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -29
- data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +6 -0
- data/lib/alchemy/admin/locale.rb +1 -1
- data/lib/alchemy/cache_digests/template_tracker.rb +4 -27
- data/lib/alchemy/elements_finder.rb +111 -0
- data/lib/alchemy/errors.rb +0 -4
- data/lib/alchemy/modules.rb +49 -18
- data/lib/alchemy/tasks/tidy.rb +3 -40
- data/lib/alchemy/test_support/controller_requests.rb +1 -1
- data/lib/alchemy/test_support/essence_shared_examples.rb +1 -1
- data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -3
- data/lib/alchemy/test_support/factories/content_factory.rb +4 -4
- data/lib/alchemy/test_support/factories/dummy_user_factory.rb +5 -5
- data/lib/alchemy/test_support/factories/element_factory.rb +12 -7
- data/lib/alchemy/test_support/factories/essence_text_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/language_factory.rb +13 -13
- data/lib/alchemy/test_support/factories/page_factory.rb +18 -17
- data/lib/alchemy/test_support/factories/picture_factory.rb +6 -4
- data/lib/alchemy/test_support/factories/site_factory.rb +6 -6
- data/lib/alchemy/tinymce.rb +1 -1
- data/lib/alchemy/upgrader/four_point_two.rb +68 -0
- data/lib/alchemy/upgrader/tasks/cells_migration.rb +41 -0
- data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +146 -0
- data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +65 -0
- data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +195 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +1 -0
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +1 -0
- data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +0 -3
- data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +0 -3
- data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +0 -3
- data/lib/rails/generators/alchemy/elements/templates/view.html.erb +3 -14
- data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -10
- data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -10
- data/lib/tasks/alchemy/tidy.rake +1 -23
- data/lib/tasks/alchemy/upgrade.rake +44 -1
- data/vendor/assets/javascripts/flatpickr/flatpickr.min.js +2 -0
- data/vendor/assets/javascripts/tinymce/license.txt +0 -0
- data/vendor/assets/javascripts/tinymce/tinymce.min.js +2 -2
- metadata +25 -31
- data/app/assets/stylesheets/alchemy/jquery.datetimepicker.scss +0 -478
- data/app/models/alchemy/cell.rb +0 -95
- data/app/models/alchemy/page/page_cells.rb +0 -69
- data/app/serializers/alchemy/cell_serializer.rb +0 -19
- data/app/views/alchemy/admin/contents/new.html.erb +0 -11
- data/app/views/alchemy/admin/contents/order.js.erb +0 -3
- data/app/views/alchemy/admin/elements/_add_picture.html.erb +0 -14
- data/app/views/alchemy/admin/elements/_picture_gallery_editor.html.erb +0 -24
- data/bin/spring +0 -16
- data/lib/alchemy/test_support/factories/cell_factory.rb +0 -9
- data/vendor/assets/javascripts/date-formatter.js +0 -161
- data/vendor/assets/javascripts/jquery_plugins/jquery.datetimepicker.full.min.js +0 -2
|
@@ -3,26 +3,26 @@ require 'alchemy/test_support/factories/site_factory'
|
|
|
3
3
|
|
|
4
4
|
FactoryBot.define do
|
|
5
5
|
factory :alchemy_language, class: 'Alchemy::Language' do
|
|
6
|
-
name 'Deutsch'
|
|
7
|
-
code 'de'
|
|
8
|
-
default true
|
|
9
|
-
frontpage_name 'Intro'
|
|
6
|
+
name { 'Deutsch' }
|
|
7
|
+
code { 'de' }
|
|
8
|
+
default { true }
|
|
9
|
+
frontpage_name { 'Intro' }
|
|
10
10
|
page_layout { Alchemy::Config.get(:default_language)['page_layout'] }
|
|
11
|
-
public true
|
|
11
|
+
public { true }
|
|
12
12
|
site { Alchemy::Site.default }
|
|
13
13
|
|
|
14
14
|
trait :klingon do
|
|
15
|
-
name 'Klingon'
|
|
16
|
-
code 'kl'
|
|
17
|
-
frontpage_name 'Tuq'
|
|
18
|
-
default false
|
|
15
|
+
name { 'Klingon' }
|
|
16
|
+
code { 'kl' }
|
|
17
|
+
frontpage_name { 'Tuq' }
|
|
18
|
+
default { false }
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
trait :english do
|
|
22
|
-
name 'English'
|
|
23
|
-
code 'en'
|
|
24
|
-
frontpage_name 'Intro'
|
|
25
|
-
default false
|
|
22
|
+
name { 'English' }
|
|
23
|
+
code { 'en' }
|
|
24
|
+
frontpage_name { 'Intro' }
|
|
25
|
+
default { false }
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
end
|
|
@@ -5,7 +5,7 @@ FactoryBot.define do
|
|
|
5
5
|
factory :alchemy_page, class: 'Alchemy::Page' do
|
|
6
6
|
language { Alchemy::Language.default || FactoryBot.create(:alchemy_language) }
|
|
7
7
|
sequence(:name) { |n| "A Page #{n}" }
|
|
8
|
-
page_layout "standard"
|
|
8
|
+
page_layout { "standard" }
|
|
9
9
|
|
|
10
10
|
parent_id do
|
|
11
11
|
(Alchemy::Page.find_by(language_root: true) ||
|
|
@@ -13,20 +13,20 @@ FactoryBot.define do
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# This speeds up creating of pages dramatically.
|
|
16
|
-
# Pass
|
|
17
|
-
|
|
16
|
+
# Pass autogenerate_elements: true to generate elements
|
|
17
|
+
autogenerate_elements { false }
|
|
18
18
|
|
|
19
19
|
trait :root do
|
|
20
|
-
name 'Root'
|
|
21
|
-
language nil
|
|
22
|
-
parent_id nil
|
|
23
|
-
page_layout nil
|
|
20
|
+
name { 'Root' }
|
|
21
|
+
language { nil }
|
|
22
|
+
parent_id { nil }
|
|
23
|
+
page_layout { nil }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
trait :language_root do
|
|
27
|
-
name 'Startseite'
|
|
27
|
+
name { 'Startseite' }
|
|
28
28
|
page_layout { language.page_layout }
|
|
29
|
-
language_root true
|
|
29
|
+
language_root { true }
|
|
30
30
|
public_on { Time.current }
|
|
31
31
|
parent_id { Alchemy::Page.root.id }
|
|
32
32
|
end
|
|
@@ -37,22 +37,23 @@ FactoryBot.define do
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
trait :system do
|
|
40
|
-
name "Systempage"
|
|
40
|
+
name { "Systempage" }
|
|
41
41
|
parent_id { Alchemy::Page.root.id }
|
|
42
|
-
language_root false
|
|
43
|
-
page_layout nil
|
|
44
|
-
language nil
|
|
42
|
+
language_root { false }
|
|
43
|
+
page_layout { nil }
|
|
44
|
+
language { nil }
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
trait :layoutpage do
|
|
48
|
-
name "Footer"
|
|
48
|
+
name { "Footer" }
|
|
49
49
|
parent_id { Alchemy::Page.find_or_create_layout_root_for(Alchemy::Language.current.id).id }
|
|
50
|
-
|
|
50
|
+
layoutpage { true }
|
|
51
|
+
page_layout { "footer" }
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
trait :restricted do
|
|
54
|
-
name "Restricted page"
|
|
55
|
-
restricted true
|
|
55
|
+
name { "Restricted page" }
|
|
56
|
+
restricted { true }
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
trait :locked do
|
|
@@ -2,9 +2,11 @@ require 'factory_bot'
|
|
|
2
2
|
|
|
3
3
|
FactoryBot.define do
|
|
4
4
|
factory :alchemy_picture, class: 'Alchemy::Picture' do
|
|
5
|
-
image_file
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
image_file do
|
|
6
|
+
File.new(Alchemy::Engine.root.join('lib', 'alchemy', 'test_support', 'fixtures', 'image.png'))
|
|
7
|
+
end
|
|
8
|
+
name { 'image' }
|
|
9
|
+
image_file_name { 'image.png' }
|
|
10
|
+
upload_hash { Time.current.hash }
|
|
9
11
|
end
|
|
10
12
|
end
|
|
@@ -2,17 +2,17 @@ require 'factory_bot'
|
|
|
2
2
|
|
|
3
3
|
FactoryBot.define do
|
|
4
4
|
factory :alchemy_site, class: 'Alchemy::Site' do
|
|
5
|
-
name 'A Site'
|
|
6
|
-
host 'domain.com'
|
|
5
|
+
name { 'A Site' }
|
|
6
|
+
host { 'domain.com' }
|
|
7
7
|
|
|
8
8
|
trait :default do
|
|
9
|
-
public true
|
|
10
|
-
name Alchemy::Config.get(:default_site)['name']
|
|
11
|
-
host Alchemy::Config.get(:default_site)['host']
|
|
9
|
+
public { true }
|
|
10
|
+
name { Alchemy::Config.get(:default_site)['name'] }
|
|
11
|
+
host { Alchemy::Config.get(:default_site)['host'] }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
trait :public do
|
|
15
|
-
public true
|
|
15
|
+
public { true }
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
data/lib/alchemy/tinymce.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Alchemy
|
|
|
4
4
|
module Tinymce
|
|
5
5
|
mattr_accessor :languages, :plugins
|
|
6
6
|
|
|
7
|
-
@@plugins = %w(alchemy_link anchor autoresize charmap code directionality fullscreen hr link paste tabfocus table)
|
|
7
|
+
@@plugins = %w(alchemy_link anchor autoresize charmap code directionality fullscreen hr link lists paste tabfocus table)
|
|
8
8
|
@@init = {
|
|
9
9
|
skin: 'alchemy',
|
|
10
10
|
width: 'auto',
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require_relative 'tasks/picture_gallery_upgrader'
|
|
2
|
+
require_relative 'tasks/picture_gallery_migration'
|
|
3
|
+
require_relative 'tasks/cells_upgrader'
|
|
4
|
+
require_relative 'tasks/cells_migration'
|
|
5
|
+
|
|
6
|
+
module Alchemy
|
|
7
|
+
class Upgrader::FourPointTwo < Upgrader
|
|
8
|
+
class << self
|
|
9
|
+
def convert_picture_galleries
|
|
10
|
+
desc 'Convert `picture_gallery` element definitions to `nestable_elements`.'
|
|
11
|
+
Alchemy::Upgrader::Tasks::PictureGalleryUpgrader.new.convert_picture_galleries
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def migrate_picture_galleries
|
|
15
|
+
desc 'Migrate existing gallery elements to `nestable_elements`.'
|
|
16
|
+
Alchemy::Upgrader::Tasks::PictureGalleryMigration.new.migrate_picture_galleries
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def convert_cells
|
|
20
|
+
desc 'Convert cells config to fixed nestable elements.'
|
|
21
|
+
Alchemy::Upgrader::Tasks::CellsUpgrader.new.convert_cells
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def migrate_cells
|
|
25
|
+
desc 'Migrate existing cells to fixed nestable elements.'
|
|
26
|
+
Alchemy::Upgrader::Tasks::CellsMigration.new.migrate_cells
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def alchemy_4_2_todos
|
|
30
|
+
notice = <<-NOTE
|
|
31
|
+
|
|
32
|
+
Element's "picture_gallery" feature removed
|
|
33
|
+
----------------------------------------------
|
|
34
|
+
|
|
35
|
+
The `picture_gallery` feature of elements was removed and has been replaced by nestable elements.
|
|
36
|
+
|
|
37
|
+
The automatic updater that just ran updated your `config/alchemy/elements.yml`. A backup was made.
|
|
38
|
+
Nevertheless, you should have a look into it and double check the changes.
|
|
39
|
+
|
|
40
|
+
We created nested elements for each gallery picture we found in your database.
|
|
41
|
+
|
|
42
|
+
We also updated your element view partials so they have hints about how to render the child elements.
|
|
43
|
+
|
|
44
|
+
Cells replaced by fixed nestable elements
|
|
45
|
+
-----------------------------------------
|
|
46
|
+
|
|
47
|
+
The Cells feature has been replaced by fixed nestable elements.
|
|
48
|
+
|
|
49
|
+
The automatic updater that just ran updated your `config/alchemy/elements.yml`.
|
|
50
|
+
Nevertheless, you should have a look into it and double check the changes.
|
|
51
|
+
|
|
52
|
+
We defined new fixed elements for each cell former defined in `cells.yml`
|
|
53
|
+
and put its `elements` into the `nestable_elements` collection of the new elements definition.
|
|
54
|
+
|
|
55
|
+
We also updated your element view partials so they render the child elements.
|
|
56
|
+
|
|
57
|
+
Please review and fix markup, if necessary.
|
|
58
|
+
|
|
59
|
+
PLEASE DOUBLE CHECK YOUR ELEMENT PARTIALS AND ADJUST ACCORDINGLY!
|
|
60
|
+
|
|
61
|
+
As always `git diff` is your friend.
|
|
62
|
+
|
|
63
|
+
NOTE
|
|
64
|
+
todo notice, 'Alchemy v4.2 changes'
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Alchemy::Upgrader::Tasks
|
|
2
|
+
class CellsMigration
|
|
3
|
+
class Cell < ActiveRecord::Base
|
|
4
|
+
self.table_name = 'alchemy_cells'
|
|
5
|
+
belongs_to :page, class_name: 'Alchemy::Page'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def migrate_cells
|
|
9
|
+
if ActiveRecord::Base.connection.data_source_exists?('alchemy_cells')
|
|
10
|
+
cells = Cell.all
|
|
11
|
+
|
|
12
|
+
if cells.any?
|
|
13
|
+
cells.each do |cell|
|
|
14
|
+
migrate_cell!(cell)
|
|
15
|
+
end
|
|
16
|
+
else
|
|
17
|
+
puts "No cells found. Skip"
|
|
18
|
+
end
|
|
19
|
+
else
|
|
20
|
+
puts "Cells table does not exist. Skip"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def migrate_cell!(cell)
|
|
27
|
+
# bust element definitions insta cache
|
|
28
|
+
Alchemy::Element.instance_variable_set('@definitions', nil)
|
|
29
|
+
fixed_element = Alchemy::Element.find_or_initialize_by(fixed: true, name: cell.name, page: cell.page)
|
|
30
|
+
elements = Alchemy::Element.where(cell_id: cell.id)
|
|
31
|
+
|
|
32
|
+
if fixed_element.new_record?
|
|
33
|
+
fixed_element.nested_elements = elements
|
|
34
|
+
fixed_element.save!
|
|
35
|
+
puts "Created new fixed element '#{fixed_element.name}' for cell '#{cell.name}'."
|
|
36
|
+
else
|
|
37
|
+
puts "Element for cell '#{cell.name}' already present. Skip"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require 'alchemy/upgrader'
|
|
2
|
+
require 'rails/generators'
|
|
3
|
+
|
|
4
|
+
module Alchemy::Upgrader::Tasks
|
|
5
|
+
class CellsUpgrader < Thor
|
|
6
|
+
include Thor::Actions
|
|
7
|
+
|
|
8
|
+
no_tasks do
|
|
9
|
+
def convert_cells
|
|
10
|
+
if File.exist?(page_layouts_config_file)
|
|
11
|
+
backup_config
|
|
12
|
+
convert_page_layouts_config
|
|
13
|
+
else
|
|
14
|
+
puts "\nNo page layouts config found. Skipping."
|
|
15
|
+
end
|
|
16
|
+
if File.exist?(cells_config_file)
|
|
17
|
+
convert_cell_config
|
|
18
|
+
delete_cells_config
|
|
19
|
+
else
|
|
20
|
+
puts "\nNo cells config found. Skipping."
|
|
21
|
+
end
|
|
22
|
+
update_cell_views
|
|
23
|
+
update_render_cell_calls
|
|
24
|
+
move_cell_views
|
|
25
|
+
generate_editor_partials
|
|
26
|
+
puts 'Done ✔'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def backup_config
|
|
33
|
+
print "-- Copy existing config file to `config/alchemy/page_layouts.yml.old` ... "
|
|
34
|
+
|
|
35
|
+
FileUtils.copy Rails.root.join('config', 'alchemy', 'page_layouts.yml'),
|
|
36
|
+
Rails.root.join('config', 'alchemy', 'page_layouts.yml.old')
|
|
37
|
+
|
|
38
|
+
puts "done ✔\n"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def write_config(config)
|
|
42
|
+
print '-- Writing new `config/alchemy/page_layouts.yml` ... '
|
|
43
|
+
|
|
44
|
+
File.open(Rails.root.join('config', 'alchemy', 'page_layouts.yml'), "w") do |f|
|
|
45
|
+
f.write config.to_yaml.sub("---\n", "").gsub("\n-", "\n\n-")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
puts "done ✔\n"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def convert_page_layouts_config
|
|
52
|
+
print '-- Moving `cells` from page layouts definition into autogenerated `elements` ... '
|
|
53
|
+
page_layouts = YAML.load_file(page_layouts_config_file)
|
|
54
|
+
page_layouts.select { |p| p['cells'].present? }.map do |page_layout|
|
|
55
|
+
elements = page_layout['elements'] || []
|
|
56
|
+
autogenerate_elements = page_layout['autogenerate'] || []
|
|
57
|
+
cell_elements = page_layout.delete('cells')
|
|
58
|
+
page_layout['elements'] = (elements + cell_elements).uniq
|
|
59
|
+
page_layout['autogenerate'] = (autogenerate_elements + cell_elements).uniq
|
|
60
|
+
end
|
|
61
|
+
puts "done ✔\n"
|
|
62
|
+
write_config(page_layouts)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def page_layouts_config_file
|
|
66
|
+
Rails.root.join('config', 'alchemy', 'page_layouts.yml')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def cells_config_file
|
|
70
|
+
Rails.root.join('config', 'alchemy', 'cells.yml')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def convert_cell_config
|
|
74
|
+
puts '-- Converting cells into unique fixed nestable elements.'
|
|
75
|
+
|
|
76
|
+
YAML.load_file(cells_config_file).each do |cell|
|
|
77
|
+
append_to_file Rails.root.join('config', 'alchemy', 'elements.yml') do
|
|
78
|
+
<<-CELL.strip_heredoc
|
|
79
|
+
|
|
80
|
+
- name: #{cell['name']}
|
|
81
|
+
fixed: true
|
|
82
|
+
unique: true
|
|
83
|
+
nestable_elements: [#{cell['elements'].join(', ')}]
|
|
84
|
+
CELL
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def delete_cells_config
|
|
90
|
+
puts '-- Deleting cells config file.'
|
|
91
|
+
FileUtils.rm(cells_config_file)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def move_cell_views
|
|
95
|
+
if Dir.exist? cells_view_folder
|
|
96
|
+
puts "-- Move cell views into elements view folder"
|
|
97
|
+
Dir.glob("#{cells_view_folder}/*").each do |view|
|
|
98
|
+
filename = File.basename(view).gsub(/(_\w+)\.(\w*\.)?(erb|haml|slim)/, '\1_view.\2\3')
|
|
99
|
+
FileUtils.mv(view, "#{elements_view_folder}/#{filename}")
|
|
100
|
+
puts " Moved #{File.basename(view)} into `app/views/alchemy/elements/` folder"
|
|
101
|
+
end
|
|
102
|
+
FileUtils.rm_rf(cells_view_folder)
|
|
103
|
+
else
|
|
104
|
+
puts "No cell views found. Skip"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def generate_editor_partials
|
|
109
|
+
puts "-- Generate editor partials"
|
|
110
|
+
Rails::Generators.invoke('alchemy:elements', ['--skip'])
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def update_cell_views
|
|
114
|
+
if Dir.exist? cells_view_folder
|
|
115
|
+
puts "-- Update cell views"
|
|
116
|
+
Dir.glob("#{cells_view_folder}/*").each do |view|
|
|
117
|
+
gsub_file(view, /cell\.elements/, 'element.nested_elements.published')
|
|
118
|
+
gsub_file(view, /render_elements\(?from_cell:\scell\)?/, 'render element.nested_elements.published')
|
|
119
|
+
gsub_file(view, /cell/, 'element')
|
|
120
|
+
end
|
|
121
|
+
else
|
|
122
|
+
puts "No cell views found. Skip"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def update_render_cell_calls
|
|
127
|
+
puts "-- Update render_cell calls"
|
|
128
|
+
Dir.glob("#{alchemy_views_folder}/**/*").each do |view|
|
|
129
|
+
next if File.directory?(view)
|
|
130
|
+
gsub_file(view, /render_cell[\(\s]?([:'"]?[a-z_]+['"]?)\)?/, 'render_elements(only: \1, fixed: true)')
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def elements_view_folder
|
|
135
|
+
Rails.root.join('app', 'views', 'alchemy', 'elements')
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def cells_view_folder
|
|
139
|
+
Rails.root.join('app', 'views', 'alchemy', 'cells')
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def alchemy_views_folder
|
|
143
|
+
Rails.root.join('app', 'views', 'alchemy')
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Alchemy
|
|
2
|
+
class Upgrader::Tasks::PictureGalleryMigration
|
|
3
|
+
def migrate_picture_galleries
|
|
4
|
+
if picture_gallery_elements.present?
|
|
5
|
+
picture_gallery_elements.each do |el|
|
|
6
|
+
migrate_element(el)
|
|
7
|
+
end
|
|
8
|
+
else
|
|
9
|
+
puts "No `picture_gallery` elements found. Skip"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def picture_gallery_elements
|
|
16
|
+
Element.distinct.joins(:contents).where("#{Content.table_name}.name LIKE 'essence_picture_%'")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def migrate_element(element)
|
|
20
|
+
gallery_contents = element.contents.where("#{Content.table_name}.name LIKE 'essence_picture_%'").order("#{Content.table_name}.position ASC")
|
|
21
|
+
|
|
22
|
+
if gallery_contents.any?
|
|
23
|
+
if element.nestable_elements.any? { |el| el != "#{element.name}_picture" }
|
|
24
|
+
parent = create_gallery_element(element)
|
|
25
|
+
else
|
|
26
|
+
parent = element
|
|
27
|
+
end
|
|
28
|
+
gallery_contents.each do |content|
|
|
29
|
+
create_element_for_content(content, parent)
|
|
30
|
+
end
|
|
31
|
+
else
|
|
32
|
+
puts "No gallery contents found for #{element.dom_id}. Skip"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def create_gallery_element(parent)
|
|
37
|
+
new_element = parent.nested_elements.create!(
|
|
38
|
+
name: "#{parent.name}_picture_gallery",
|
|
39
|
+
public: parent.public,
|
|
40
|
+
folded: parent.folded,
|
|
41
|
+
creator: parent.creator,
|
|
42
|
+
updater: parent.updater,
|
|
43
|
+
page: parent.page,
|
|
44
|
+
autogenerate_contents: false
|
|
45
|
+
)
|
|
46
|
+
puts "Created new `#{new_element.name}` for `#{parent.name}`"
|
|
47
|
+
new_element
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def create_element_for_content(content, parent)
|
|
51
|
+
new_element = parent.nested_elements.create!(
|
|
52
|
+
name: "#{parent.name}_picture",
|
|
53
|
+
public: parent.public,
|
|
54
|
+
folded: parent.folded,
|
|
55
|
+
creator: parent.creator,
|
|
56
|
+
updater: parent.updater,
|
|
57
|
+
page: parent.page,
|
|
58
|
+
autogenerate_contents: false
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
content.update_columns(element_id: new_element.id, name: 'picture')
|
|
62
|
+
puts "Created new `#{new_element.name}` for `#{parent.name}`"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|