alchemy_cms 3.4.2 → 3.5.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|