alchemy_cms 4.5.0 → 5.0.0.rc1
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 +56 -18
- data/.github/workflows/stale.yml +1 -1
- data/.gitignore +20 -2
- data/.hound.yml +2 -1
- data/.prettierrc +6 -0
- data/.rubocop.yml +33 -20
- data/CHANGELOG.md +117 -0
- data/Gemfile +24 -22
- data/README.md +32 -20
- data/Rakefile +11 -8
- data/alchemy_cms.gemspec +6 -5
- data/app/assets/javascripts/alchemy/admin.js +1 -5
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +2 -1
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -2
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +5 -5
- data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +17 -17
- data/app/assets/javascripts/alchemy/node_select.js +39 -0
- data/app/assets/javascripts/alchemy/templates/index.js +1 -0
- data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
- data/app/assets/javascripts/alchemy/templates/page.hbs +1 -1
- data/app/assets/stylesheets/alchemy/_mixins.scss +2 -3
- data/app/assets/stylesheets/alchemy/_variables.scss +2 -2
- data/app/assets/stylesheets/alchemy/admin.scss +3 -2
- data/app/assets/stylesheets/alchemy/base.scss +0 -1
- data/app/assets/stylesheets/alchemy/elements.scss +1 -1
- data/app/assets/stylesheets/alchemy/forms.scss +5 -0
- data/app/assets/stylesheets/alchemy/lists.scss +0 -8
- data/app/assets/stylesheets/alchemy/node-select.scss +43 -0
- data/app/assets/stylesheets/alchemy/nodes.scss +2 -2
- data/app/assets/stylesheets/alchemy/sitemap.scss +63 -21
- data/app/assets/stylesheets/alchemy/tables.scss +1 -24
- data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
- data/app/controllers/alchemy/admin/base_controller.rb +13 -33
- data/app/controllers/alchemy/admin/clipboard_controller.rb +5 -4
- data/app/controllers/alchemy/admin/contents_controller.rb +1 -2
- data/app/controllers/alchemy/admin/dashboard_controller.rb +10 -9
- data/app/controllers/alchemy/admin/elements_controller.rb +20 -20
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +12 -14
- data/app/controllers/alchemy/admin/languages_controller.rb +35 -2
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -2
- data/app/controllers/alchemy/admin/nodes_controller.rb +5 -4
- data/app/controllers/alchemy/admin/pages_controller.rb +50 -63
- data/app/controllers/alchemy/admin/pictures_controller.rb +16 -16
- data/app/controllers/alchemy/admin/resources_controller.rb +21 -13
- data/app/controllers/alchemy/admin/sites_controller.rb +18 -0
- data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
- data/app/controllers/alchemy/admin/tags_controller.rb +5 -3
- data/app/controllers/alchemy/admin/trash_controller.rb +6 -6
- data/app/controllers/alchemy/api/base_controller.rb +2 -2
- data/app/controllers/alchemy/api/contents_controller.rb +4 -4
- data/app/controllers/alchemy/api/elements_controller.rb +8 -8
- data/app/controllers/alchemy/api/nodes_controller.rb +37 -1
- data/app/controllers/alchemy/api/pages_controller.rb +15 -22
- data/app/controllers/alchemy/attachments_controller.rb +5 -5
- data/app/controllers/alchemy/base_controller.rb +10 -9
- data/app/controllers/alchemy/messages_controller.rb +16 -23
- data/app/controllers/alchemy/pages_controller.rb +13 -11
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +3 -2
- data/app/controllers/concerns/alchemy/admin/current_language.rb +23 -0
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -5
- data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +4 -4
- data/app/controllers/concerns/alchemy/page_redirects.rb +2 -9
- data/app/controllers/concerns/alchemy/site_redirects.rb +2 -2
- data/app/decorators/alchemy/content_editor.rb +55 -0
- data/app/decorators/alchemy/element_editor.rb +39 -0
- data/app/helpers/alchemy/admin/attachments_helper.rb +6 -6
- data/app/helpers/alchemy/admin/base_helper.rb +36 -35
- data/app/helpers/alchemy/admin/contents_helper.rb +3 -3
- data/app/helpers/alchemy/admin/elements_helper.rb +3 -88
- data/app/helpers/alchemy/admin/essences_helper.rb +8 -117
- data/app/helpers/alchemy/admin/form_helper.rb +1 -1
- data/app/helpers/alchemy/admin/navigation_helper.rb +24 -23
- data/app/helpers/alchemy/admin/pages_helper.rb +12 -12
- data/app/helpers/alchemy/admin/pictures_helper.rb +4 -6
- data/app/helpers/alchemy/admin/tags_helper.rb +8 -7
- data/app/helpers/alchemy/base_helper.rb +13 -8
- data/app/helpers/alchemy/elements_block_helper.rb +2 -31
- data/app/helpers/alchemy/elements_helper.rb +12 -58
- data/app/helpers/alchemy/pages_helper.rb +24 -174
- data/app/helpers/alchemy/url_helper.rb +2 -1
- data/app/mailers/alchemy/base_mailer.rb +1 -1
- data/app/mailers/alchemy/messages_mailer.rb +1 -1
- data/app/models/alchemy/attachment.rb +20 -18
- data/app/models/alchemy/base_record.rb +2 -5
- data/app/models/alchemy/content.rb +33 -52
- data/app/models/alchemy/content/factory.rb +24 -31
- data/app/models/alchemy/element.rb +45 -53
- data/app/models/alchemy/element/definitions.rb +4 -4
- data/app/models/alchemy/element/element_contents.rb +9 -6
- data/app/models/alchemy/element/element_essences.rb +4 -3
- data/app/models/alchemy/element/presenters.rb +3 -2
- data/app/models/alchemy/element_to_page.rb +1 -1
- data/app/models/alchemy/essence_boolean.rb +1 -3
- data/app/models/alchemy/essence_date.rb +2 -3
- data/app/models/alchemy/essence_file.rb +4 -4
- data/app/models/alchemy/essence_html.rb +1 -3
- data/app/models/alchemy/essence_link.rb +1 -3
- data/app/models/alchemy/essence_node.rb +18 -0
- data/app/models/alchemy/essence_page.rb +3 -16
- data/app/models/alchemy/essence_picture.rb +17 -16
- data/app/models/alchemy/essence_picture_view.rb +7 -6
- data/app/models/alchemy/essence_richtext.rb +1 -3
- data/app/models/alchemy/essence_select.rb +1 -3
- data/app/models/alchemy/essence_text.rb +0 -2
- data/app/models/alchemy/folded_page.rb +1 -0
- data/app/models/alchemy/language.rb +21 -35
- data/app/models/alchemy/language/code.rb +4 -4
- data/app/models/alchemy/legacy_page_url.rb +1 -1
- data/app/models/alchemy/message.rb +3 -3
- data/app/models/alchemy/node.rb +34 -10
- data/app/models/alchemy/page.rb +53 -123
- data/app/models/alchemy/page/fixed_attributes.rb +3 -2
- data/app/models/alchemy/page/page_elements.rb +35 -44
- data/app/models/alchemy/page/page_naming.rb +20 -70
- data/app/models/alchemy/page/page_natures.rb +7 -34
- data/app/models/alchemy/page/page_scopes.rb +23 -29
- data/app/models/alchemy/page/url_path.rb +64 -0
- data/app/models/alchemy/picture.rb +40 -30
- data/app/models/alchemy/picture/preprocessor.rb +26 -0
- data/app/models/alchemy/picture/transformations.rb +9 -7
- data/app/models/alchemy/picture/url.rb +5 -5
- data/app/models/alchemy/site.rb +6 -36
- data/app/models/alchemy/site/layout.rb +2 -2
- data/app/models/concerns/alchemy/touch_elements.rb +24 -0
- data/app/serializers/alchemy/content_serializer.rb +0 -3
- data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
- data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
- data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
- data/app/serializers/alchemy/node_serializer.rb +2 -0
- data/app/serializers/alchemy/page_serializer.rb +2 -1
- data/app/serializers/alchemy/page_tree_serializer.rb +11 -14
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
- data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
- data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
- data/app/views/alchemy/admin/contents/create.js.erb +1 -3
- data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
- data/app/views/alchemy/admin/elements/create.js.erb +1 -1
- data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
- data/app/views/alchemy/admin/elements/index.html.erb +3 -3
- data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
- data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
- data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
- data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
- data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
- data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
- data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
- data/app/views/alchemy/admin/languages/index.html.erb +23 -4
- data/app/views/alchemy/admin/languages/new.html.erb +1 -0
- data/app/views/alchemy/admin/layoutpages/index.html.erb +6 -2
- data/app/views/alchemy/admin/nodes/_form.html.erb +20 -17
- data/app/views/alchemy/admin/nodes/_node.html.erb +1 -5
- data/app/views/alchemy/admin/nodes/index.html.erb +3 -4
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
- data/app/views/alchemy/admin/pages/_form.html.erb +1 -2
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
- data/app/views/alchemy/admin/pages/_page.html.erb +14 -25
- data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +6 -0
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/info.html.erb +0 -9
- data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
- data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
- data/app/views/alchemy/admin/pictures/index.html.erb +18 -3
- data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
- data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
- data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
- data/app/views/alchemy/admin/sites/index.html.erb +21 -9
- data/app/views/alchemy/admin/sites/new.html.erb +1 -0
- data/app/views/alchemy/admin/tags/index.html.erb +2 -2
- data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
- data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
- data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
- data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
- data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
- data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
- data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
- data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
- data/app/views/alchemy/pages/show.rss.builder +3 -2
- data/app/views/layouts/alchemy/admin.html.erb +1 -0
- data/babel.config.js +12 -0
- data/bin/rails +5 -4
- data/config/alchemy/config.yml +23 -22
- data/config/brakeman.ignore +1 -1
- data/config/initializers/assets.rb +2 -1
- data/config/initializers/dragonfly.rb +2 -1
- data/config/initializers/mime_types.rb +1 -0
- data/config/initializers/mini_profiler.rb +3 -2
- data/config/initializers/simple_form.rb +6 -6
- data/config/locales/alchemy.en.yml +29 -14
- data/config/routes.rb +25 -24
- data/config/spring.rb +3 -2
- data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
- data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
- data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
- data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
- data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
- data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
- data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
- data/lib/alchemy/admin/locale.rb +3 -1
- data/lib/alchemy/admin/preview_url.rb +85 -0
- data/lib/alchemy/auth_accessors.rb +8 -7
- data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
- data/lib/alchemy/config.rb +28 -2
- data/lib/alchemy/configuration_methods.rb +3 -1
- data/lib/alchemy/controller_actions.rb +6 -5
- data/lib/alchemy/deprecation.rb +2 -1
- data/lib/alchemy/elements_finder.rb +5 -5
- data/lib/alchemy/engine.rb +23 -8
- data/lib/alchemy/errors.rb +0 -7
- data/lib/alchemy/essence.rb +17 -16
- data/lib/alchemy/filetypes.rb +5 -5
- data/lib/alchemy/forms/builder.rb +4 -4
- data/lib/alchemy/hints.rb +1 -1
- data/lib/alchemy/i18n.rb +2 -1
- data/lib/alchemy/install/tasks.rb +41 -0
- data/lib/alchemy/modules.rb +12 -12
- data/lib/alchemy/name_conversions.rb +5 -5
- data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
- data/lib/alchemy/page_layout.rb +15 -12
- data/lib/alchemy/paths.rb +1 -1
- data/lib/alchemy/permissions.rb +7 -6
- data/lib/alchemy/resource.rb +23 -13
- data/lib/alchemy/resources_helper.rb +12 -18
- data/lib/alchemy/routing_constraints.rb +1 -1
- data/lib/alchemy/seeder.rb +42 -14
- data/lib/alchemy/shell.rb +13 -10
- data/lib/alchemy/taggable.rb +1 -0
- data/lib/alchemy/tasks/tidy.rb +4 -3
- data/lib/alchemy/test_support/config_stubbing.rb +1 -0
- data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
- data/lib/alchemy/test_support/factories.rb +1 -1
- data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
- data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
- data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
- data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
- data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
- data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
- data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
- data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
- data/lib/alchemy/test_support/factories/language_factory.rb +21 -14
- data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
- data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
- data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
- data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
- data/lib/alchemy/test_support/integration_helpers.rb +1 -0
- data/lib/alchemy/test_support/shared_contexts.rb +5 -4
- data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
- data/lib/alchemy/tinymce.rb +15 -13
- data/lib/alchemy/upgrader.rb +8 -7
- data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
- data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
- data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +52 -50
- data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
- data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
- data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
- data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
- data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
- data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
- data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
- data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
- data/lib/generators/alchemy/install/install_generator.rb +169 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/menus.yml.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +2 -2
- data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
- data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
- data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
- data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
- data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +1 -1
- data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +1 -1
- data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
- data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
- data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
- data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
- data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
- data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
- data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
- data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
- data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
- data/lib/tasks/alchemy/db.rake +3 -19
- data/lib/tasks/alchemy/install.rake +5 -48
- data/lib/tasks/alchemy/tidy.rake +9 -8
- data/lib/tasks/alchemy/upgrade.rake +28 -105
- data/package.json +45 -0
- data/package/admin.js +14 -0
- data/package/src/__tests__/i18n.spec.js +70 -0
- data/package/src/i18n.js +48 -0
- data/package/src/node_tree.js +72 -0
- data/package/src/translations.js +32 -0
- data/package/src/utils/__tests__/ajax.spec.js +124 -0
- data/package/src/utils/__tests__/events.spec.js +38 -0
- data/package/src/utils/ajax.js +48 -0
- data/package/src/utils/events.js +16 -0
- data/vendor/assets/fonts/fa-regular-400.eot +0 -0
- data/vendor/assets/fonts/fa-regular-400.svg +798 -358
- data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
- data/vendor/assets/fonts/fa-solid-900.eot +0 -0
- data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
- data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
- data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
- data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
- data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
- data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
- data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
- data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
- data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
- data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
- data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
- data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
- metadata +115 -87
- data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
- data/app/assets/javascripts/alchemy/alchemy.node_tree.js +0 -66
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
- data/app/assets/javascripts/alchemy/alchemy.utils.js +0 -45
- data/app/helpers/alchemy/essences_helper.rb +0 -119
- data/app/models/concerns/alchemy/content_touching.rb +0 -23
- data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
- data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
- data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -33
- data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
- data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
- data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
- data/app/views/alchemy/navigation/_link.html.erb +0 -19
- data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
- data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
- data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
- data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
- data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
- data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
- data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
- data/lib/alchemy/ssl_protection.rb +0 -32
- data/lib/alchemy/tasks/helpers.rb +0 -81
- data/lib/alchemy/test_support/controller_requests.rb +0 -93
- data/lib/alchemy/upgrader/four_point_four.rb +0 -52
- data/lib/alchemy/upgrader/four_point_one.rb +0 -42
- data/lib/alchemy/upgrader/four_point_two.rb +0 -85
- data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -43
- data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -148
- data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -28
- data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
- data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
- data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
- data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
- data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
- data/lib/tasks/alchemy/convert.rake +0 -95
- data/vendor/assets/javascripts/sortable/Sortable.min.js +0 -2
- data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
- data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -15,7 +15,6 @@ module Alchemy
|
|
15
15
|
# fixed_attributes:
|
16
16
|
# - public_on: nil
|
17
17
|
# - public_until: nil
|
18
|
-
# - visible: false
|
19
18
|
#
|
20
19
|
class Page::FixedAttributes
|
21
20
|
attr_reader :page
|
@@ -31,7 +30,7 @@ module Alchemy
|
|
31
30
|
# @return Hash
|
32
31
|
#
|
33
32
|
def attributes
|
34
|
-
@_attributes ||= page.definition.fetch(
|
33
|
+
@_attributes ||= page.definition.fetch("fixed_attributes", {}).symbolize_keys
|
35
34
|
end
|
36
35
|
alias_method :all, :attributes
|
37
36
|
|
@@ -52,6 +51,7 @@ module Alchemy
|
|
52
51
|
#
|
53
52
|
def fixed?(name)
|
54
53
|
return false if name.nil?
|
54
|
+
|
55
55
|
attributes.key?(name.to_sym)
|
56
56
|
end
|
57
57
|
|
@@ -59,6 +59,7 @@ module Alchemy
|
|
59
59
|
#
|
60
60
|
def [](name)
|
61
61
|
return nil if name.nil?
|
62
|
+
|
62
63
|
attributes[name.to_sym]
|
63
64
|
end
|
64
65
|
end
|
@@ -9,37 +9,37 @@ module Alchemy
|
|
9
9
|
|
10
10
|
has_many :all_elements,
|
11
11
|
-> { order(:position) },
|
12
|
-
class_name:
|
12
|
+
class_name: "Alchemy::Element",
|
13
13
|
inverse_of: :page
|
14
14
|
has_many :elements,
|
15
15
|
-> { order(:position).not_nested.unfixed.available },
|
16
|
-
class_name:
|
16
|
+
class_name: "Alchemy::Element",
|
17
17
|
inverse_of: :page
|
18
18
|
has_many :trashed_elements,
|
19
19
|
-> { Element.trashed.order(:position) },
|
20
|
-
class_name:
|
20
|
+
class_name: "Alchemy::Element",
|
21
21
|
inverse_of: :page
|
22
22
|
has_many :fixed_elements,
|
23
23
|
-> { order(:position).fixed.available },
|
24
|
-
class_name:
|
24
|
+
class_name: "Alchemy::Element",
|
25
25
|
inverse_of: :page
|
26
26
|
has_many :dependent_destroyable_elements,
|
27
27
|
-> { not_nested },
|
28
|
-
class_name:
|
28
|
+
class_name: "Alchemy::Element",
|
29
29
|
dependent: :destroy
|
30
30
|
has_many :contents, through: :elements
|
31
31
|
has_and_belongs_to_many :to_be_swept_elements, -> { distinct },
|
32
|
-
class_name:
|
32
|
+
class_name: "Alchemy::Element",
|
33
33
|
join_table: ElementToPage.table_name
|
34
34
|
|
35
35
|
after_create :generate_elements,
|
36
|
-
unless: -> {
|
36
|
+
unless: -> { autogenerate_elements == false }
|
37
37
|
|
38
38
|
after_update :trash_not_allowed_elements!,
|
39
|
-
if: :
|
39
|
+
if: :saved_change_to_page_layout?
|
40
40
|
|
41
41
|
after_update :generate_elements,
|
42
|
-
if: :
|
42
|
+
if: :saved_change_to_page_layout?
|
43
43
|
end
|
44
44
|
|
45
45
|
module ClassMethods
|
@@ -53,7 +53,7 @@ module Alchemy
|
|
53
53
|
source_elements = source.all_elements.not_nested.not_trashed
|
54
54
|
source_elements.order(:position).map do |source_element|
|
55
55
|
Element.copy(source_element, {
|
56
|
-
page_id: target.id
|
56
|
+
page_id: target.id,
|
57
57
|
}).tap(&:move_to_bottom)
|
58
58
|
end
|
59
59
|
end
|
@@ -81,11 +81,11 @@ module Alchemy
|
|
81
81
|
#
|
82
82
|
def available_element_definitions(only_element_named = nil)
|
83
83
|
@_element_definitions ||= if only_element_named
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
84
|
+
definition = Element.definition_by_name(only_element_named)
|
85
|
+
element_definitions_by_name(definition["nestable_elements"])
|
86
|
+
else
|
87
|
+
element_definitions
|
88
|
+
end
|
89
89
|
|
90
90
|
return [] if @_element_definitions.blank?
|
91
91
|
|
@@ -100,20 +100,20 @@ module Alchemy
|
|
100
100
|
# All names of elements that can actually be placed on current page.
|
101
101
|
#
|
102
102
|
def available_element_names
|
103
|
-
@_available_element_names ||= available_element_definitions.map { |e| e[
|
103
|
+
@_available_element_names ||= available_element_definitions.map { |e| e["name"] }
|
104
104
|
end
|
105
105
|
|
106
106
|
# Available element definitions excluding nested unique elements.
|
107
107
|
#
|
108
108
|
def available_elements_within_current_scope(parent)
|
109
109
|
@_available_elements = if parent
|
110
|
-
|
111
|
-
|
112
|
-
|
110
|
+
parents_unique_nested_elements = parent.nested_elements.where(unique: true).pluck(:name)
|
111
|
+
available_element_definitions(parent.name).reject do |e|
|
112
|
+
parents_unique_nested_elements.include? e["name"]
|
113
|
+
end
|
114
|
+
else
|
115
|
+
available_element_definitions
|
113
116
|
end
|
114
|
-
else
|
115
|
-
available_element_definitions
|
116
|
-
end
|
117
117
|
end
|
118
118
|
|
119
119
|
# All element definitions defined for page's page layout
|
@@ -129,10 +129,10 @@ module Alchemy
|
|
129
129
|
#
|
130
130
|
def descendent_element_definitions
|
131
131
|
definitions = element_definitions_by_name(element_definition_names)
|
132
|
-
definitions.select { |d| d.key?(
|
133
|
-
definitions += element_definitions_by_name(d[
|
132
|
+
definitions.select { |d| d.key?("nestable_elements") }.each do |d|
|
133
|
+
definitions += element_definitions_by_name(d["nestable_elements"])
|
134
134
|
end
|
135
|
-
definitions.uniq { |d| d[
|
135
|
+
definitions.uniq { |d| d["name"] }
|
136
136
|
end
|
137
137
|
|
138
138
|
# All names of elements that are defined in the page definition.
|
@@ -145,10 +145,8 @@ module Alchemy
|
|
145
145
|
# elements: [headline, contactform]
|
146
146
|
#
|
147
147
|
def element_definition_names
|
148
|
-
definition[
|
148
|
+
definition["elements"] || []
|
149
149
|
end
|
150
|
-
alias_method :element_names_from_definition, :element_definition_names
|
151
|
-
deprecate element_names_from_definition: :element_definition_names, deprecator: Alchemy::Deprecation
|
152
150
|
|
153
151
|
# Element definitions with given name(s)
|
154
152
|
#
|
@@ -163,7 +161,7 @@ module Alchemy
|
|
163
161
|
if names.to_s == "all"
|
164
162
|
Element.definitions
|
165
163
|
else
|
166
|
-
Element.definitions.select { |e| names.include? e[
|
164
|
+
Element.definitions.select { |e| names.include? e["name"] }
|
167
165
|
end
|
168
166
|
end
|
169
167
|
|
@@ -176,14 +174,14 @@ module Alchemy
|
|
176
174
|
# feed_elements: [element_name, element_2_name]
|
177
175
|
#
|
178
176
|
def feed_elements
|
179
|
-
elements.named(definition[
|
177
|
+
elements.named(definition["feed_elements"])
|
180
178
|
end
|
181
179
|
|
182
180
|
# Returns an array of all EssenceRichtext contents ids from not folded elements
|
183
181
|
#
|
184
182
|
def richtext_contents_ids
|
185
183
|
Alchemy::Content.joins(:element)
|
186
|
-
.where(Element.table_name => {page_id: id, folded: false})
|
184
|
+
.where(Element.table_name => { page_id: id, folded: false })
|
187
185
|
.select(&:has_tinymce?)
|
188
186
|
.collect(&:id)
|
189
187
|
end
|
@@ -197,8 +195,9 @@ module Alchemy
|
|
197
195
|
def generate_elements
|
198
196
|
existing_elements = all_elements.not_nested.not_trashed
|
199
197
|
existing_element_names = existing_elements.pluck(:name).uniq
|
200
|
-
definition.fetch(
|
198
|
+
definition.fetch("autogenerate", []).each do |element_name|
|
201
199
|
next if existing_element_names.include?(element_name)
|
200
|
+
|
202
201
|
Element.create(page: self, name: element_name)
|
203
202
|
end
|
204
203
|
end
|
@@ -207,24 +206,16 @@ module Alchemy
|
|
207
206
|
def trash_not_allowed_elements!
|
208
207
|
not_allowed_elements = elements.where([
|
209
208
|
"#{Element.table_name}.name NOT IN (?)",
|
210
|
-
element_definition_names
|
209
|
+
element_definition_names,
|
211
210
|
])
|
212
211
|
not_allowed_elements.to_a.map(&:trash!)
|
213
212
|
end
|
214
213
|
|
215
|
-
def has_page_layout_changed?
|
216
|
-
if active_record_5_1?
|
217
|
-
saved_change_to_page_layout?
|
218
|
-
else
|
219
|
-
page_layout_changed?
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
214
|
# Deletes unique and already present definitions from @_element_definitions.
|
224
215
|
#
|
225
216
|
def delete_unique_element_definitions!
|
226
217
|
@_element_definitions.delete_if do |element|
|
227
|
-
element[
|
218
|
+
element["unique"] && @_existing_element_names.include?(element["name"])
|
228
219
|
end
|
229
220
|
end
|
230
221
|
|
@@ -232,8 +223,8 @@ module Alchemy
|
|
232
223
|
#
|
233
224
|
def delete_outnumbered_element_definitions!
|
234
225
|
@_element_definitions.delete_if do |element|
|
235
|
-
outnumbered = @_existing_element_names.select { |name| name == element[
|
236
|
-
element[
|
226
|
+
outnumbered = @_existing_element_names.select { |name| name == element["name"] }
|
227
|
+
element["amount"] && outnumbered.count >= element["amount"].to_i
|
237
228
|
end
|
238
229
|
end
|
239
230
|
end
|
@@ -9,29 +9,22 @@ module Alchemy
|
|
9
9
|
included do
|
10
10
|
before_validation :set_urlname,
|
11
11
|
if: :renamed?,
|
12
|
-
unless: -> {
|
12
|
+
unless: -> { name.blank? }
|
13
13
|
|
14
14
|
validates :name,
|
15
15
|
presence: true
|
16
16
|
validates :urlname,
|
17
|
-
uniqueness: {scope: [:language_id, :layoutpage], if: -> { urlname.present? }},
|
18
|
-
exclusion:
|
19
|
-
length:
|
20
|
-
format: {with: /\A[:\.\w\-+_\/\?&%;=]*\z/, if: -> { definition['redirects_to_external'] }}
|
21
|
-
validates :urlname,
|
22
|
-
on: :update,
|
23
|
-
presence: {if: -> { definition['redirects_to_external'] }}
|
17
|
+
uniqueness: { scope: [:language_id, :layoutpage], if: -> { urlname.present? } },
|
18
|
+
exclusion: { in: RESERVED_URLNAMES },
|
19
|
+
length: { minimum: 3, if: -> { urlname.present? } }
|
24
20
|
|
25
21
|
before_save :set_title,
|
26
|
-
unless: -> { systempage? || definition['redirects_to_external'] },
|
27
22
|
if: -> { title.blank? }
|
28
23
|
|
29
24
|
after_update :update_descendants_urlnames,
|
30
|
-
if: :
|
25
|
+
if: :saved_change_to_urlname?
|
31
26
|
|
32
|
-
after_move :update_urlname
|
33
|
-
if: -> { Config.get(:url_nesting) },
|
34
|
-
unless: -> { definition['redirects_to_external'] }
|
27
|
+
after_move :update_urlname!
|
35
28
|
end
|
36
29
|
|
37
30
|
# Returns true if name or urlname has changed.
|
@@ -42,7 +35,7 @@ module Alchemy
|
|
42
35
|
# Makes a slug of all ancestors urlnames including mine and delimit them be slash.
|
43
36
|
# So the whole path is stored as urlname in the database.
|
44
37
|
def update_urlname!
|
45
|
-
new_urlname = nested_url_name
|
38
|
+
new_urlname = nested_url_name
|
46
39
|
if urlname != new_urlname
|
47
40
|
legacy_urls.create(urlname: urlname)
|
48
41
|
update_column(:urlname, new_urlname)
|
@@ -51,56 +44,21 @@ module Alchemy
|
|
51
44
|
|
52
45
|
# Returns always the last part of a urlname path
|
53
46
|
def slug
|
54
|
-
urlname.to_s.split(
|
55
|
-
end
|
56
|
-
|
57
|
-
# Returns an urlname prefixed with http://, if no protocol is given
|
58
|
-
def external_urlname
|
59
|
-
return urlname if urlname =~ /\A(\/|[a-z]+:\/\/)/
|
60
|
-
"http://#{urlname}"
|
61
|
-
end
|
62
|
-
|
63
|
-
# Returns an array of visible/non-language_root ancestors.
|
64
|
-
def visible_ancestors
|
65
|
-
return [] unless parent
|
66
|
-
if new_record?
|
67
|
-
parent.visible_ancestors.tap do |base|
|
68
|
-
base.push(parent) if parent.visible?
|
69
|
-
end
|
70
|
-
else
|
71
|
-
ancestors.visible.contentpages.where(language_root: nil).to_a
|
72
|
-
end
|
47
|
+
urlname.to_s.split("/").last
|
73
48
|
end
|
74
49
|
|
75
50
|
private
|
76
51
|
|
77
|
-
def should_update_descendants_urlnames?
|
78
|
-
return false if !Config.get(:url_nesting)
|
79
|
-
if active_record_5_1?
|
80
|
-
saved_change_to_urlname? || saved_change_to_visible?
|
81
|
-
else
|
82
|
-
urlname_changed? || visible_changed?
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
52
|
def update_descendants_urlnames
|
87
53
|
reload
|
88
|
-
descendants.each
|
89
|
-
next if descendant.definition['redirects_to_external']
|
90
|
-
descendant.update_urlname!
|
91
|
-
end
|
54
|
+
descendants.each(&:update_urlname!)
|
92
55
|
end
|
93
56
|
|
94
57
|
# Sets the urlname to a url friendly slug.
|
95
58
|
# Either from name, or if present, from urlname.
|
96
|
-
#
|
59
|
+
# The urlname contains the whole path including parent urlnames.
|
97
60
|
def set_urlname
|
98
|
-
|
99
|
-
value = slug
|
100
|
-
else
|
101
|
-
value = urlname
|
102
|
-
end
|
103
|
-
self[:urlname] = nested_url_name(value)
|
61
|
+
self[:urlname] = nested_url_name
|
104
62
|
end
|
105
63
|
|
106
64
|
def set_title
|
@@ -112,25 +70,17 @@ module Alchemy
|
|
112
70
|
# Names shorter than 3 will be filled up with dashes,
|
113
71
|
# so it does not collidate with the language code.
|
114
72
|
#
|
115
|
-
def
|
116
|
-
url_name = convert_to_urlname(
|
117
|
-
|
118
|
-
('-' * (3 - url_name.length)) + url_name
|
119
|
-
else
|
120
|
-
url_name
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def nested_url_name(value)
|
125
|
-
(ancestor_slugs << convert_url_name(value)).join('/')
|
73
|
+
def converted_url_name
|
74
|
+
url_name = convert_to_urlname(slug.blank? ? name : slug)
|
75
|
+
url_name.rjust(3, "-")
|
126
76
|
end
|
127
77
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
78
|
+
def nested_url_name
|
79
|
+
if parent&.language_root?
|
80
|
+
converted_url_name
|
81
|
+
else
|
82
|
+
[parent&.urlname, converted_url_name].compact.join("/")
|
83
|
+
end
|
134
84
|
end
|
135
85
|
end
|
136
86
|
end
|
@@ -14,20 +14,16 @@ module Alchemy
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def taggable?
|
17
|
-
definition[
|
17
|
+
definition["taggable"] == true
|
18
18
|
end
|
19
19
|
|
20
20
|
def rootpage?
|
21
21
|
!new_record? && parent_id.blank?
|
22
22
|
end
|
23
23
|
|
24
|
-
def systempage?
|
25
|
-
return true if Page.count.zero?
|
26
|
-
rootpage? || (parent_id == Page.root.id && !language_root?)
|
27
|
-
end
|
28
|
-
|
29
24
|
def folded?(user_id)
|
30
25
|
return unless Alchemy.user_class < ActiveRecord::Base
|
26
|
+
|
31
27
|
folded_pages.where(user_id: user_id, folded: true).any?
|
32
28
|
end
|
33
29
|
|
@@ -51,46 +47,22 @@ module Alchemy
|
|
51
47
|
|
52
48
|
def editor_roles
|
53
49
|
return unless has_limited_editors?
|
54
|
-
definition["editable_by"]
|
55
|
-
end
|
56
|
-
|
57
|
-
# Returns true or false if the pages definition for config/alchemy/page_layouts.yml contains redirects_to_external: true
|
58
|
-
# @deprecated Please use a menu node with an external url instead.
|
59
|
-
def redirects_to_external?
|
60
|
-
!!definition["redirects_to_external"]
|
61
|
-
end
|
62
|
-
deprecate redirects_to_external?: 'Please use a menu node with an external url instead.', deprecator: Alchemy::Deprecation
|
63
50
|
|
64
|
-
|
65
|
-
def has_controller?
|
66
|
-
!PageLayout.get(page_layout).nil? && !PageLayout.get(page_layout)["controller"].blank?
|
51
|
+
definition["editable_by"]
|
67
52
|
end
|
68
|
-
deprecate :has_controller?, deprecator: Alchemy::Deprecation
|
69
53
|
|
70
54
|
# True if page locked_at timestamp and locked_by id are set
|
71
55
|
def locked?
|
72
56
|
locked_by? && locked_at?
|
73
57
|
end
|
74
58
|
|
75
|
-
# @deprecated Please use a menu node with an url pointing to your controller path instead.
|
76
|
-
def controller_and_action
|
77
|
-
if definition['controller']
|
78
|
-
{
|
79
|
-
controller: definition["controller"].gsub(/(^\b)/, "/#{$1}"),
|
80
|
-
action: definition["action"]
|
81
|
-
}
|
82
|
-
end
|
83
|
-
end
|
84
|
-
deprecate controller_and_action: 'Please use a menu node with an url pointing to your controller path instead.', deprecator: Alchemy::Deprecation
|
85
|
-
|
86
59
|
# Returns a Hash describing the status of the Page.
|
87
60
|
#
|
88
61
|
def status
|
89
62
|
{
|
90
63
|
public: public?,
|
91
|
-
visible: visible?,
|
92
64
|
locked: locked?,
|
93
|
-
restricted: restricted
|
65
|
+
restricted: restricted?,
|
94
66
|
}
|
95
67
|
end
|
96
68
|
|
@@ -116,7 +88,7 @@ module Alchemy
|
|
116
88
|
# Page layout names are defined inside the config/alchemy/page_layouts.yml file.
|
117
89
|
# Translate the name in your config/locales language yml file.
|
118
90
|
def layout_display_name
|
119
|
-
Alchemy.t(page_layout, scope:
|
91
|
+
Alchemy.t(page_layout, scope: "page_layout_names")
|
120
92
|
end
|
121
93
|
|
122
94
|
# Returns the name for the layout partial
|
@@ -174,8 +146,9 @@ module Alchemy
|
|
174
146
|
#
|
175
147
|
def cache_page?
|
176
148
|
return false unless caching_enabled?
|
149
|
+
|
177
150
|
page_layout = PageLayout.get(self.page_layout)
|
178
|
-
page_layout[
|
151
|
+
page_layout["cache"] != false && page_layout["searchresults"] != true
|
179
152
|
end
|
180
153
|
|
181
154
|
private
|