alchemy_cms 5.2.0.rc1 → 6.0.0.b2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +6 -14
- data/.gitignore +0 -1
- data/.hound.yml +1 -1
- data/.rubocop.yml +46 -4
- data/CHANGELOG.md +105 -2
- data/Gemfile +8 -1
- data/README.md +5 -2
- data/alchemy_cms.gemspec +78 -65
- data/app/assets/javascripts/alchemy/admin.js +0 -2
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -27
- data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +2 -1
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +0 -25
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +2 -0
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +1 -1
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +3 -1
- data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +40 -27
- data/app/assets/javascripts/alchemy/templates/node_folder.hbs +1 -1
- data/app/assets/stylesheets/alchemy/admin.scss +1 -1
- data/app/assets/stylesheets/alchemy/archive.scss +18 -4
- data/app/assets/stylesheets/alchemy/buttons.scss +0 -4
- data/app/assets/stylesheets/alchemy/elements.scss +73 -61
- data/app/assets/stylesheets/alchemy/images.scss +8 -0
- data/app/assets/stylesheets/alchemy/node-select.scss +4 -3
- data/app/assets/stylesheets/alchemy/page-select.scss +1 -0
- data/app/controllers/alchemy/admin/attachments_controller.rb +8 -4
- data/app/controllers/alchemy/admin/base_controller.rb +5 -7
- data/app/controllers/alchemy/admin/elements_controller.rb +58 -34
- data/app/controllers/alchemy/admin/essence_audios_controller.rb +30 -0
- data/app/controllers/alchemy/admin/essence_files_controller.rb +0 -14
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +8 -79
- data/app/controllers/alchemy/admin/essence_videos_controller.rb +33 -0
- data/app/controllers/alchemy/admin/ingredients_controller.rb +30 -0
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +7 -22
- data/app/controllers/alchemy/admin/pictures_controller.rb +56 -17
- data/app/controllers/alchemy/admin/resources_controller.rb +84 -10
- data/app/controllers/alchemy/api/elements_controller.rb +13 -4
- data/app/controllers/alchemy/api/pages_controller.rb +4 -3
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +13 -3
- data/app/controllers/concerns/alchemy/admin/crop_action.rb +26 -0
- data/app/decorators/alchemy/element_editor.rb +48 -1
- data/app/decorators/alchemy/ingredient_editor.rb +154 -0
- data/app/helpers/alchemy/admin/elements_helper.rb +1 -0
- data/app/helpers/alchemy/admin/essences_helper.rb +1 -1
- data/app/helpers/alchemy/admin/ingredients_helper.rb +42 -0
- data/app/helpers/alchemy/elements_block_helper.rb +22 -7
- data/app/helpers/alchemy/elements_helper.rb +12 -5
- data/app/helpers/alchemy/pages_helper.rb +3 -9
- data/app/jobs/alchemy/base_job.rb +11 -0
- data/app/jobs/alchemy/publish_page_job.rb +11 -0
- data/app/models/alchemy/attachment.rb +24 -7
- data/app/models/alchemy/content.rb +1 -6
- data/app/models/alchemy/content/factory.rb +23 -27
- data/app/models/alchemy/element.rb +39 -72
- data/app/models/alchemy/element/definitions.rb +29 -27
- data/app/models/alchemy/element/element_contents.rb +131 -122
- data/app/models/alchemy/element/element_essences.rb +100 -98
- data/app/models/alchemy/element/element_ingredients.rb +176 -0
- data/app/models/alchemy/element/presenters.rb +104 -85
- data/app/models/alchemy/elements_repository.rb +126 -0
- data/app/models/alchemy/essence_audio.rb +12 -0
- data/app/models/alchemy/essence_headline.rb +40 -0
- data/app/models/alchemy/essence_picture.rb +4 -116
- data/app/models/alchemy/essence_richtext.rb +12 -0
- data/app/models/alchemy/essence_video.rb +12 -0
- data/app/models/alchemy/image_cropper_settings.rb +87 -0
- data/app/models/alchemy/ingredient.rb +224 -0
- data/app/models/alchemy/ingredient_validator.rb +97 -0
- data/app/models/alchemy/ingredients/audio.rb +29 -0
- data/app/models/alchemy/ingredients/boolean.rb +21 -0
- data/app/models/alchemy/ingredients/datetime.rb +20 -0
- data/app/models/alchemy/ingredients/file.rb +30 -0
- data/app/models/alchemy/ingredients/headline.rb +42 -0
- data/app/models/alchemy/ingredients/html.rb +19 -0
- data/app/models/alchemy/ingredients/link.rb +16 -0
- data/app/models/alchemy/ingredients/node.rb +23 -0
- data/app/models/alchemy/ingredients/page.rb +23 -0
- data/app/models/alchemy/ingredients/picture.rb +41 -0
- data/app/models/alchemy/ingredients/richtext.rb +57 -0
- data/app/models/alchemy/ingredients/select.rb +10 -0
- data/app/models/alchemy/ingredients/text.rb +17 -0
- data/app/models/alchemy/ingredients/video.rb +33 -0
- data/app/models/alchemy/language.rb +0 -11
- data/app/models/alchemy/page.rb +76 -33
- data/app/models/alchemy/page/fixed_attributes.rb +53 -51
- data/app/models/alchemy/page/page_elements.rb +186 -205
- data/app/models/alchemy/page/page_naming.rb +66 -64
- data/app/models/alchemy/page/page_natures.rb +139 -142
- data/app/models/alchemy/page/page_scopes.rb +117 -102
- data/app/models/alchemy/page/publisher.rb +50 -0
- data/app/models/alchemy/page/url_path.rb +1 -1
- data/app/models/alchemy/page_version.rb +58 -0
- data/app/models/alchemy/picture.rb +18 -40
- data/app/models/alchemy/picture/calculations.rb +2 -8
- data/app/models/alchemy/picture/preprocessor.rb +2 -0
- data/app/models/alchemy/picture/transformations.rb +24 -96
- data/app/models/concerns/alchemy/picture_thumbnails.rb +181 -0
- data/app/models/concerns/alchemy/touch_elements.rb +2 -2
- data/app/presenters/alchemy/picture_view.rb +88 -0
- data/app/serializers/alchemy/element_serializer.rb +5 -0
- data/app/serializers/alchemy/page_tree_serializer.rb +3 -2
- data/app/services/alchemy/delete_elements.rb +44 -0
- data/app/services/alchemy/duplicate_element.rb +56 -0
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +2 -3
- data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +3 -3
- data/app/views/alchemy/admin/attachments/assign.js.erb +11 -0
- data/app/views/alchemy/admin/attachments/index.html.erb +2 -3
- data/app/views/alchemy/admin/crop.html.erb +36 -0
- data/app/views/alchemy/admin/elements/_element.html.erb +14 -10
- data/app/views/alchemy/admin/elements/{_element_footer.html.erb → _footer.html.erb} +0 -0
- data/app/views/alchemy/admin/elements/{_new_element_form.html.erb → _form.html.erb} +1 -1
- data/app/views/alchemy/admin/elements/{_element_header.html.erb → _header.html.erb} +1 -1
- data/app/views/alchemy/admin/elements/{_element_toolbar.html.erb → _toolbar.html.erb} +5 -6
- data/app/views/alchemy/admin/elements/{trash.js.erb → destroy.js.erb} +1 -3
- data/app/views/alchemy/admin/elements/new.html.erb +3 -3
- data/app/views/alchemy/admin/elements/order.js.erb +0 -17
- data/app/views/alchemy/admin/elements/update.js.erb +3 -2
- data/app/views/alchemy/admin/essence_audios/edit.html.erb +7 -0
- data/app/views/alchemy/admin/essence_pictures/update.js.erb +0 -1
- data/app/views/alchemy/admin/essence_videos/edit.html.erb +11 -0
- data/app/views/alchemy/admin/ingredients/_audio_fields.html.erb +4 -0
- data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +18 -0
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +25 -0
- data/app/views/alchemy/admin/ingredients/_video_fields.html.erb +8 -0
- data/app/views/alchemy/admin/ingredients/edit.html.erb +4 -0
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +0 -5
- data/app/views/alchemy/admin/nodes/_node.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_anchor_link.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_external_link.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_file_link.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_form.html.erb +0 -6
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +5 -2
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +1 -1
- data/app/views/alchemy/admin/pages/edit.html.erb +36 -24
- data/app/views/alchemy/admin/pages/index.html.erb +2 -9
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +2 -4
- data/app/views/alchemy/admin/partials/_routes.html.erb +7 -11
- data/app/views/alchemy/admin/partials/_search_form.html.erb +9 -0
- data/app/views/alchemy/admin/pictures/_archive.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +5 -7
- data/app/views/alchemy/admin/pictures/_infos.html.erb +0 -1
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +4 -4
- data/app/views/alchemy/admin/pictures/assign.js.erb +10 -0
- data/app/views/alchemy/admin/pictures/index.html.erb +8 -3
- data/app/views/alchemy/admin/resources/_filter.html.erb +12 -0
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +14 -17
- data/app/views/alchemy/admin/resources/_form.html.erb +3 -0
- data/app/views/alchemy/admin/resources/_table_header.html.erb +15 -0
- data/app/views/alchemy/admin/resources/index.html.erb +3 -11
- data/app/views/alchemy/essences/_essence_audio_editor.html.erb +4 -0
- data/app/views/alchemy/essences/_essence_audio_view.html.erb +15 -0
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +15 -6
- data/app/views/alchemy/essences/_essence_headline_editor.html.erb +36 -0
- data/app/views/alchemy/essences/_essence_headline_view.html.erb +10 -0
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +8 -4
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +27 -12
- data/app/views/alchemy/essences/_essence_picture_view.html.erb +3 -3
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +12 -4
- data/app/views/alchemy/essences/_essence_video_editor.html.erb +4 -0
- data/app/views/alchemy/essences/_essence_video_view.html.erb +18 -0
- data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +21 -16
- data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +2 -2
- data/app/views/alchemy/ingredients/_audio_editor.html.erb +5 -0
- data/app/views/alchemy/ingredients/_audio_view.html.erb +14 -0
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +11 -0
- data/app/views/alchemy/ingredients/_boolean_view.html.erb +1 -0
- data/app/views/alchemy/ingredients/_datetime_editor.html.erb +17 -0
- data/app/views/alchemy/ingredients/_datetime_view.html.erb +9 -0
- data/app/views/alchemy/ingredients/_file_editor.html.erb +50 -0
- data/app/views/alchemy/ingredients/_file_view.html.erb +17 -0
- data/app/views/alchemy/ingredients/_headline_editor.html.erb +30 -0
- data/app/views/alchemy/ingredients/_headline_view.html.erb +9 -0
- data/app/views/alchemy/ingredients/_html_editor.html.erb +8 -0
- data/app/views/alchemy/ingredients/_html_view.html.erb +1 -0
- data/app/views/alchemy/ingredients/_link_editor.html.erb +24 -0
- data/app/views/alchemy/ingredients/_link_view.html.erb +9 -0
- data/app/views/alchemy/ingredients/_node_editor.html.erb +25 -0
- data/app/views/alchemy/ingredients/_node_view.html.erb +1 -0
- data/app/views/alchemy/ingredients/_page_editor.html.erb +24 -0
- data/app/views/alchemy/ingredients/_page_view.html.erb +4 -0
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +59 -0
- data/app/views/alchemy/ingredients/_picture_view.html.erb +5 -0
- data/app/views/alchemy/ingredients/_richtext_editor.html.erb +12 -0
- data/app/views/alchemy/ingredients/_richtext_view.html.erb +3 -0
- data/app/views/alchemy/ingredients/_select_editor.html.erb +29 -0
- data/app/views/alchemy/ingredients/_select_view.html.erb +1 -0
- data/app/views/alchemy/ingredients/_text_editor.html.erb +19 -0
- data/app/views/alchemy/ingredients/_text_view.html.erb +16 -0
- data/app/views/alchemy/ingredients/_video_editor.html.erb +5 -0
- data/app/views/alchemy/ingredients/_video_view.html.erb +17 -0
- data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +20 -0
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +57 -0
- data/config/brakeman.ignore +66 -159
- data/config/initializers/dragonfly.rb +10 -0
- data/config/locales/alchemy.en.yml +108 -64
- data/config/routes.rb +17 -22
- data/db/migrate/20201207131309_create_page_versions.rb +19 -0
- data/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +76 -0
- data/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb +10 -0
- data/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +7 -0
- data/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +12 -0
- data/db/migrate/20210506135919_create_essence_audios.rb +19 -0
- data/db/migrate/20210506140258_create_essence_videos.rb +23 -0
- data/db/migrate/20210508091432_create_alchemy_ingredients.rb +22 -0
- data/lib/alchemy/admin/preview_url.rb +2 -0
- data/lib/alchemy/deprecation.rb +1 -1
- data/lib/alchemy/dragonfly/processors/auto_orient.rb +18 -0
- data/lib/alchemy/dragonfly/processors/crop_resize.rb +35 -0
- data/lib/alchemy/elements_finder.rb +14 -60
- data/lib/alchemy/essence.rb +1 -2
- data/lib/alchemy/forms/builder.rb +21 -1
- data/lib/alchemy/hints.rb +8 -4
- data/lib/alchemy/page_layout.rb +0 -13
- data/lib/alchemy/permissions.rb +30 -29
- data/lib/alchemy/resource.rb +18 -6
- data/lib/alchemy/resource_filter.rb +40 -0
- data/lib/alchemy/resources_helper.rb +1 -16
- data/lib/alchemy/tasks/tidy.rb +29 -0
- data/lib/alchemy/test_support.rb +2 -4
- data/lib/alchemy/test_support/essence_shared_examples.rb +0 -1
- data/lib/alchemy/test_support/factories/element_factory.rb +8 -8
- data/lib/alchemy/test_support/factories/essence_audio_factory.rb +7 -0
- data/lib/alchemy/test_support/factories/essence_video_factory.rb +7 -0
- data/lib/alchemy/test_support/factories/ingredient_factory.rb +25 -0
- data/lib/alchemy/test_support/factories/page_factory.rb +20 -1
- data/lib/alchemy/test_support/factories/page_version_factory.rb +23 -0
- data/lib/alchemy/test_support/having_crop_action_examples.rb +170 -0
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +646 -0
- data/lib/alchemy/test_support/shared_ingredient_editor_examples.rb +21 -0
- data/lib/alchemy/test_support/shared_ingredient_examples.rb +75 -0
- data/lib/alchemy/tinymce.rb +17 -0
- data/lib/alchemy/upgrader/six_point_zero.rb +21 -0
- data/lib/alchemy/upgrader/tasks/add_page_versions.rb +33 -0
- data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +59 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +1 -0
- data/lib/generators/alchemy/elements/elements_generator.rb +1 -0
- data/lib/generators/alchemy/elements/templates/view.html.erb +9 -0
- data/lib/generators/alchemy/elements/templates/view.html.haml +9 -0
- data/lib/generators/alchemy/elements/templates/view.html.slim +9 -0
- data/lib/generators/alchemy/ingredient/ingredient_generator.rb +38 -0
- data/lib/generators/alchemy/ingredient/templates/editor.html.erb +14 -0
- data/lib/generators/alchemy/ingredient/templates/model.rb.tt +13 -0
- data/lib/generators/alchemy/ingredient/templates/view.html.erb +1 -0
- data/lib/generators/alchemy/install/templates/dragonfly.rb.tt +1 -1
- data/lib/generators/alchemy/menus/templates/node.html.erb +1 -1
- data/lib/generators/alchemy/menus/templates/node.html.haml +1 -1
- data/lib/generators/alchemy/menus/templates/node.html.slim +1 -1
- data/lib/generators/alchemy/menus/templates/wrapper.html.erb +1 -1
- data/lib/generators/alchemy/menus/templates/wrapper.html.haml +1 -1
- data/lib/generators/alchemy/menus/templates/wrapper.html.slim +1 -1
- data/lib/tasks/alchemy/thumbnails.rake +4 -2
- data/lib/tasks/alchemy/tidy.rake +12 -0
- data/lib/tasks/alchemy/upgrade.rake +26 -0
- data/package.json +3 -2
- data/package/admin.js +11 -1
- data/package/src/__tests__/i18n.spec.js +23 -0
- data/package/src/file_editors.js +28 -0
- data/package/src/i18n.js +1 -3
- data/package/src/image_cropper.js +103 -0
- data/package/src/image_loader.js +58 -0
- data/package/src/node_tree.js +5 -5
- data/package/src/picture_editors.js +169 -0
- data/package/src/utils/__tests__/ajax.spec.js +20 -12
- data/package/src/utils/ajax.js +8 -3
- data/vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js +3 -18
- data/vendor/assets/stylesheets/jquery.Jcrop.min.scss +2 -28
- metadata +290 -53
- data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +0 -44
- data/app/assets/javascripts/alchemy/alchemy.trash_window.js.coffee +0 -30
- data/app/assets/stylesheets/alchemy/trash.scss +0 -8
- data/app/controllers/alchemy/admin/trash_controller.rb +0 -44
- data/app/views/alchemy/admin/attachments/_filter_bar.html.erb +0 -29
- data/app/views/alchemy/admin/essence_files/assign.js.erb +0 -3
- data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -4
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +0 -48
- data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +0 -30
- data/app/views/alchemy/admin/trash/clear.js.erb +0 -4
- data/app/views/alchemy/admin/trash/index.html.erb +0 -31
- data/lib/alchemy/test_support/factories.rb +0 -16
data/config/routes.rb
CHANGED
@@ -6,7 +6,7 @@ Alchemy::Engine.routes.draw do
|
|
6
6
|
|
7
7
|
get "/sitemap.xml" => "pages#sitemap", format: "xml"
|
8
8
|
|
9
|
-
scope Alchemy.admin_path, {constraints: Alchemy.admin_constraints} do
|
9
|
+
scope Alchemy.admin_path, { constraints: Alchemy.admin_constraints } do
|
10
10
|
get "/" => redirect("#{Alchemy.admin_path}/dashboard"), as: :admin
|
11
11
|
get "/dashboard" => "admin/dashboard#index", as: :admin_dashboard
|
12
12
|
get "/dashboard/info" => "admin/dashboard#info", as: :dashboard_info
|
@@ -15,7 +15,7 @@ Alchemy::Engine.routes.draw do
|
|
15
15
|
get "/leave" => "admin/base#leave", as: :leave_admin
|
16
16
|
end
|
17
17
|
|
18
|
-
namespace :admin, {path: Alchemy.admin_path, constraints: Alchemy.admin_constraints} do
|
18
|
+
namespace :admin, { path: Alchemy.admin_path, constraints: Alchemy.admin_constraints } do
|
19
19
|
resources :contents, only: [:create]
|
20
20
|
|
21
21
|
resources :nodes
|
@@ -35,7 +35,6 @@ Alchemy::Engine.routes.draw do
|
|
35
35
|
post :unlock
|
36
36
|
post :publish
|
37
37
|
post :fold
|
38
|
-
post :visit
|
39
38
|
get :configure
|
40
39
|
get :preview
|
41
40
|
get :info
|
@@ -50,7 +49,6 @@ Alchemy::Engine.routes.draw do
|
|
50
49
|
member do
|
51
50
|
patch :publish
|
52
51
|
post :fold
|
53
|
-
delete :trash
|
54
52
|
end
|
55
53
|
end
|
56
54
|
|
@@ -63,6 +61,8 @@ Alchemy::Engine.routes.draw do
|
|
63
61
|
get :edit_multiple
|
64
62
|
end
|
65
63
|
member do
|
64
|
+
get :url
|
65
|
+
put :assign
|
66
66
|
delete :remove
|
67
67
|
end
|
68
68
|
end
|
@@ -70,23 +70,25 @@ Alchemy::Engine.routes.draw do
|
|
70
70
|
resources :attachments, except: [:new] do
|
71
71
|
member do
|
72
72
|
get :download
|
73
|
+
put :assign
|
73
74
|
end
|
74
75
|
end
|
75
76
|
|
76
|
-
resources :
|
77
|
-
|
78
|
-
|
79
|
-
end
|
77
|
+
resources :essence_audios, only: [:edit, :update]
|
78
|
+
|
79
|
+
concern :croppable do
|
80
80
|
member do
|
81
81
|
get :crop
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
resources :
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
resources :essence_pictures, only: [:edit, :update], concerns: [:croppable]
|
86
|
+
|
87
|
+
resources :essence_files, only: [:edit, :update]
|
88
|
+
|
89
|
+
resources :essence_videos, only: [:edit, :update]
|
90
|
+
|
91
|
+
resources :ingredients, only: [:edit, :update], concerns: [:croppable]
|
90
92
|
|
91
93
|
resources :legacy_page_urls
|
92
94
|
resources :languages do
|
@@ -104,13 +106,6 @@ Alchemy::Engine.routes.draw do
|
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
107
|
-
resource :trash, only: :index, controller: "trash" do
|
108
|
-
collection do
|
109
|
-
get :index
|
110
|
-
delete :clear
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
109
|
resources :tags do
|
115
110
|
collection do
|
116
111
|
get :autocomplete
|
@@ -131,7 +126,7 @@ Alchemy::Engine.routes.draw do
|
|
131
126
|
resources :elements, only: :show
|
132
127
|
resources :contents, only: :show
|
133
128
|
|
134
|
-
namespace :api, defaults: {format: "json"} do
|
129
|
+
namespace :api, defaults: { format: "json" } do
|
135
130
|
resources :contents, only: [:index, :show]
|
136
131
|
|
137
132
|
resources :elements, only: [:index, :show] do
|
@@ -159,7 +154,7 @@ Alchemy::Engine.routes.draw do
|
|
159
154
|
end
|
160
155
|
|
161
156
|
get "/:locale" => "pages#index",
|
162
|
-
constraints: {locale: Alchemy::RoutingConstraints::LOCALE_REGEXP},
|
157
|
+
constraints: { locale: Alchemy::RoutingConstraints::LOCALE_REGEXP },
|
163
158
|
as: :show_language_root
|
164
159
|
|
165
160
|
# The page show action has to be last route
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreatePageVersions < ActiveRecord::Migration[5.2]
|
4
|
+
def change
|
5
|
+
create_table :alchemy_page_versions do |t|
|
6
|
+
t.references :page,
|
7
|
+
null: false,
|
8
|
+
index: true,
|
9
|
+
foreign_key: {
|
10
|
+
to_table: :alchemy_pages,
|
11
|
+
on_delete: :cascade,
|
12
|
+
}
|
13
|
+
t.datetime :public_on
|
14
|
+
t.datetime :public_until
|
15
|
+
t.index [:public_on, :public_until]
|
16
|
+
t.timestamps
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddPageVersionIdToAlchemyElements < ActiveRecord::Migration[5.2]
|
4
|
+
class LocalPage < ActiveRecord::Base
|
5
|
+
self.table_name = :alchemy_pages
|
6
|
+
has_many :elements, class_name: "LocalElement", inverse_of: :page
|
7
|
+
has_many :versions, class_name: "LocalVersion", inverse_of: :page, foreign_key: :page_id
|
8
|
+
end
|
9
|
+
|
10
|
+
class LocalVersion < ActiveRecord::Base
|
11
|
+
self.table_name = :alchemy_page_versions
|
12
|
+
belongs_to :page, class_name: "LocalPage", inverse_of: :versions
|
13
|
+
has_many :elements, class_name: "LocalElement", inverse_of: :versions
|
14
|
+
end
|
15
|
+
|
16
|
+
class LocalElement < ActiveRecord::Base
|
17
|
+
self.table_name = :alchemy_elements
|
18
|
+
belongs_to :page, class_name: "LocalPage", inverse_of: :elements
|
19
|
+
belongs_to :page_version, class_name: "LocalVersion", inverse_of: :elements
|
20
|
+
end
|
21
|
+
|
22
|
+
def change
|
23
|
+
add_reference :alchemy_elements, :page_version,
|
24
|
+
index: false,
|
25
|
+
foreign_key: {
|
26
|
+
to_table: :alchemy_page_versions,
|
27
|
+
on_delete: :cascade,
|
28
|
+
}
|
29
|
+
add_index :alchemy_elements, [:page_version_id, :parent_element_id],
|
30
|
+
name: "idx_alchemy_elements_on_page_version_id_and_parent_element_id"
|
31
|
+
add_index :alchemy_elements, [:page_version_id, :position],
|
32
|
+
name: "idx_alchemy_elements_on_page_version_id_and_position"
|
33
|
+
|
34
|
+
# Add a page version for each page so we can add a not null constraint
|
35
|
+
reversible do |dir|
|
36
|
+
dir.up do
|
37
|
+
say_with_time "Create draft version for each page." do
|
38
|
+
LocalPage.find_each do |page|
|
39
|
+
next if page.versions.any?
|
40
|
+
|
41
|
+
page.versions.create!.tap do |version|
|
42
|
+
Alchemy::Element.where(page_id: page.id).update_all(page_version_id: version.id)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
LocalVersion.count
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
change_column_null :alchemy_elements, :page_version_id, false
|
51
|
+
|
52
|
+
# Remove the existing page relation
|
53
|
+
remove_reference :alchemy_elements, :page,
|
54
|
+
null: false,
|
55
|
+
index: false,
|
56
|
+
foreign_key: {
|
57
|
+
to_table: :alchemy_pages,
|
58
|
+
on_delete: :cascade,
|
59
|
+
on_update: :cascade,
|
60
|
+
}
|
61
|
+
if index_exists? :alchemy_elements,
|
62
|
+
:parent_element_id,
|
63
|
+
name: "index_alchemy_elements_on_page_id_and_parent_element_id"
|
64
|
+
remove_index :alchemy_elements,
|
65
|
+
column: [:parent_element_id],
|
66
|
+
name: "index_alchemy_elements_on_page_id_and_parent_element_id"
|
67
|
+
end
|
68
|
+
if index_exists? :alchemy_elements,
|
69
|
+
:position,
|
70
|
+
name: "index_elements_on_page_id_and_position"
|
71
|
+
remove_index :alchemy_elements,
|
72
|
+
column: [:position],
|
73
|
+
name: "index_elements_on_page_id_and_position"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RenamePublicOnAndPublicUntilOnAlchemyPages < ActiveRecord::Migration[6.0]
|
4
|
+
def change
|
5
|
+
remove_index :alchemy_pages, column: [:public_on, :public_until],
|
6
|
+
name: "index_alchemy_pages_on_public_on_and_public_until"
|
7
|
+
rename_column :alchemy_pages, :public_on, :legacy_public_on
|
8
|
+
rename_column :alchemy_pages, :public_until, :legacy_public_until
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateEssenceAudios < ActiveRecord::Migration[6.0]
|
4
|
+
def up
|
5
|
+
return if table_exists? :alchemy_essence_audios
|
6
|
+
|
7
|
+
create_table :alchemy_essence_audios do |t|
|
8
|
+
t.references :attachment
|
9
|
+
t.boolean :controls, default: true, null: false
|
10
|
+
t.boolean :autoplay, default: false
|
11
|
+
t.boolean :loop, default: false, null: false
|
12
|
+
t.boolean :muted, default: false, null: false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def down
|
17
|
+
drop_table :alchemy_essence_audios
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateEssenceVideos < ActiveRecord::Migration[6.0]
|
4
|
+
def up
|
5
|
+
return if table_exists? :alchemy_essence_videos
|
6
|
+
|
7
|
+
create_table :alchemy_essence_videos do |t|
|
8
|
+
t.references :attachment
|
9
|
+
t.string :width
|
10
|
+
t.string :height
|
11
|
+
t.boolean :allow_fullscreen, default: true, null: false
|
12
|
+
t.boolean :autoplay, default: false, null: false
|
13
|
+
t.boolean :controls, default: true, null: false
|
14
|
+
t.boolean :loop, default: false, null: false
|
15
|
+
t.boolean :muted, default: false, null: false
|
16
|
+
t.string :preload
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def down
|
21
|
+
drop_table :alchemy_essence_videos
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateAlchemyIngredients < ActiveRecord::Migration[6.0]
|
4
|
+
def change
|
5
|
+
create_table :alchemy_ingredients do |t|
|
6
|
+
t.references :element, null: false, foreign_key: { to_table: :alchemy_elements, on_delete: :cascade }
|
7
|
+
t.string :type, index: true, null: false
|
8
|
+
t.string :role, null: false
|
9
|
+
t.text :value
|
10
|
+
if ActiveRecord::Migration.connection.adapter_name.match?(/postgres/i)
|
11
|
+
t.jsonb :data, default: {}
|
12
|
+
else
|
13
|
+
t.json :data
|
14
|
+
end
|
15
|
+
t.belongs_to :related_object, null: true, polymorphic: true, index: false
|
16
|
+
t.index [:element_id, :role], unique: true
|
17
|
+
t.index [:related_object_id, :related_object_type], name: "idx_alchemy_ingredient_relation"
|
18
|
+
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/alchemy/deprecation.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dragonfly/image_magick/commands"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module Dragonfly
|
7
|
+
module Processors
|
8
|
+
class AutoOrient
|
9
|
+
def call(content)
|
10
|
+
::Dragonfly::ImageMagick::Commands.convert(
|
11
|
+
content,
|
12
|
+
"-auto-orient"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dragonfly/image_magick/commands"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module Dragonfly
|
7
|
+
module Processors
|
8
|
+
class CropResize
|
9
|
+
include ::Dragonfly::ParamValidators
|
10
|
+
|
11
|
+
IS_CROP_ARGUMENT = ->(args_string) {
|
12
|
+
args_string.match?(::Dragonfly::ImageMagick::Processors::Thumb::CROP_GEOMETRY)
|
13
|
+
}
|
14
|
+
|
15
|
+
IS_RESIZE_ARGUMENT = ->(args_string) {
|
16
|
+
args_string.match?(::Dragonfly::ImageMagick::Processors::Thumb::RESIZE_GEOMETRY)
|
17
|
+
}
|
18
|
+
|
19
|
+
def call(content, crop_argument, resize_argument)
|
20
|
+
validate!(crop_argument, &IS_CROP_ARGUMENT)
|
21
|
+
validate!(resize_argument, &IS_RESIZE_ARGUMENT)
|
22
|
+
::Dragonfly::ImageMagick::Commands.convert(
|
23
|
+
content,
|
24
|
+
"-crop #{crop_argument} -resize #{resize_argument}"
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_url(attrs, _args = "", opts = {})
|
29
|
+
format = opts["format"]
|
30
|
+
attrs.ext = format if format
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "alchemy/logger"
|
4
4
|
|
5
5
|
module Alchemy
|
6
|
-
# Loads elements from given page
|
6
|
+
# Loads elements from given page version.
|
7
7
|
#
|
8
8
|
# Used by {Alchemy::Page#find_elements} and {Alchemy::ElementsHelper#render_elements} helper.
|
9
9
|
#
|
@@ -30,22 +30,18 @@ module Alchemy
|
|
30
30
|
@options = options
|
31
31
|
end
|
32
32
|
|
33
|
-
# @param page [Alchemy::
|
34
|
-
# The page the elements are loaded from.
|
35
|
-
# @return [
|
36
|
-
def elements(
|
37
|
-
elements = find_elements(
|
38
|
-
|
39
|
-
if fallback_required?(elements)
|
40
|
-
elements = elements.merge(fallback_elements)
|
41
|
-
end
|
33
|
+
# @param page [Alchemy::PageVersion]
|
34
|
+
# The page version the elements are loaded from.
|
35
|
+
# @return [Alchemy::ElementsRepository]
|
36
|
+
def elements(page_version:)
|
37
|
+
elements = find_elements(page_version)
|
42
38
|
|
43
39
|
if options[:reverse]
|
44
|
-
elements = elements.
|
40
|
+
elements = elements.reverse
|
45
41
|
end
|
46
42
|
|
47
43
|
if options[:random]
|
48
|
-
elements = elements.
|
44
|
+
elements = elements.random
|
49
45
|
end
|
50
46
|
|
51
47
|
elements.offset(options[:offset]).limit(options[:count])
|
@@ -53,17 +49,14 @@ module Alchemy
|
|
53
49
|
|
54
50
|
private
|
55
51
|
|
56
|
-
attr_reader :
|
52
|
+
attr_reader :options
|
57
53
|
|
58
|
-
def find_elements(
|
59
|
-
|
60
|
-
return Alchemy::Element.none unless page
|
54
|
+
def find_elements(page_version)
|
55
|
+
return Alchemy::ElementsRepository.none unless page_version
|
61
56
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
elements = page.elements
|
66
|
-
end
|
57
|
+
elements = Alchemy::ElementsRepository.new(page_version.elements.available)
|
58
|
+
elements = elements.not_nested
|
59
|
+
elements = options[:fixed] ? elements.fixed : elements.unfixed
|
67
60
|
|
68
61
|
if options[:only]
|
69
62
|
elements = elements.named(options[:only])
|
@@ -75,44 +68,5 @@ module Alchemy
|
|
75
68
|
|
76
69
|
elements
|
77
70
|
end
|
78
|
-
|
79
|
-
def get_page(page_or_layout)
|
80
|
-
case page_or_layout
|
81
|
-
when Alchemy::Page
|
82
|
-
page_or_layout
|
83
|
-
when String
|
84
|
-
Alchemy::Deprecation.warn "Passing a String as `from_page` option to " \
|
85
|
-
"`render_elements` is deprecated and will be removed with Alchemy 6.0. " \
|
86
|
-
"Please load the page beforehand and pass it as an object instead."
|
87
|
-
Alchemy::Page.find_by(
|
88
|
-
language: Alchemy::Language.current,
|
89
|
-
page_layout: page_or_layout,
|
90
|
-
restricted: false,
|
91
|
-
)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def fallback_required?(elements)
|
96
|
-
if options[:fallback]
|
97
|
-
Alchemy::Deprecation.warn "Passing `fallback` options to `render_elements` is deprecated an will be removed with Alchemy 6.0."
|
98
|
-
end
|
99
|
-
options[:fallback] && elements
|
100
|
-
.where(Alchemy::Element.table_name => {name: options[:fallback][:for]})
|
101
|
-
.none?
|
102
|
-
end
|
103
|
-
|
104
|
-
def fallback_elements
|
105
|
-
find_elements(options[:fallback][:from])
|
106
|
-
.named(options[:fallback][:with] || options[:fallback][:for])
|
107
|
-
end
|
108
|
-
|
109
|
-
def random_function
|
110
|
-
case ActiveRecord::Base.connection_config[:adapter]
|
111
|
-
when "postgresql", "sqlite3"
|
112
|
-
"RANDOM()"
|
113
|
-
else
|
114
|
-
"RAND()"
|
115
|
-
end
|
116
|
-
end
|
117
71
|
end
|
118
72
|
end
|