alchemy_cms 4.4.3 → 5.0.0.beta1
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 +34 -21
- data/CHANGELOG.md +120 -0
- data/Gemfile +24 -22
- data/README.md +31 -19
- data/Rakefile +10 -8
- data/alchemy_cms.gemspec +6 -4
- data/app/assets/javascripts/alchemy/admin.js +1 -2
- 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 +2 -0
- data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
- data/app/assets/javascripts/alchemy/templates/node_folder.hbs +3 -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 +6 -1
- 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 -14
- 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 +65 -0
- 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 +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 +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 +55 -9
- 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 +18 -27
- 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 +14 -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 +23 -15
- data/app/views/alchemy/admin/nodes/_node.html.erb +5 -19
- data/app/views/alchemy/admin/nodes/index.html.erb +8 -19
- 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/partials/_routes.html.erb +8 -0
- 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 -24
- 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 +37 -14
- data/config/routes.rb +32 -28
- 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 +26 -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/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 +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/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 +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/generators/alchemy/install/templates/menus.yml.tt +8 -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 +5 -5
- 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 +2 -2
- data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +2 -2
- 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 +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 +128 -81
- data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
- 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/stylesheets/fontawesome/fa-regular.scss +0 -22
- data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -22,10 +22,13 @@ module Alchemy
|
|
22
22
|
if definition.blank?
|
23
23
|
raise ContentDefinitionError, "No definition found in elements.yml for #{attributes.inspect} and #{element.inspect}"
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
|
+
super(
|
27
|
+
name: definition[:name],
|
28
|
+
essence_type: normalize_essence_type(definition[:type]),
|
29
|
+
element_id: element.id
|
30
|
+
).tap(&:build_essence)
|
26
31
|
end
|
27
|
-
alias_method :build, :new
|
28
|
-
deprecate build: :new, deprecator: Alchemy::Deprecation
|
29
32
|
|
30
33
|
# Creates a new content from elements definition in the +elements.yml+ file.
|
31
34
|
#
|
@@ -34,20 +37,11 @@ module Alchemy
|
|
34
37
|
#
|
35
38
|
# @return [Alchemy::Content]
|
36
39
|
#
|
37
|
-
def create(
|
38
|
-
attributes
|
39
|
-
|
40
|
-
Alchemy::Deprecation.warn 'Passing an element as first argument to Alchemy::Content.create is deprecated! Pass an attribute hash with element inside instead.'
|
41
|
-
element = args.first
|
42
|
-
else
|
43
|
-
element = attributes[:element]
|
44
|
-
end
|
45
|
-
new(attributes.merge(element: element)).tap do |content|
|
46
|
-
content.create_essence!(attributes[:essence_type])
|
40
|
+
def create(attributes = {})
|
41
|
+
new(attributes).tap do |content|
|
42
|
+
content.essence.save && content.save
|
47
43
|
end
|
48
44
|
end
|
49
|
-
alias_method :create_from_scratch, :create
|
50
|
-
deprecate create_from_scratch: :create, deprecator: Alchemy::Deprecation
|
51
45
|
|
52
46
|
# Creates a copy of source and also copies the associated essence.
|
53
47
|
#
|
@@ -62,11 +56,11 @@ module Alchemy
|
|
62
56
|
new_content = Content.new(
|
63
57
|
source.attributes.
|
64
58
|
except(*SKIPPED_ATTRIBUTES_ON_COPY).
|
65
|
-
merge(differences.with_indifferent_access)
|
59
|
+
merge(differences.with_indifferent_access),
|
66
60
|
)
|
67
61
|
new_essence = source.essence.class.create!(
|
68
62
|
source.essence.attributes.
|
69
|
-
except(*SKIPPED_ATTRIBUTES_ON_COPY)
|
63
|
+
except(*SKIPPED_ATTRIBUTES_ON_COPY),
|
70
64
|
)
|
71
65
|
new_content.tap do |content|
|
72
66
|
content.essence = new_essence
|
@@ -77,7 +71,7 @@ module Alchemy
|
|
77
71
|
# Returns all content definitions from elements.yml
|
78
72
|
#
|
79
73
|
def definitions
|
80
|
-
definitions = Element.definitions.flat_map { |e| e[
|
74
|
+
definitions = Element.definitions.flat_map { |e| e["contents"] }
|
81
75
|
definitions.compact!
|
82
76
|
definitions
|
83
77
|
end
|
@@ -119,12 +113,22 @@ module Alchemy
|
|
119
113
|
element.content_definition_for(name) || {}
|
120
114
|
end
|
121
115
|
|
116
|
+
# Build essence from definition.
|
117
|
+
#
|
118
|
+
# If an optional type is passed, this type of essence gets created.
|
119
|
+
#
|
120
|
+
def build_essence(type = essence_type)
|
121
|
+
self.essence = essence_class(type).new({
|
122
|
+
ingredient: default_value,
|
123
|
+
})
|
124
|
+
end
|
125
|
+
|
122
126
|
# Creates essence from definition.
|
123
127
|
#
|
124
128
|
# If an optional type is passed, this type of essence gets created.
|
125
129
|
#
|
126
130
|
def create_essence!(type = nil)
|
127
|
-
|
131
|
+
build_essence(type).save!
|
128
132
|
save!
|
129
133
|
end
|
130
134
|
|
@@ -135,18 +139,7 @@ module Alchemy
|
|
135
139
|
# If an optional type is passed, this type of essence gets constantized.
|
136
140
|
#
|
137
141
|
def essence_class(type = nil)
|
138
|
-
Content.normalize_essence_type(type || definition[
|
139
|
-
end
|
140
|
-
|
141
|
-
# Prepares the attributes for creating the essence.
|
142
|
-
#
|
143
|
-
# 1. It sets a default text if given in +elements.yml+
|
144
|
-
#
|
145
|
-
def prepared_attributes_for_essence
|
146
|
-
attributes = {
|
147
|
-
ingredient: default_text(definition['default'])
|
148
|
-
}
|
149
|
-
attributes
|
142
|
+
Content.normalize_essence_type(type || definition["type"]).constantize
|
150
143
|
end
|
151
144
|
end
|
152
145
|
end
|
@@ -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.
|
@@ -60,17 +62,17 @@ module Alchemy
|
|
60
62
|
|
61
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
|
@@ -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
|