alchemy_cms 3.4.2 → 3.5.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/.codeclimate.yml +9 -3
- data/.teatro.yml +1 -0
- data/.travis.yml +14 -17
- data/CHANGELOG.md +44 -6
- data/Gemfile +7 -4
- data/README.md +60 -10
- data/Rakefile +1 -1
- data/alchemy_cms.gemspec +5 -8
- data/app/assets/javascripts/alchemy/admin.js +2 -0
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +1 -0
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +1 -0
- data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +9 -7
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +1 -0
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +11 -7
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +8 -3
- data/app/assets/javascripts/alchemy/alchemy.tooltips.coffee +10 -0
- data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +104 -73
- data/app/assets/stylesheets/alchemy/_defaults.scss +1 -4
- data/app/assets/stylesheets/alchemy/_extends.scss +13 -35
- data/app/assets/stylesheets/alchemy/_mixins.scss +82 -18
- data/app/assets/stylesheets/alchemy/_variables.scss +21 -8
- data/app/assets/stylesheets/alchemy/admin.scss +4 -0
- data/app/assets/stylesheets/alchemy/archive.scss +8 -12
- data/app/assets/stylesheets/alchemy/attachments.scss +39 -0
- data/app/assets/stylesheets/alchemy/base.scss +26 -15
- data/app/assets/stylesheets/alchemy/buttons.scss +59 -31
- data/app/assets/stylesheets/alchemy/dashboard.scss +3 -3
- data/app/assets/stylesheets/alchemy/dialogs.scss +10 -8
- data/app/assets/stylesheets/alchemy/elements.scss +65 -41
- data/app/assets/stylesheets/alchemy/errors.scss +7 -0
- data/app/assets/stylesheets/alchemy/flash.scss +1 -1
- data/app/assets/stylesheets/alchemy/form_fields.scss +0 -37
- data/app/assets/stylesheets/alchemy/forms.scss +18 -27
- data/app/assets/stylesheets/alchemy/frame.scss +104 -204
- data/app/assets/stylesheets/alchemy/hints.scss +62 -0
- data/app/assets/stylesheets/alchemy/icon-font.scss +2 -1
- data/app/assets/stylesheets/alchemy/icons.scss +9 -4
- data/app/assets/stylesheets/alchemy/image_library.scss +6 -6
- data/app/assets/stylesheets/alchemy/jquery-ui.scss +6 -4
- data/app/assets/stylesheets/alchemy/lists.scss +0 -1
- data/app/assets/stylesheets/alchemy/menubar.scss +3 -4
- data/app/assets/stylesheets/alchemy/modules.scss +0 -6
- data/app/assets/stylesheets/alchemy/navigation.scss +242 -0
- data/app/assets/stylesheets/alchemy/pagination.scss +3 -3
- data/app/assets/stylesheets/alchemy/print.scss +1 -0
- data/app/assets/stylesheets/alchemy/resource_info.scss +45 -0
- data/app/assets/stylesheets/alchemy/search.scss +72 -1
- data/app/assets/stylesheets/alchemy/selects.scss +38 -44
- data/app/assets/stylesheets/alchemy/sitemap.scss +89 -79
- data/app/assets/stylesheets/alchemy/tables.scss +6 -10
- data/app/assets/stylesheets/alchemy/toolbar.scss +7 -36
- data/app/assets/stylesheets/alchemy/upload.scss +12 -3
- data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +6 -3
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.svg +58 -170
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.ttf +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.woff +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.svg +124 -148
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.ttf +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.woff +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +426 -144
- data/app/controllers/alchemy/admin/attachments_controller.rb +24 -16
- data/app/controllers/alchemy/admin/clipboard_controller.rb +1 -1
- data/app/controllers/alchemy/admin/essence_files_controller.rb +1 -1
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +9 -8
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +1 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +2 -2
- data/app/controllers/alchemy/admin/resources_controller.rb +2 -2
- data/app/controllers/alchemy/admin/tags_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +16 -0
- data/app/controllers/alchemy/messages_controller.rb +1 -1
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +2 -2
- data/app/helpers/alchemy/admin/attachments_helper.rb +11 -0
- data/app/helpers/alchemy/admin/base_helper.rb +37 -4
- data/app/helpers/alchemy/admin/contents_helper.rb +11 -4
- data/app/helpers/alchemy/admin/elements_helper.rb +0 -19
- data/app/helpers/alchemy/admin/essences_helper.rb +7 -30
- data/app/helpers/alchemy/admin/navigation_helper.rb +13 -51
- data/app/helpers/alchemy/admin/pages_helper.rb +21 -16
- data/app/helpers/alchemy/admin/pictures_helper.rb +9 -0
- data/app/helpers/alchemy/deprecated_pages_helper.rb +54 -0
- data/app/helpers/alchemy/essences_helper.rb +1 -1
- data/app/helpers/alchemy/pages_helper.rb +8 -109
- data/app/helpers/alchemy/url_helper.rb +8 -13
- data/app/models/alchemy/attachment.rb +7 -4
- data/app/models/alchemy/cell.rb +2 -2
- data/app/models/alchemy/content.rb +2 -2
- data/app/models/alchemy/content/factory.rb +12 -9
- data/app/models/alchemy/element.rb +6 -3
- data/app/models/alchemy/essence_file.rb +1 -1
- data/app/models/alchemy/essence_picture.rb +37 -47
- data/app/models/alchemy/essence_picture_view.rb +8 -1
- data/app/models/alchemy/folded_page.rb +3 -2
- data/app/models/alchemy/legacy_page_url.rb +3 -3
- data/app/models/alchemy/page.rb +50 -5
- data/app/models/alchemy/page/fixed_attributes.rb +63 -0
- data/app/models/alchemy/page/page_elements.rb +10 -7
- data/app/models/alchemy/page/page_natures.rb +19 -0
- data/app/models/alchemy/picture.rb +1 -0
- data/app/models/alchemy/picture/transformations.rb +1 -1
- data/app/models/alchemy/picture/url.rb +82 -0
- data/app/serializers/alchemy/page_tree_serializer.rb +29 -8
- data/app/views/alchemy/_edit_mode.html.erb +2 -0
- data/app/views/alchemy/_menubar.html.erb +1 -1
- data/app/views/alchemy/_preview_mode_code.html.erb +6 -0
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_attachment.html.erb +25 -5
- data/app/views/alchemy/admin/attachments/_replace_button.html.erb +26 -0
- data/app/views/alchemy/admin/attachments/index.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/show.html.erb +52 -0
- data/app/views/alchemy/admin/elements/_element_header.html.erb +6 -3
- data/app/views/alchemy/admin/elements/create.js.erb +0 -2
- data/app/views/alchemy/admin/elements/trash.js.erb +0 -1
- data/app/views/alchemy/admin/elements/update.js.erb +0 -2
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -4
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +1 -1
- data/app/views/alchemy/admin/languages/index.html.erb +1 -0
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +26 -27
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_form.html.erb +13 -40
- data/app/views/alchemy/admin/pages/_locked_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_page.html.erb +119 -61
- data/app/views/alchemy/admin/pages/_page_for_links.html.erb +4 -2
- data/app/views/alchemy/admin/pages/_page_infos.html.erb +12 -12
- data/app/views/alchemy/admin/pages/_page_status.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +35 -0
- data/app/views/alchemy/admin/pages/edit.html.erb +13 -2
- data/app/views/alchemy/admin/pages/index.html.erb +3 -8
- data/app/views/alchemy/admin/pages/info.html.erb +15 -2
- data/app/views/alchemy/admin/pages/sort.js.erb +1 -1
- data/app/views/alchemy/admin/pages/update.js.erb +1 -14
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +12 -8
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +4 -4
- data/app/views/alchemy/admin/partials/_search_form.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_sub_navigation.html.erb +9 -6
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_picture.html.erb +1 -6
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -6
- data/app/views/alchemy/admin/pictures/index.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/show.html.erb +1 -6
- data/app/views/alchemy/admin/uploader/_button.html.erb +4 -4
- data/app/views/alchemy/base/500.html.erb +15 -1
- data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +13 -15
- data/app/views/alchemy/essences/_essence_boolean_view.html.erb +1 -3
- data/app/views/alchemy/essences/_essence_date_editor.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_date_view.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +2 -7
- data/app/views/alchemy/essences/_essence_file_view.html.erb +1 -3
- data/app/views/alchemy/essences/_essence_html_editor.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_html_view.html.erb +1 -3
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_link_view.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +47 -49
- data/app/views/alchemy/essences/_essence_picture_view.html.erb +1 -3
- data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_richtext_view.html.erb +1 -3
- data/app/views/alchemy/essences/_essence_select_editor.html.erb +27 -29
- data/app/views/alchemy/essences/_essence_select_view.html.erb +1 -3
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +17 -19
- data/app/views/alchemy/essences/_essence_text_view.html.erb +0 -2
- data/app/views/alchemy/pages/_meta_data.html.erb +9 -0
- data/app/views/layouts/alchemy/admin.html.erb +9 -11
- data/bin/alchemy +1 -2
- data/config/alchemy/config.yml +1 -1
- data/config/alchemy/modules.yml +0 -16
- data/config/initializers/dragonfly.rb +0 -18
- data/config/initializers/mini_profiler.rb +6 -0
- data/config/locales/alchemy.de.yml +9 -1
- data/config/locales/alchemy.en.yml +7 -1
- data/config/locales/alchemy.es.yml +6 -0
- data/config/locales/alchemy.fr.yml +2 -0
- data/config/locales/alchemy.it.yml +3 -1
- data/config/locales/alchemy.nl.yml +2 -0
- data/config/locales/alchemy.ru.yml +2 -0
- data/config/routes.rb +3 -8
- data/db/migrate/20160912223112_add_index_to_alchemy_pages_rgt.rb +9 -0
- data/db/migrate/20160927205604_add_foreign_key_indices_and_null_constraints.rb +20 -0
- data/db/migrate/20160928080104_add_foreign_keys.rb +27 -0
- data/lib/alchemy/admin/locale.rb +4 -3
- data/lib/alchemy/engine.rb +2 -4
- data/lib/alchemy/errors.rb +9 -2
- data/lib/alchemy/forms/builder.rb +8 -0
- data/lib/alchemy/modules.rb +20 -19
- data/lib/alchemy/permissions.rb +15 -4
- data/lib/alchemy/resources_helper.rb +4 -2
- data/lib/alchemy/sass_support.rb +9 -0
- data/lib/alchemy/seeder.rb +89 -1
- data/lib/alchemy/test_support/essence_shared_examples.rb +2 -0
- data/lib/alchemy/test_support/factories/attachment_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/content_factory.rb +1 -0
- data/lib/alchemy/test_support/factories/element_factory.rb +1 -0
- data/lib/alchemy/test_support/factories/picture_factory.rb +1 -1
- data/lib/alchemy/test_support/fixtures/image.png +0 -0
- data/lib/alchemy/tinymce.rb +2 -6
- data/lib/alchemy/upgrader.rb +4 -55
- data/lib/alchemy/upgrader/tasks/install_dragonfly_config.rb +14 -0
- data/lib/alchemy/upgrader/three_point_five.rb +32 -0
- data/lib/alchemy/upgrader/three_point_four.rb +2 -8
- data/lib/alchemy/upgrader/three_point_one.rb +30 -30
- data/lib/alchemy/upgrader/three_point_three.rb +31 -31
- data/lib/alchemy/upgrader/three_point_two.rb +25 -25
- data/lib/alchemy/upgrader/three_point_zero.rb +59 -59
- data/lib/alchemy/version.rb +1 -1
- data/lib/rails/generators/alchemy/elements/templates/view.html.erb +1 -1
- data/lib/rails/generators/alchemy/elements/templates/view.html.haml +1 -1
- data/lib/rails/generators/alchemy/elements/templates/view.html.slim +1 -1
- data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -3
- data/lib/rails/generators/alchemy/install/files/_article_view.html.erb +1 -1
- data/lib/rails/generators/alchemy/install/files/application.html.erb +3 -4
- data/lib/rails/generators/alchemy/install/install_generator.rb +4 -0
- data/lib/rails/generators/alchemy/install/templates/dragonfly.rb.tt +35 -0
- data/lib/rails/generators/alchemy/module/module_generator.rb +1 -1
- data/lib/tasks/alchemy/db.rake +6 -0
- data/lib/tasks/alchemy/tidy.rake +85 -0
- data/lib/tasks/alchemy/upgrade.rake +165 -16
- data/vendor/assets/javascripts/clipboard.min.js +7 -0
- data/vendor/assets/javascripts/fileupload/jquery.fileupload-process.js +4 -4
- data/vendor/assets/javascripts/fileupload/jquery.fileupload-validate.js +2 -2
- data/vendor/assets/javascripts/fileupload/jquery.fileupload.js +29 -14
- data/vendor/assets/javascripts/fileupload/jquery.iframe-transport.js +2 -2
- data/vendor/assets/javascripts/tinymce/langs/es.js +2 -2
- data/vendor/assets/javascripts/tinymce/langs/fr.js +1 -1
- data/vendor/assets/javascripts/tinymce/langs/it.js +1 -1
- data/vendor/assets/javascripts/tinymce/langs/nl.js +3 -3
- data/vendor/assets/javascripts/tinymce/tinymce.min.js +15 -12
- metadata +44 -88
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/readme.md +0 -1
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.eot +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.eot +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/img/wline.gif +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.ie7.min.css +0 -1
- data/app/controllers/alchemy/pictures_controller.rb +0 -97
- data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +0 -8
- data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/code/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/hr/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/tabfocus/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +0 -1
- data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +0 -1
|
@@ -33,25 +33,25 @@ module Alchemy
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def create
|
|
36
|
-
@attachment = Attachment.
|
|
37
|
-
|
|
38
|
-
render succesful_uploader_response(file: @attachment)
|
|
39
|
-
else
|
|
40
|
-
render failed_uploader_response(file: @attachment)
|
|
41
|
-
end
|
|
36
|
+
@attachment = Attachment.create(attachment_attributes)
|
|
37
|
+
handle_uploader_response(status: :created)
|
|
42
38
|
end
|
|
43
39
|
|
|
44
40
|
def update
|
|
45
|
-
@attachment.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
@attachment.update(attachment_attributes)
|
|
42
|
+
if attachment_attributes['file'].present?
|
|
43
|
+
handle_uploader_response(status: :accepted)
|
|
44
|
+
else
|
|
45
|
+
render_errors_or_redirect(
|
|
46
|
+
@attachment,
|
|
47
|
+
admin_attachments_path(
|
|
48
|
+
per_page: params[:per_page],
|
|
49
|
+
page: params[:page],
|
|
50
|
+
q: params[:q]
|
|
51
|
+
),
|
|
52
|
+
Alchemy.t("File successfully updated")
|
|
53
|
+
)
|
|
54
|
+
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def destroy
|
|
@@ -75,6 +75,14 @@ module Alchemy
|
|
|
75
75
|
|
|
76
76
|
private
|
|
77
77
|
|
|
78
|
+
def handle_uploader_response(status:)
|
|
79
|
+
if @attachment.valid?
|
|
80
|
+
render succesful_uploader_response(file: @attachment, status: status)
|
|
81
|
+
else
|
|
82
|
+
render failed_uploader_response(file: @attachment)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
78
86
|
def in_overlay?
|
|
79
87
|
params[:content_id].present?
|
|
80
88
|
end
|
|
@@ -2,7 +2,7 @@ module Alchemy
|
|
|
2
2
|
module Admin
|
|
3
3
|
class ClipboardController < Alchemy::Admin::BaseController
|
|
4
4
|
authorize_resource class: :alchemy_admin_clipboard
|
|
5
|
-
|
|
5
|
+
before_action :set_clipboard
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
8
|
@clipboard_items = model_class.all_from_clipboard(@clipboard)
|
|
@@ -3,7 +3,7 @@ module Alchemy
|
|
|
3
3
|
class EssenceFilesController < Alchemy::Admin::BaseController
|
|
4
4
|
authorize_resource class: Alchemy::EssenceFile
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
before_action :load_essence_file, only: [:edit, :update]
|
|
7
7
|
|
|
8
8
|
helper "Alchemy::Admin::Contents"
|
|
9
9
|
|
|
@@ -3,9 +3,9 @@ module Alchemy
|
|
|
3
3
|
class EssencePicturesController < Alchemy::Admin::BaseController
|
|
4
4
|
authorize_resource class: Alchemy::EssencePicture
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
before_action :load_essence_picture, only: [:edit, :crop, :update]
|
|
7
|
+
before_action :load_content, only: [:edit, :update, :assign]
|
|
8
|
+
before_action :load_options
|
|
9
9
|
|
|
10
10
|
helper 'alchemy/admin/contents'
|
|
11
11
|
helper 'alchemy/admin/essences'
|
|
@@ -74,14 +74,15 @@ module Alchemy
|
|
|
74
74
|
@content = Content.find(params[:content_id])
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
# Gets the minimum size of the image to be rendered.
|
|
78
|
-
#
|
|
77
|
+
# Gets the minimum size of the image to be rendered.
|
|
78
|
+
#
|
|
79
|
+
# The +render_size+ attribute has preference over the +size+ parameter.
|
|
79
80
|
#
|
|
80
81
|
def sizes_from_essence_or_params
|
|
81
|
-
if @essence_picture.render_size?
|
|
82
|
+
if @essence_picture.render_size?
|
|
82
83
|
@essence_picture.sizes_from_string(@essence_picture.render_size)
|
|
83
|
-
elsif @options[:
|
|
84
|
-
@essence_picture.sizes_from_string(@options[:
|
|
84
|
+
elsif @options[:size]
|
|
85
|
+
@essence_picture.sizes_from_string(@options[:size])
|
|
85
86
|
else
|
|
86
87
|
{ width: 0, height: 0 }
|
|
87
88
|
end
|
|
@@ -2,6 +2,7 @@ module Alchemy
|
|
|
2
2
|
module Admin
|
|
3
3
|
class LayoutpagesController < Alchemy::Admin::BaseController
|
|
4
4
|
authorize_resource class: :alchemy_admin_layoutpages
|
|
5
|
+
helper Alchemy::Admin::PagesHelper
|
|
5
6
|
|
|
6
7
|
def index
|
|
7
8
|
@layout_root = Page.find_or_create_layout_root_for(Language.current.id)
|
|
@@ -81,7 +81,7 @@ module Alchemy
|
|
|
81
81
|
def edit
|
|
82
82
|
# fetching page via before filter
|
|
83
83
|
if page_is_locked?
|
|
84
|
-
flash[:
|
|
84
|
+
flash[:warning] = Alchemy.t('This page is locked', name: @page.locker_name)
|
|
85
85
|
redirect_to admin_pages_path
|
|
86
86
|
elsif page_needs_lock?
|
|
87
87
|
@page.lock_to!(current_alchemy_user)
|
|
@@ -348,7 +348,7 @@ module Alchemy
|
|
|
348
348
|
end
|
|
349
349
|
|
|
350
350
|
def redirect_path_after_create_page
|
|
351
|
-
if @page.redirects_to_external?
|
|
351
|
+
if @page.redirects_to_external? || !@page.editable_by?(current_alchemy_user)
|
|
352
352
|
admin_pages_path
|
|
353
353
|
else
|
|
354
354
|
params[:redirect_to] || edit_admin_page_path(@page)
|
|
@@ -10,10 +10,10 @@ module Alchemy
|
|
|
10
10
|
helper Alchemy::ResourcesHelper, TagsHelper
|
|
11
11
|
helper_method :resource_handler
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
before_action :load_resource,
|
|
14
14
|
only: [:show, :edit, :update, :destroy]
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
before_action do
|
|
17
17
|
authorize!(action_name.to_sym, resource_instance_variable || resource_handler.model)
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -12,6 +12,22 @@ module Alchemy
|
|
|
12
12
|
respond_with @pages
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# Returns all pages as nested json object for tree views
|
|
16
|
+
#
|
|
17
|
+
# Pass a page_id param to only load tree for this page
|
|
18
|
+
#
|
|
19
|
+
# Pass elements=true param to include elements for pages
|
|
20
|
+
#
|
|
21
|
+
def nested
|
|
22
|
+
@page = Page.find_by(id: params[:page_id]) || Language.current_root_page
|
|
23
|
+
|
|
24
|
+
render json: PageTreeSerializer.new(@page,
|
|
25
|
+
ability: current_ability,
|
|
26
|
+
user: current_alchemy_user,
|
|
27
|
+
elements: params[:elements],
|
|
28
|
+
full: true)
|
|
29
|
+
end
|
|
30
|
+
|
|
15
31
|
# Returns a json object for page
|
|
16
32
|
#
|
|
17
33
|
# You can either load the page via id or its urlname
|
|
@@ -42,7 +42,7 @@ module Alchemy
|
|
|
42
42
|
# Please have a look at the +alchemy/config/config.yml+ file for further Message settings.
|
|
43
43
|
#
|
|
44
44
|
class MessagesController < Alchemy::BaseController
|
|
45
|
-
|
|
45
|
+
before_action :get_page, except: :create
|
|
46
46
|
|
|
47
47
|
helper 'alchemy/pages'
|
|
48
48
|
|
|
@@ -3,7 +3,7 @@ module Alchemy
|
|
|
3
3
|
module UploaderResponses
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
5
|
|
|
6
|
-
def succesful_uploader_response(file:)
|
|
6
|
+
def succesful_uploader_response(file:, status: :created)
|
|
7
7
|
message = Alchemy.t(:upload_success,
|
|
8
8
|
scope: [:uploader, file.class.model_name.i18n_key],
|
|
9
9
|
name: file.name
|
|
@@ -11,7 +11,7 @@ module Alchemy
|
|
|
11
11
|
|
|
12
12
|
{
|
|
13
13
|
json: uploader_response(file: file, message: message),
|
|
14
|
-
status:
|
|
14
|
+
status: status
|
|
15
15
|
}
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -6,6 +6,17 @@ module Alchemy
|
|
|
6
6
|
def mime_to_human(mime)
|
|
7
7
|
Alchemy.t(mime, scope: 'mime_types', default: Alchemy.t(:document))
|
|
8
8
|
end
|
|
9
|
+
|
|
10
|
+
def attachment_preview_size(attachment)
|
|
11
|
+
case attachment.icon_css_class
|
|
12
|
+
when 'image' then '600x475'
|
|
13
|
+
when 'audio' then '600x190'
|
|
14
|
+
when 'video' then '600x485'
|
|
15
|
+
when 'pdf' then '600x500'
|
|
16
|
+
else
|
|
17
|
+
'600x145'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
9
20
|
end
|
|
10
21
|
end
|
|
11
22
|
end
|
|
@@ -58,7 +58,7 @@ module Alchemy
|
|
|
58
58
|
|
|
59
59
|
# Used for translations selector in Alchemy cockpit user settings.
|
|
60
60
|
def translations_for_select
|
|
61
|
-
Alchemy::I18n.available_locales.map do |locale|
|
|
61
|
+
Alchemy::I18n.available_locales.sort.map do |locale|
|
|
62
62
|
[Alchemy.t(locale, scope: :translations), locale]
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -397,16 +397,24 @@ module Alchemy
|
|
|
397
397
|
current_params.merge(p).delete_if { |_k, v| v.blank? }
|
|
398
398
|
end
|
|
399
399
|
|
|
400
|
+
# Render a hint icon with tooltip for given object.
|
|
401
|
+
# The model class needs to include the hints module
|
|
400
402
|
def render_hint_for(element)
|
|
401
403
|
return unless element.has_hint?
|
|
402
|
-
|
|
403
|
-
render_icon(:
|
|
404
|
+
content_tag :span, class: 'hint-with-icon' do
|
|
405
|
+
render_icon(:questionmark) +
|
|
406
|
+
content_tag(:span, element.hint.html_safe, class: 'hint-bubble')
|
|
404
407
|
end
|
|
405
408
|
end
|
|
406
409
|
|
|
407
410
|
# Appends the current controller and action to body as css class.
|
|
408
411
|
def alchemy_body_class
|
|
409
|
-
|
|
412
|
+
[
|
|
413
|
+
controller_name,
|
|
414
|
+
action_name,
|
|
415
|
+
content_for(:main_menu_style),
|
|
416
|
+
content_for(:alchemy_body_class)
|
|
417
|
+
].compact
|
|
410
418
|
end
|
|
411
419
|
|
|
412
420
|
# (internal) Returns options for the clipboard select tag
|
|
@@ -426,6 +434,31 @@ module Alchemy
|
|
|
426
434
|
Alchemy::Config.get(:format_matchers)['link_url'] || /^(mailto:|\/|[a-z]+:\/\/)/
|
|
427
435
|
end
|
|
428
436
|
|
|
437
|
+
# Renders a hint with tooltip
|
|
438
|
+
#
|
|
439
|
+
# == Example
|
|
440
|
+
#
|
|
441
|
+
# <%= hint_with_tooltip('Page layout is missing', class: 'warning icon') %>
|
|
442
|
+
#
|
|
443
|
+
# @param text [String] - The text displayed in the tooltip
|
|
444
|
+
# @param html_options [Hash] - Options passed to the wrapper `content_tag`
|
|
445
|
+
#
|
|
446
|
+
def hint_with_tooltip(text, html_options = {})
|
|
447
|
+
css_class = "#{html_options[:class]} with-hint"
|
|
448
|
+
content_tag :span, html_options.merge(class: css_class) do
|
|
449
|
+
content_tag(:span, text, class: 'hint-bubble')
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
# Renders a warning icon with a hint
|
|
454
|
+
# that explains the user that the page layout is missing
|
|
455
|
+
def page_layout_missing_warning
|
|
456
|
+
hint_with_tooltip(
|
|
457
|
+
Alchemy.t(:page_definition_missing),
|
|
458
|
+
class: 'inline warning icon'
|
|
459
|
+
)
|
|
460
|
+
end
|
|
461
|
+
|
|
429
462
|
private
|
|
430
463
|
|
|
431
464
|
def permission_from_options(options)
|
|
@@ -13,14 +13,21 @@ module Alchemy
|
|
|
13
13
|
if content.blank?
|
|
14
14
|
warning('Content is nil')
|
|
15
15
|
return
|
|
16
|
-
else
|
|
17
|
-
content_name = content.name_for_label
|
|
18
16
|
end
|
|
17
|
+
|
|
18
|
+
content_name = content.name_for_label
|
|
19
|
+
|
|
19
20
|
if content.definition.blank?
|
|
20
21
|
warning("Content #{content.name} is missing its definition")
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
icon = hint_with_tooltip(
|
|
24
|
+
Alchemy.t(:content_definition_missing),
|
|
25
|
+
class: 'inline warning icon'
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
content_name = "#{icon} #{content_name}".html_safe
|
|
23
29
|
end
|
|
30
|
+
|
|
24
31
|
if content.has_validations?
|
|
25
32
|
"#{content_name}<span class='validation_indicator'>*</span>".html_safe
|
|
26
33
|
else
|
|
@@ -94,25 +94,6 @@ module Alchemy
|
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
# This helper loads all elements from page that have EssenceSelects in them.
|
|
98
|
-
#
|
|
99
|
-
# It returns a javascript function that replaces all editor partials of this elements.
|
|
100
|
-
#
|
|
101
|
-
# We need this while updating, creating or trashing an element,
|
|
102
|
-
# because another element on the same page could have a element selector in it.
|
|
103
|
-
#
|
|
104
|
-
# In cases like this one wants Ember.js databinding!
|
|
105
|
-
#
|
|
106
|
-
def update_essence_select_elements(page, element)
|
|
107
|
-
elements = page.elements.not_trashed.joins(:contents)
|
|
108
|
-
.where(["#{Content.table_name}.element_id != ?", element.id])
|
|
109
|
-
.where(Content.table_name => {essence_type: "Alchemy::EssenceSelect"})
|
|
110
|
-
return if elements.blank?
|
|
111
|
-
elements.collect do |el|
|
|
112
|
-
render 'alchemy/admin/elements/refresh_editor', element: el
|
|
113
|
-
end.join.html_safe
|
|
114
|
-
end
|
|
115
|
-
|
|
116
97
|
# CSS classes for the element editor partial.
|
|
117
98
|
def element_editor_classes(element, local_assigns)
|
|
118
99
|
[
|
|
@@ -56,41 +56,18 @@ module Alchemy
|
|
|
56
56
|
render 'alchemy/admin/contents/missing', {element: element, name: name, options: options}
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
# Renders a thumbnail for given EssencePicture content with correct cropping and size
|
|
60
|
+
def essence_picture_thumbnail(content, options = {})
|
|
61
|
+
picture = content.ingredient
|
|
61
62
|
essence = content.essence
|
|
62
|
-
return if ingredient.blank?
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
(
|
|
66
|
-
content.settings_value(:crop, options) == true ||
|
|
67
|
-
content.settings_value(:crop, options) == "true"
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
size = if essence.render_size.blank?
|
|
71
|
-
content.settings_value(:size, options)
|
|
72
|
-
else
|
|
73
|
-
essence.render_size
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
image_options = {
|
|
77
|
-
size: essence.thumbnail_size(size, crop),
|
|
78
|
-
crop_from: essence.crop_from.blank? ? nil : essence.crop_from,
|
|
79
|
-
crop_size: essence.crop_size.blank? ? nil : essence.crop_size,
|
|
80
|
-
crop: crop ? 'crop' : nil,
|
|
81
|
-
upsample: content.settings_value(:upsample, options)
|
|
82
|
-
}
|
|
64
|
+
return if picture.nil?
|
|
83
65
|
|
|
84
66
|
image_tag(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
name: ingredient.urlname,
|
|
88
|
-
sh: ingredient.security_token(image_options),
|
|
89
|
-
format: ingredient.image_file_format
|
|
90
|
-
}.merge(image_options)),
|
|
91
|
-
alt: ingredient.name,
|
|
67
|
+
essence.thumbnail_url(options),
|
|
68
|
+
alt: picture.name,
|
|
92
69
|
class: 'img_paddingtop',
|
|
93
|
-
title: Alchemy.t(:image_name) + ": #{
|
|
70
|
+
title: Alchemy.t(:image_name) + ": #{picture.name}"
|
|
94
71
|
)
|
|
95
72
|
end
|
|
96
73
|
|
|
@@ -11,24 +11,11 @@ module Alchemy
|
|
|
11
11
|
def alchemy_main_navigation_entry(alchemy_module)
|
|
12
12
|
render(
|
|
13
13
|
'alchemy/admin/partials/main_navigation_entry',
|
|
14
|
-
alchemy_module: alchemy_module
|
|
15
|
-
navigation:
|
|
14
|
+
alchemy_module: alchemy_module,
|
|
15
|
+
navigation: alchemy_module['navigation']
|
|
16
16
|
)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
# Renders the subnavigation from current module
|
|
20
|
-
#
|
|
21
|
-
# We find the module from current controller and index action.
|
|
22
|
-
#
|
|
23
|
-
def admin_subnavigation
|
|
24
|
-
if current_alchemy_module.present?
|
|
25
|
-
render(
|
|
26
|
-
'alchemy/admin/partials/sub_navigation',
|
|
27
|
-
entries: current_sub_navigation
|
|
28
|
-
)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
19
|
# Used for checking the main navi permissions
|
|
33
20
|
#
|
|
34
21
|
# To let your module be navigatable by the user you have to provide an Ability for it.
|
|
@@ -46,7 +33,6 @@ module Alchemy
|
|
|
46
33
|
# can :index, :my_admin_posts
|
|
47
34
|
#
|
|
48
35
|
def navigate_module(navigation)
|
|
49
|
-
navigation.stringify_keys!
|
|
50
36
|
[
|
|
51
37
|
navigation['action'].to_sym,
|
|
52
38
|
navigation['controller'].to_s.gsub(/\A\//, '').gsub(/\//, '_').to_sym
|
|
@@ -58,8 +44,9 @@ module Alchemy
|
|
|
58
44
|
def main_navigation_css_classes(navigation)
|
|
59
45
|
[
|
|
60
46
|
'main_navi_entry',
|
|
61
|
-
admin_mainnavi_active?(navigation) ? 'active' : nil
|
|
62
|
-
|
|
47
|
+
admin_mainnavi_active?(navigation) ? 'active' : nil,
|
|
48
|
+
navigation.key?('sub_navigation') ? 'has_sub_navigation' : nil
|
|
49
|
+
].compact
|
|
63
50
|
end
|
|
64
51
|
|
|
65
52
|
# Returns true if given navi entry is in params controller and action
|
|
@@ -148,7 +135,7 @@ module Alchemy
|
|
|
148
135
|
# A Alchemy module definition
|
|
149
136
|
#
|
|
150
137
|
def url_options_for_module(alchemy_module)
|
|
151
|
-
url_options_for_navigation_entry(
|
|
138
|
+
url_options_for_navigation_entry(alchemy_module['navigation'] || {})
|
|
152
139
|
end
|
|
153
140
|
|
|
154
141
|
# Returns a url options hash for given navigation entry.
|
|
@@ -157,7 +144,6 @@ module Alchemy
|
|
|
157
144
|
# A Alchemy module navigation entry
|
|
158
145
|
#
|
|
159
146
|
def url_options_for_navigation_entry(entry)
|
|
160
|
-
entry.stringify_keys!
|
|
161
147
|
{
|
|
162
148
|
controller: entry['controller'],
|
|
163
149
|
action: entry['action'],
|
|
@@ -172,40 +158,15 @@ module Alchemy
|
|
|
172
158
|
module_definition_for(controller: params[:controller], action: 'index')
|
|
173
159
|
end
|
|
174
160
|
|
|
175
|
-
# Returns the sub navigation for current Alchemy module.
|
|
176
|
-
#
|
|
177
|
-
def current_sub_navigation
|
|
178
|
-
module_sub_navigation(module_main_navigation(current_alchemy_module))
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
# Returns navigation entries from given module.
|
|
182
|
-
#
|
|
183
|
-
def module_main_navigation(alchemy_module)
|
|
184
|
-
alchemy_module.fetch('navigation', {}).stringify_keys
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
# Returns sub navigation entries from given module.
|
|
188
|
-
#
|
|
189
|
-
def module_sub_navigation(alchemy_module)
|
|
190
|
-
alchemy_module.fetch('sub_navigation', []).map(&:stringify_keys)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Returns nested navigation entries for given module.
|
|
194
|
-
#
|
|
195
|
-
def module_nested_navigation(alchemy_module)
|
|
196
|
-
alchemy_module.fetch('nested', []).map(&:stringify_keys)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
161
|
# Returns true if the current controller and action is in a modules navigation definition.
|
|
200
162
|
#
|
|
201
|
-
def admin_mainnavi_active?(
|
|
202
|
-
main_navigation.stringify_keys!
|
|
163
|
+
def admin_mainnavi_active?(navigation)
|
|
203
164
|
# Has the given navigation entry a active sub navigation?
|
|
204
|
-
has_active_entry?(
|
|
165
|
+
has_active_entry?(navigation['sub_navigation'] || []) ||
|
|
205
166
|
# Has the given navigation entry a active nested navigation?
|
|
206
|
-
has_active_entry?(
|
|
167
|
+
has_active_entry?(navigation['nested'] || []) ||
|
|
207
168
|
# Is the navigation entry active?
|
|
208
|
-
entry_active?(
|
|
169
|
+
entry_active?(navigation || {})
|
|
209
170
|
end
|
|
210
171
|
|
|
211
172
|
# Returns true if the given entry's controller is current controller
|
|
@@ -219,7 +180,8 @@ module Alchemy
|
|
|
219
180
|
# Also checks if given entry has a +nested_actions+ key, if so it checks if one of them is current controller's action
|
|
220
181
|
#
|
|
221
182
|
def is_entry_action_active?(entry)
|
|
222
|
-
entry['action'] == params[:action] ||
|
|
183
|
+
entry['action'] == params[:action] ||
|
|
184
|
+
entry.fetch('nested_actions', []).include?(params[:action])
|
|
223
185
|
end
|
|
224
186
|
|
|
225
187
|
# Returns true if an entry of given entries is active.
|
|
@@ -228,7 +190,7 @@ module Alchemy
|
|
|
228
190
|
# Alchemy module navigation entries.
|
|
229
191
|
#
|
|
230
192
|
def has_active_entry?(entries)
|
|
231
|
-
|
|
193
|
+
entries.any? { |entry| entry_active?(entry) }
|
|
232
194
|
end
|
|
233
195
|
end
|
|
234
196
|
end
|