alchemy_cms 4.6.7 → 5.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +33 -1
- data/.github/workflows/stale.yml +1 -1
- data/.gitignore +20 -2
- data/.hound.yml +2 -1
- data/.prettierrc +6 -0
- data/.rubocop.yml +31 -10
- data/CHANGELOG.md +89 -32
- data/Gemfile +24 -22
- data/README.md +31 -19
- data/Rakefile +10 -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.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/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/node-select.scss +43 -0
- data/app/assets/stylesheets/alchemy/nodes.scss +1 -1
- data/app/assets/stylesheets/alchemy/sitemap.scss +5 -1
- data/app/assets/stylesheets/alchemy/tables.scss +1 -24
- data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +3 -3
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +7 -7
- data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
- data/app/controllers/alchemy/admin/base_controller.rb +16 -42
- 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 -62
- 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 +14 -23
- 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/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 +4 -4
- data/app/helpers/alchemy/admin/pictures_helper.rb +3 -3
- 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 +21 -19
- data/app/models/alchemy/base_record.rb +2 -5
- data/app/models/alchemy/content/factory.rb +24 -31
- data/app/models/alchemy/content.rb +33 -38
- 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.rb +46 -54
- 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/code.rb +4 -4
- data/app/models/alchemy/language.rb +21 -35
- data/app/models/alchemy/legacy_page_url.rb +1 -1
- data/app/models/alchemy/message.rb +3 -3
- data/app/models/alchemy/node.rb +28 -5
- 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 +0 -2
- data/app/models/alchemy/page.rb +47 -128
- data/app/models/alchemy/picture/transformations.rb +9 -7
- data/app/models/alchemy/picture/url.rb +5 -5
- data/app/models/alchemy/picture.rb +19 -28
- data/app/models/alchemy/site/layout.rb +2 -2
- data/app/models/alchemy/site.rb +6 -36
- 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_tree_serializer.rb +9 -13
- 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 +3 -3
- data/app/views/alchemy/admin/nodes/_form.html.erb +18 -15
- 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 +0 -1
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
- data/app/views/alchemy/admin/pages/_page.html.erb +11 -19
- data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
- 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/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 +15 -18
- 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 +23 -8
- 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 +64 -0
- data/lib/alchemy/auth_accessors.rb +8 -7
- data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
- data/lib/alchemy/config.rb +1 -5
- 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 +22 -14
- 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/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 +25 -17
- 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/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 +16 -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/factories.rb +1 -1
- 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/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/upgrader.rb +8 -7
- data/lib/alchemy/userstamp.rb +1 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +52 -51
- 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 +110 -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 +3 -2
- data/lib/tasks/alchemy/tidy.rake +9 -8
- data/lib/tasks/alchemy/upgrade.rake +18 -120
- 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/package.json +45 -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 +117 -98
- 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 -37
- 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/error_tracking/airbrake_handler.rb +0 -13
- data/lib/alchemy/error_tracking.rb +0 -14
- data/lib/alchemy/ssl_protection.rb +0 -34
- 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_six.rb +0 -50
- data/lib/alchemy/upgrader/four_point_two.rb +0 -86
- data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -45
- data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -166
- data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -32
- data/lib/alchemy/upgrader/tasks/fixed_element_name_finder.rb +0 -31
- 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 -98
- 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
|
@@ -28,29 +28,25 @@ module Alchemy
|
|
|
28
28
|
belongs_to :element, touch: true, inverse_of: :contents
|
|
29
29
|
has_one :page, through: :element
|
|
30
30
|
|
|
31
|
-
stampable stamper_class_name: Alchemy.user_class.name
|
|
32
|
-
|
|
33
|
-
acts_as_list scope: [:element_id]
|
|
34
|
-
|
|
35
31
|
# Essence scopes
|
|
36
|
-
scope :essence_booleans,
|
|
37
|
-
scope :essence_dates,
|
|
38
|
-
scope :essence_files,
|
|
39
|
-
scope :essence_htmls,
|
|
40
|
-
scope :essence_links,
|
|
41
|
-
scope :essence_pictures,
|
|
32
|
+
scope :essence_booleans, -> { where(essence_type: "Alchemy::EssenceBoolean") }
|
|
33
|
+
scope :essence_dates, -> { where(essence_type: "Alchemy::EssenceDate") }
|
|
34
|
+
scope :essence_files, -> { where(essence_type: "Alchemy::EssenceFile") }
|
|
35
|
+
scope :essence_htmls, -> { where(essence_type: "Alchemy::EssenceHtml") }
|
|
36
|
+
scope :essence_links, -> { where(essence_type: "Alchemy::EssenceLink") }
|
|
37
|
+
scope :essence_pictures, -> { where(essence_type: "Alchemy::EssencePicture") }
|
|
42
38
|
scope :essence_richtexts, -> { where(essence_type: "Alchemy::EssenceRichtext") }
|
|
43
|
-
scope :essence_selects,
|
|
44
|
-
scope :essence_texts,
|
|
45
|
-
scope :named,
|
|
46
|
-
scope :available,
|
|
47
|
-
scope :published,
|
|
48
|
-
scope :not_trashed,
|
|
49
|
-
scope :not_restricted,
|
|
50
|
-
|
|
51
|
-
delegate :restricted?, to: :page,
|
|
52
|
-
delegate :trashed?,
|
|
53
|
-
delegate :public?,
|
|
39
|
+
scope :essence_selects, -> { where(essence_type: "Alchemy::EssenceSelect") }
|
|
40
|
+
scope :essence_texts, -> { where(essence_type: "Alchemy::EssenceText") }
|
|
41
|
+
scope :named, ->(name) { where(name: name) }
|
|
42
|
+
scope :available, -> { published.not_trashed }
|
|
43
|
+
scope :published, -> { joins(:element).merge(Element.published) }
|
|
44
|
+
scope :not_trashed, -> { joins(:element).merge(Element.not_trashed) }
|
|
45
|
+
scope :not_restricted, -> { joins(:element).merge(Element.not_restricted) }
|
|
46
|
+
|
|
47
|
+
delegate :restricted?, to: :page, allow_nil: true
|
|
48
|
+
delegate :trashed?, to: :element, allow_nil: true
|
|
49
|
+
delegate :public?, to: :element, allow_nil: true
|
|
54
50
|
|
|
55
51
|
class << self
|
|
56
52
|
# Returns the translated label for a content name.
|
|
@@ -72,7 +68,7 @@ module Alchemy
|
|
|
72
68
|
Alchemy.t(
|
|
73
69
|
content_name,
|
|
74
70
|
scope: "content_names.#{element_name}",
|
|
75
|
-
default: Alchemy.t("content_names.#{content_name}", default: content_name.humanize)
|
|
71
|
+
default: Alchemy.t("content_names.#{content_name}", default: content_name.humanize),
|
|
76
72
|
)
|
|
77
73
|
end
|
|
78
74
|
end
|
|
@@ -99,6 +95,7 @@ module Alchemy
|
|
|
99
95
|
# Settings from the elements.yml definition
|
|
100
96
|
def settings
|
|
101
97
|
return {} if definition.blank?
|
|
98
|
+
|
|
102
99
|
@settings ||= definition.fetch(:settings, {})
|
|
103
100
|
end
|
|
104
101
|
|
|
@@ -114,12 +111,14 @@ module Alchemy
|
|
|
114
111
|
|
|
115
112
|
def siblings
|
|
116
113
|
return [] if !element
|
|
114
|
+
|
|
117
115
|
element.contents
|
|
118
116
|
end
|
|
119
117
|
|
|
120
118
|
# Gets the ingredient from essence
|
|
121
119
|
def ingredient
|
|
122
120
|
return nil if essence.nil?
|
|
121
|
+
|
|
123
122
|
essence.ingredient
|
|
124
123
|
end
|
|
125
124
|
|
|
@@ -129,7 +128,7 @@ module Alchemy
|
|
|
129
128
|
{
|
|
130
129
|
name: name,
|
|
131
130
|
value: serialized_ingredient,
|
|
132
|
-
link: essence.try(:link)
|
|
131
|
+
link: essence.try(:link),
|
|
133
132
|
}.delete_if { |_k, v| v.blank? }
|
|
134
133
|
end
|
|
135
134
|
|
|
@@ -145,6 +144,7 @@ module Alchemy
|
|
|
145
144
|
# Sets the ingredient from essence
|
|
146
145
|
def ingredient=(value)
|
|
147
146
|
raise EssenceMissingError if essence.nil?
|
|
147
|
+
|
|
148
148
|
essence.ingredient = value
|
|
149
149
|
end
|
|
150
150
|
|
|
@@ -156,11 +156,12 @@ module Alchemy
|
|
|
156
156
|
#
|
|
157
157
|
def update_essence(params = {})
|
|
158
158
|
raise EssenceMissingError if essence.nil?
|
|
159
|
+
|
|
159
160
|
if essence.update(params)
|
|
160
|
-
|
|
161
|
+
true
|
|
161
162
|
else
|
|
162
163
|
errors.add(:essence, :validation_failed)
|
|
163
|
-
|
|
164
|
+
false
|
|
164
165
|
end
|
|
165
166
|
end
|
|
166
167
|
|
|
@@ -169,12 +170,13 @@ module Alchemy
|
|
|
169
170
|
end
|
|
170
171
|
|
|
171
172
|
def has_validations?
|
|
172
|
-
definition[
|
|
173
|
+
definition["validate"].present?
|
|
173
174
|
end
|
|
174
175
|
|
|
175
176
|
# Returns a string used as dom id on html elements.
|
|
176
177
|
def dom_id
|
|
177
|
-
return
|
|
178
|
+
return "" if essence.nil?
|
|
179
|
+
|
|
178
180
|
"#{essence_partial_name}_#{id}"
|
|
179
181
|
end
|
|
180
182
|
|
|
@@ -189,7 +191,7 @@ module Alchemy
|
|
|
189
191
|
|
|
190
192
|
# Returns true if this content should be taken for element preview.
|
|
191
193
|
def preview_content?
|
|
192
|
-
!!definition[
|
|
194
|
+
!!definition["as_element_title"]
|
|
193
195
|
end
|
|
194
196
|
|
|
195
197
|
# Proxy method that returns the preview text from essence.
|
|
@@ -199,7 +201,8 @@ module Alchemy
|
|
|
199
201
|
end
|
|
200
202
|
|
|
201
203
|
def essence_partial_name
|
|
202
|
-
return
|
|
204
|
+
return "" if essence.nil?
|
|
205
|
+
|
|
203
206
|
essence.partial_name
|
|
204
207
|
end
|
|
205
208
|
|
|
@@ -223,19 +226,11 @@ module Alchemy
|
|
|
223
226
|
"has_tinymce" + (has_custom_tinymce_config? ? " #{element.name}_#{name}" : "")
|
|
224
227
|
end
|
|
225
228
|
|
|
226
|
-
def editor
|
|
227
|
-
@_editor ||= ContentEditor.new(self)
|
|
228
|
-
end
|
|
229
|
-
delegate :form_field_name, to: :editor
|
|
230
|
-
deprecate form_field_name: "use Alchemy::ContentEditor#form_field_name instead", deprecator: Alchemy::Deprecation
|
|
231
|
-
delegate :form_field_id, to: :editor
|
|
232
|
-
deprecate form_field_id: "use Alchemy::ContentEditor#form_field_id instead", deprecator: Alchemy::Deprecation
|
|
233
|
-
|
|
234
229
|
# Returns the default value from content definition
|
|
235
230
|
#
|
|
236
231
|
# If the value is a symbol it gets passed through i18n
|
|
237
232
|
# inside the +alchemy.default_content_texts+ scope
|
|
238
|
-
def
|
|
233
|
+
def default_value(default = definition[:default])
|
|
239
234
|
case default
|
|
240
235
|
when Symbol
|
|
241
236
|
Alchemy.t(default, scope: :default_content_texts)
|
|
@@ -19,7 +19,7 @@ module Alchemy
|
|
|
19
19
|
# Returns one element definition by given name.
|
|
20
20
|
#
|
|
21
21
|
def definition_by_name(name)
|
|
22
|
-
definitions.detect { |d| d[
|
|
22
|
+
definitions.detect { |d| d["name"] == name }
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
private
|
|
@@ -30,21 +30,21 @@ module Alchemy
|
|
|
30
30
|
if ::File.exist?(definitions_file_path)
|
|
31
31
|
::YAML.safe_load(ERB.new(File.read(definitions_file_path)).result, YAML_WHITELIST_CLASSES, [], true) || []
|
|
32
32
|
else
|
|
33
|
-
raise LoadError, "Could not find elements.yml file! Please run `rails generate alchemy:
|
|
33
|
+
raise LoadError, "Could not find elements.yml file! Please run `rails generate alchemy:install`"
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# Returns the +elements.yml+ file path
|
|
38
38
|
#
|
|
39
39
|
def definitions_file_path
|
|
40
|
-
Rails.root.join
|
|
40
|
+
Rails.root.join "config/alchemy/elements.yml"
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# The definition of this element.
|
|
45
45
|
#
|
|
46
46
|
def definition
|
|
47
|
-
if definition = self.class.definitions.detect { |d| d[
|
|
47
|
+
if definition = self.class.definitions.detect { |d| d["name"] == name }
|
|
48
48
|
definition
|
|
49
49
|
else
|
|
50
50
|
log_warning "Could not find element definition for #{name}. Please check your elements.yml file!"
|
|
@@ -47,6 +47,7 @@ module Alchemy
|
|
|
47
47
|
#
|
|
48
48
|
def update_contents(contents_attributes)
|
|
49
49
|
return true if contents_attributes.nil?
|
|
50
|
+
|
|
50
51
|
contents.each do |content|
|
|
51
52
|
content_hash = contents_attributes[content.id.to_s] || next
|
|
52
53
|
content.update_essence(content_hash) || errors.add(:base, :essence_validation_failed)
|
|
@@ -72,7 +73,7 @@ module Alchemy
|
|
|
72
73
|
# rss_title: true
|
|
73
74
|
#
|
|
74
75
|
def content_for_rss_title
|
|
75
|
-
content_for_rss_meta(
|
|
76
|
+
content_for_rss_meta("title")
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
# Returns the content that is marked as rss description.
|
|
@@ -86,13 +87,14 @@ module Alchemy
|
|
|
86
87
|
# rss_description: true
|
|
87
88
|
#
|
|
88
89
|
def content_for_rss_description
|
|
89
|
-
content_for_rss_meta(
|
|
90
|
+
content_for_rss_meta("description")
|
|
90
91
|
end
|
|
91
92
|
|
|
92
93
|
# Returns the array with the hashes for all element contents in the elements.yml file
|
|
93
94
|
def content_definitions
|
|
94
95
|
return nil if definition.blank?
|
|
95
|
-
|
|
96
|
+
|
|
97
|
+
definition["contents"]
|
|
96
98
|
end
|
|
97
99
|
|
|
98
100
|
# Returns the definition for given content_name
|
|
@@ -101,7 +103,7 @@ module Alchemy
|
|
|
101
103
|
log_warning "Element #{name} is missing the content definition for #{content_name}"
|
|
102
104
|
nil
|
|
103
105
|
else
|
|
104
|
-
content_definitions.detect { |d| d[
|
|
106
|
+
content_definitions.detect { |d| d["name"] == content_name.to_s }
|
|
105
107
|
end
|
|
106
108
|
end
|
|
107
109
|
|
|
@@ -136,12 +138,13 @@ module Alchemy
|
|
|
136
138
|
def content_for_rss_meta(type)
|
|
137
139
|
definition = content_definitions.detect { |c| c["rss_#{type}"] }
|
|
138
140
|
return if definition.blank?
|
|
139
|
-
|
|
141
|
+
|
|
142
|
+
contents.detect { |content| content.name == definition["name"] }
|
|
140
143
|
end
|
|
141
144
|
|
|
142
145
|
# creates the contents for this element as described in the elements.yml
|
|
143
146
|
def create_contents
|
|
144
|
-
definition.fetch(
|
|
147
|
+
definition.fetch("contents", []).each do |attributes|
|
|
145
148
|
Content.create(attributes.merge(element: self))
|
|
146
149
|
end
|
|
147
150
|
end
|
|
@@ -6,6 +6,7 @@ module Alchemy
|
|
|
6
6
|
def ingredient(name)
|
|
7
7
|
content = content_by_name(name)
|
|
8
8
|
return nil if content.blank?
|
|
9
|
+
|
|
9
10
|
content.ingredient
|
|
10
11
|
end
|
|
11
12
|
|
|
@@ -96,12 +97,12 @@ module Alchemy
|
|
|
96
97
|
errors.each do |error|
|
|
97
98
|
messages << Alchemy.t(
|
|
98
99
|
"#{name}.#{content_name}.#{error}",
|
|
99
|
-
scope:
|
|
100
|
+
scope: "content_validations",
|
|
100
101
|
default: [
|
|
101
102
|
"fields.#{content_name}.#{error}".to_sym,
|
|
102
|
-
"errors.#{error}".to_sym
|
|
103
|
+
"errors.#{error}".to_sym,
|
|
103
104
|
],
|
|
104
|
-
field: Content.translated_label_for(content_name, name)
|
|
105
|
+
field: Content.translated_label_for(content_name, name),
|
|
105
106
|
)
|
|
106
107
|
end
|
|
107
108
|
end
|
|
@@ -23,7 +23,7 @@ module Alchemy
|
|
|
23
23
|
# If no translation is found a humanized name is used.
|
|
24
24
|
#
|
|
25
25
|
def display_name_for(name)
|
|
26
|
-
Alchemy.t(name, scope:
|
|
26
|
+
Alchemy.t(name, scope: "element_names", default: name.to_s.humanize)
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -32,7 +32,7 @@ module Alchemy
|
|
|
32
32
|
# @see Alchemy::Element::Presenters#display_name_for
|
|
33
33
|
#
|
|
34
34
|
def display_name
|
|
35
|
-
self.class.display_name_for(definition[
|
|
35
|
+
self.class.display_name_for(definition["name"] || name)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# Returns a preview text for element.
|
|
@@ -97,6 +97,7 @@ module Alchemy
|
|
|
97
97
|
|
|
98
98
|
def preview_text_from_nested_elements(maxlength)
|
|
99
99
|
return if all_nested_elements.empty?
|
|
100
|
+
|
|
100
101
|
all_nested_elements.first.preview_text(maxlength)
|
|
101
102
|
end
|
|
102
103
|
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
module Alchemy
|
|
24
24
|
class Element < BaseRecord
|
|
25
|
+
NAME_REGEXP = /\A[a-z0-9_-]+\z/
|
|
26
|
+
|
|
25
27
|
include Alchemy::Logger
|
|
26
28
|
include Alchemy::Taggable
|
|
27
29
|
include Alchemy::Hints
|
|
@@ -34,7 +36,7 @@ module Alchemy
|
|
|
34
36
|
"hint",
|
|
35
37
|
"taggable",
|
|
36
38
|
"compact",
|
|
37
|
-
"message"
|
|
39
|
+
"message",
|
|
38
40
|
].freeze
|
|
39
41
|
|
|
40
42
|
SKIPPED_ATTRIBUTES_ON_COPY = [
|
|
@@ -45,7 +47,7 @@ module Alchemy
|
|
|
45
47
|
"folded",
|
|
46
48
|
"position",
|
|
47
49
|
"updated_at",
|
|
48
|
-
"updater_id"
|
|
50
|
+
"updater_id",
|
|
49
51
|
].freeze
|
|
50
52
|
|
|
51
53
|
# All Elements that share the same page id and parent element id and are fixed or not are considered a list.
|
|
@@ -58,19 +60,19 @@ module Alchemy
|
|
|
58
60
|
#
|
|
59
61
|
acts_as_list scope: [:page_id, :fixed, :parent_element_id]
|
|
60
62
|
|
|
61
|
-
stampable stamper_class_name: Alchemy.
|
|
63
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
|
62
64
|
|
|
63
|
-
has_many :contents,
|
|
65
|
+
has_many :contents, dependent: :destroy, inverse_of: :element
|
|
64
66
|
|
|
65
67
|
has_many :all_nested_elements,
|
|
66
68
|
-> { order(:position).not_trashed },
|
|
67
|
-
class_name:
|
|
69
|
+
class_name: "Alchemy::Element",
|
|
68
70
|
foreign_key: :parent_element_id,
|
|
69
71
|
dependent: :destroy
|
|
70
72
|
|
|
71
73
|
has_many :nested_elements,
|
|
72
74
|
-> { order(:position).available },
|
|
73
|
-
class_name:
|
|
75
|
+
class_name: "Alchemy::Element",
|
|
74
76
|
foreign_key: :parent_element_id,
|
|
75
77
|
dependent: :destroy,
|
|
76
78
|
inverse_of: :parent_element
|
|
@@ -79,17 +81,17 @@ module Alchemy
|
|
|
79
81
|
|
|
80
82
|
# A nested element belongs to a parent element.
|
|
81
83
|
belongs_to :parent_element,
|
|
82
|
-
class_name:
|
|
84
|
+
class_name: "Alchemy::Element",
|
|
83
85
|
optional: true,
|
|
84
86
|
touch: true,
|
|
85
87
|
inverse_of: :nested_elements
|
|
86
88
|
|
|
87
89
|
has_and_belongs_to_many :touchable_pages, -> { distinct },
|
|
88
|
-
class_name:
|
|
90
|
+
class_name: "Alchemy::Page",
|
|
89
91
|
join_table: ElementToPage.table_name
|
|
90
92
|
|
|
91
93
|
validates_presence_of :name, on: :create
|
|
92
|
-
validates_format_of :name, on: :create, with:
|
|
94
|
+
validates_format_of :name, on: :create, with: NAME_REGEXP
|
|
93
95
|
|
|
94
96
|
attr_accessor :autogenerate_contents
|
|
95
97
|
attr_accessor :autogenerate_nested_elements
|
|
@@ -98,19 +100,19 @@ module Alchemy
|
|
|
98
100
|
|
|
99
101
|
after_update :touch_touchable_pages
|
|
100
102
|
|
|
101
|
-
scope :trashed,
|
|
102
|
-
scope :not_trashed,
|
|
103
|
-
scope :published,
|
|
104
|
-
scope :not_restricted,
|
|
105
|
-
scope :available,
|
|
106
|
-
scope :named,
|
|
107
|
-
scope :excluded,
|
|
108
|
-
scope :fixed,
|
|
109
|
-
scope :unfixed,
|
|
110
|
-
scope :from_current_site, -> { where(Language.table_name => {site_id: Site.current || Site.default}).joins(page:
|
|
111
|
-
scope :folded,
|
|
112
|
-
scope :expanded,
|
|
113
|
-
scope :not_nested,
|
|
103
|
+
scope :trashed, -> { where(position: nil).order("updated_at DESC") }
|
|
104
|
+
scope :not_trashed, -> { where.not(position: nil) }
|
|
105
|
+
scope :published, -> { where(public: true) }
|
|
106
|
+
scope :not_restricted, -> { joins(:page).merge(Page.not_restricted) }
|
|
107
|
+
scope :available, -> { published.not_trashed }
|
|
108
|
+
scope :named, ->(names) { where(name: names) }
|
|
109
|
+
scope :excluded, ->(names) { where.not(name: names) }
|
|
110
|
+
scope :fixed, -> { where(fixed: true) }
|
|
111
|
+
scope :unfixed, -> { where(fixed: false) }
|
|
112
|
+
scope :from_current_site, -> { where(Language.table_name => { site_id: Site.current || Site.default }).joins(page: "language") }
|
|
113
|
+
scope :folded, -> { where(folded: true) }
|
|
114
|
+
scope :expanded, -> { where(folded: false) }
|
|
115
|
+
scope :not_nested, -> { where(parent_element_id: nil) }
|
|
114
116
|
|
|
115
117
|
delegate :restricted?, to: :page, allow_nil: true
|
|
116
118
|
|
|
@@ -131,7 +133,8 @@ module Alchemy
|
|
|
131
133
|
#
|
|
132
134
|
def new(attributes = {})
|
|
133
135
|
return super if attributes[:name].blank?
|
|
134
|
-
|
|
136
|
+
|
|
137
|
+
element_attributes = attributes.to_h.merge(name: attributes[:name].split("#").first)
|
|
135
138
|
element_definition = Element.definition_by_name(element_attributes[:name])
|
|
136
139
|
if element_definition.nil?
|
|
137
140
|
raise(ElementDefinitionError, attributes)
|
|
@@ -139,11 +142,6 @@ module Alchemy
|
|
|
139
142
|
|
|
140
143
|
super(element_definition.merge(element_attributes).except(*FORBIDDEN_DEFINITION_ATTRIBUTES))
|
|
141
144
|
end
|
|
142
|
-
alias_method :new_from_scratch, :new
|
|
143
|
-
deprecate new_from_scratch: :new, deprecator: Alchemy::Deprecation
|
|
144
|
-
|
|
145
|
-
alias_method :create_from_scratch, :create
|
|
146
|
-
deprecate create_from_scratch: :create, deprecator: Alchemy::Deprecation
|
|
147
145
|
|
|
148
146
|
# This methods does a copy of source and all depending contents and all of their depending essences.
|
|
149
147
|
#
|
|
@@ -158,13 +156,13 @@ module Alchemy
|
|
|
158
156
|
#
|
|
159
157
|
def copy(source_element, differences = {})
|
|
160
158
|
attributes = source_element.attributes.with_indifferent_access
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
159
|
+
.except(*SKIPPED_ATTRIBUTES_ON_COPY)
|
|
160
|
+
.merge(differences)
|
|
161
|
+
.merge({
|
|
162
|
+
autogenerate_contents: false,
|
|
163
|
+
autogenerate_nested_elements: false,
|
|
164
|
+
tag_list: source_element.tag_list,
|
|
165
|
+
})
|
|
168
166
|
|
|
169
167
|
new_element = create!(attributes)
|
|
170
168
|
|
|
@@ -181,13 +179,15 @@ module Alchemy
|
|
|
181
179
|
|
|
182
180
|
def all_from_clipboard(clipboard)
|
|
183
181
|
return [] if clipboard.nil?
|
|
184
|
-
|
|
182
|
+
|
|
183
|
+
where(id: clipboard.collect { |e| e["id"] })
|
|
185
184
|
end
|
|
186
185
|
|
|
187
186
|
# All elements in clipboard that could be placed on page
|
|
188
187
|
#
|
|
189
188
|
def all_from_clipboard_for_page(clipboard, page)
|
|
190
189
|
return [] if clipboard.nil? || page.nil?
|
|
190
|
+
|
|
191
191
|
all_from_clipboard(clipboard).select { |ce|
|
|
192
192
|
page.available_element_names.include?(ce.name)
|
|
193
193
|
}
|
|
@@ -199,7 +199,7 @@ module Alchemy
|
|
|
199
199
|
# Pass an element name to get next of this kind.
|
|
200
200
|
#
|
|
201
201
|
def next(name = nil)
|
|
202
|
-
elements = page.elements.published.where(
|
|
202
|
+
elements = page.elements.published.where("position > ?", position)
|
|
203
203
|
select_element(elements, name, :asc)
|
|
204
204
|
end
|
|
205
205
|
|
|
@@ -208,13 +208,14 @@ module Alchemy
|
|
|
208
208
|
# Pass an element name to get previous of this kind.
|
|
209
209
|
#
|
|
210
210
|
def prev(name = nil)
|
|
211
|
-
elements = page.elements.published.where(
|
|
211
|
+
elements = page.elements.published.where("position < ?", position)
|
|
212
212
|
select_element(elements, name, :desc)
|
|
213
213
|
end
|
|
214
214
|
|
|
215
215
|
# Stores the page into +touchable_pages+ (Pages that have to be touched after updating the element).
|
|
216
216
|
def store_page(page)
|
|
217
217
|
return true if page.nil?
|
|
218
|
+
|
|
218
219
|
unless touchable_pages.include? page
|
|
219
220
|
touchable_pages << page
|
|
220
221
|
end
|
|
@@ -233,7 +234,7 @@ module Alchemy
|
|
|
233
234
|
|
|
234
235
|
# Returns true if the definition of this element has a taggable true value.
|
|
235
236
|
def taggable?
|
|
236
|
-
definition[
|
|
237
|
+
definition["taggable"] == true
|
|
237
238
|
end
|
|
238
239
|
|
|
239
240
|
# The opposite of folded?
|
|
@@ -243,7 +244,7 @@ module Alchemy
|
|
|
243
244
|
|
|
244
245
|
# Defined as compact element?
|
|
245
246
|
def compact?
|
|
246
|
-
definition[
|
|
247
|
+
definition["compact"] == true
|
|
247
248
|
end
|
|
248
249
|
|
|
249
250
|
# The element's view partial is dependent from its name
|
|
@@ -261,17 +262,7 @@ module Alchemy
|
|
|
261
262
|
# Element partials live in +app/views/alchemy/elements+
|
|
262
263
|
#
|
|
263
264
|
def to_partial_path
|
|
264
|
-
|
|
265
|
-
Alchemy::Deprecation.warn <<~WARN
|
|
266
|
-
Having the `_view` suffix on your element view partials is deprecated
|
|
267
|
-
and will not be supported in Alchemy 5.0 anymore. You can safely remove the suffix now.
|
|
268
|
-
|
|
269
|
-
Please also rename the local `element` or `#{name}_view` variable into `#{name}`.
|
|
270
|
-
WARN
|
|
271
|
-
"alchemy/elements/#{name}_view"
|
|
272
|
-
else
|
|
273
|
-
"alchemy/elements/#{name}"
|
|
274
|
-
end
|
|
265
|
+
"alchemy/elements/#{name}"
|
|
275
266
|
end
|
|
276
267
|
|
|
277
268
|
# Returns the key that's taken for cache path.
|
|
@@ -290,7 +281,7 @@ module Alchemy
|
|
|
290
281
|
|
|
291
282
|
# A collection of element names that can be nested inside this element.
|
|
292
283
|
def nestable_elements
|
|
293
|
-
definition.fetch(
|
|
284
|
+
definition.fetch("nestable_elements", [])
|
|
294
285
|
end
|
|
295
286
|
|
|
296
287
|
# Copy all nested elements from current element to given target element.
|
|
@@ -298,7 +289,7 @@ module Alchemy
|
|
|
298
289
|
nested_elements.map do |nested_element|
|
|
299
290
|
Element.copy(nested_element, {
|
|
300
291
|
parent_element_id: target_element.id,
|
|
301
|
-
page_id: target_element.page_id
|
|
292
|
+
page_id: target_element.page_id,
|
|
302
293
|
})
|
|
303
294
|
end
|
|
304
295
|
end
|
|
@@ -306,7 +297,7 @@ module Alchemy
|
|
|
306
297
|
private
|
|
307
298
|
|
|
308
299
|
def generate_nested_elements
|
|
309
|
-
definition.fetch(
|
|
300
|
+
definition.fetch("autogenerate", []).each do |nestable_element|
|
|
310
301
|
if nestable_elements.include?(nestable_element)
|
|
311
302
|
Element.create(page: page, parent_element_id: id, name: nestable_element)
|
|
312
303
|
else
|
|
@@ -326,6 +317,7 @@ module Alchemy
|
|
|
326
317
|
#
|
|
327
318
|
def touch_touchable_pages
|
|
328
319
|
return unless respond_to?(:touchable_pages)
|
|
320
|
+
|
|
329
321
|
touchable_pages.each(&:touch)
|
|
330
322
|
end
|
|
331
323
|
end
|
|
@@ -8,14 +8,12 @@
|
|
|
8
8
|
# value :boolean
|
|
9
9
|
# created_at :datetime not null
|
|
10
10
|
# updated_at :datetime not null
|
|
11
|
-
# creator_id :integer
|
|
12
|
-
# updater_id :integer
|
|
13
11
|
#
|
|
14
12
|
|
|
15
13
|
# Stores boolean values.
|
|
16
14
|
# Provides a checkbox in the editor views.
|
|
17
15
|
module Alchemy
|
|
18
16
|
class EssenceBoolean < BaseRecord
|
|
19
|
-
acts_as_essence ingredient_column:
|
|
17
|
+
acts_as_essence ingredient_column: "value"
|
|
20
18
|
end
|
|
21
19
|
end
|
|
@@ -6,19 +6,18 @@
|
|
|
6
6
|
#
|
|
7
7
|
# id :integer not null, primary key
|
|
8
8
|
# date :datetime
|
|
9
|
-
# creator_id :integer
|
|
10
|
-
# updater_id :integer
|
|
11
9
|
# created_at :datetime not null
|
|
12
10
|
# updated_at :datetime not null
|
|
13
11
|
#
|
|
14
12
|
|
|
15
13
|
module Alchemy
|
|
16
14
|
class EssenceDate < BaseRecord
|
|
17
|
-
acts_as_essence ingredient_column:
|
|
15
|
+
acts_as_essence ingredient_column: "date"
|
|
18
16
|
|
|
19
17
|
# Returns self.date for the Element#preview_text method.
|
|
20
18
|
def preview_text(_maxlength = nil)
|
|
21
19
|
return "" if date.blank?
|
|
20
|
+
|
|
22
21
|
::I18n.l(date, format: :'alchemy.essence_date')
|
|
23
22
|
end
|
|
24
23
|
end
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
# attachment_id :integer
|
|
9
9
|
# title :string
|
|
10
10
|
# css_class :string
|
|
11
|
-
# creator_id :integer
|
|
12
|
-
# updater_id :integer
|
|
13
11
|
# created_at :datetime not null
|
|
14
12
|
# updated_at :datetime not null
|
|
15
13
|
# link_text :string
|
|
@@ -18,19 +16,21 @@
|
|
|
18
16
|
module Alchemy
|
|
19
17
|
class EssenceFile < BaseRecord
|
|
20
18
|
belongs_to :attachment, optional: true
|
|
21
|
-
acts_as_essence ingredient_column:
|
|
19
|
+
acts_as_essence ingredient_column: "attachment"
|
|
22
20
|
|
|
23
21
|
def attachment_url
|
|
24
22
|
return if attachment.nil?
|
|
23
|
+
|
|
25
24
|
routes.download_attachment_path(
|
|
26
25
|
id: attachment.id,
|
|
27
26
|
name: attachment.urlname,
|
|
28
|
-
format: attachment.suffix
|
|
27
|
+
format: attachment.suffix,
|
|
29
28
|
)
|
|
30
29
|
end
|
|
31
30
|
|
|
32
31
|
def preview_text(max = 30)
|
|
33
32
|
return "" if attachment.blank?
|
|
33
|
+
|
|
34
34
|
attachment.name.to_s[0..max - 1]
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -6,15 +6,13 @@
|
|
|
6
6
|
#
|
|
7
7
|
# id :integer not null, primary key
|
|
8
8
|
# source :text
|
|
9
|
-
# creator_id :integer
|
|
10
|
-
# updater_id :integer
|
|
11
9
|
# created_at :datetime not null
|
|
12
10
|
# updated_at :datetime not null
|
|
13
11
|
#
|
|
14
12
|
|
|
15
13
|
module Alchemy
|
|
16
14
|
class EssenceHtml < BaseRecord
|
|
17
|
-
acts_as_essence ingredient_column:
|
|
15
|
+
acts_as_essence ingredient_column: "source"
|
|
18
16
|
|
|
19
17
|
# Returns the first x (default = 30) (HTML escaped) characters from self.source for the Element#preview_text method.
|
|
20
18
|
def preview_text(maxlength = 30)
|
|
@@ -11,12 +11,10 @@
|
|
|
11
11
|
# link_class_name :string
|
|
12
12
|
# created_at :datetime not null
|
|
13
13
|
# updated_at :datetime not null
|
|
14
|
-
# creator_id :integer
|
|
15
|
-
# updater_id :integer
|
|
16
14
|
#
|
|
17
15
|
|
|
18
16
|
module Alchemy
|
|
19
17
|
class EssenceLink < BaseRecord
|
|
20
|
-
acts_as_essence ingredient_column:
|
|
18
|
+
acts_as_essence ingredient_column: "link"
|
|
21
19
|
end
|
|
22
20
|
end
|