alchemy_cms 4.6.1 → 5.0.0
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 +30 -9
- data/CHANGELOG.md +102 -1
- 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.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/navigation.scss +1 -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/alchemy/tags.scss +2 -2
- 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 +51 -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 +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 +38 -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 +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 +4 -3
- data/app/mailers/alchemy/base_mailer.rb +1 -1
- data/app/mailers/alchemy/messages_mailer.rb +1 -1
- data/app/models/alchemy/attachment.rb +24 -19
- data/app/models/alchemy/base_record.rb +2 -5
- data/app/models/alchemy/content.rb +33 -38
- 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 +5 -5
- 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 +18 -17
- 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 +27 -4
- data/app/models/alchemy/page.rb +46 -127
- 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/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 +9 -7
- 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_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/pictures/index.html.erb +18 -3
- data/app/views/alchemy/admin/pictures/show.html.erb +1 -1
- 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/resources/index.html.erb +21 -22
- 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_file_view.html.erb +1 -1
- 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 -16
- 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 +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 +3 -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 +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 +25 -15
- 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 +18 -116
- 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 +112 -88
- 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/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 -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 -97
- 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
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class AddLanguageIdForeignKeyToAlchemyPages < ActiveRecord::Migration[5.2]
|
|
4
|
+
def change
|
|
5
|
+
add_foreign_key :alchemy_pages, :alchemy_languages, column: :language_id
|
|
6
|
+
change_column_null :alchemy_pages, :language_id, false, Alchemy::Language.default&.id
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
class AddMenuTypeToAlchemyNodes < ActiveRecord::Migration[5.2]
|
|
3
|
+
class LocalNode < ActiveRecord::Base
|
|
4
|
+
self.table_name = :alchemy_nodes
|
|
5
|
+
acts_as_nested_set scope: :language_id
|
|
6
|
+
|
|
7
|
+
def self.root_for(node)
|
|
8
|
+
return node if node.parent_id.nil?
|
|
9
|
+
|
|
10
|
+
root_for(node.parent)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def up
|
|
15
|
+
add_column :alchemy_nodes, :menu_type, :string
|
|
16
|
+
LocalNode.all.each do |node|
|
|
17
|
+
root = LocalNode.root_for(node)
|
|
18
|
+
menu_type = root.name.parameterize.underscore
|
|
19
|
+
node.update(menu_type: menu_type)
|
|
20
|
+
end
|
|
21
|
+
change_column_null :alchemy_nodes, :menu_type, false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def down
|
|
25
|
+
remove_column :alchemy_nodes, :menu_type
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
class RemoveVisibleFromAlchemyPages < ActiveRecord::Migration[5.2]
|
|
3
|
+
class LocalPage < ActiveRecord::Base
|
|
4
|
+
self.table_name = "alchemy_pages"
|
|
5
|
+
|
|
6
|
+
scope :invisible, -> { where(visible: [false, nil]) }
|
|
7
|
+
scope :contentpages, -> { where(layoutpage: [false, nil]) }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def up
|
|
11
|
+
if LocalPage.invisible.contentpages.where.not(parent_id: nil).any?
|
|
12
|
+
abort "You have invisible pages in your database! " \
|
|
13
|
+
"Please re-structure your page tree before running this migration. " \
|
|
14
|
+
"You might also downgrade to Alchemy 4.6 and " \
|
|
15
|
+
"run the `alchemy:upgrade:4.6:restructure_page_tree` rake task."
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
remove_column :alchemy_pages, :visible
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def down
|
|
22
|
+
add_column :alchemy_pages, :visible, :boolean, default: false
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/alchemy/admin/locale.rb
CHANGED
|
@@ -47,6 +47,7 @@ module Alchemy
|
|
|
47
47
|
# Try to get the locale from user settings.
|
|
48
48
|
def locale_from_user
|
|
49
49
|
return if !current_alchemy_user
|
|
50
|
+
|
|
50
51
|
if user_has_preferred_language?
|
|
51
52
|
current_alchemy_user.language
|
|
52
53
|
end
|
|
@@ -55,6 +56,7 @@ module Alchemy
|
|
|
55
56
|
# Checks if the +current_alchemy_user+ has a preferred language set or not.
|
|
56
57
|
def user_has_preferred_language?
|
|
57
58
|
return if !current_alchemy_user
|
|
59
|
+
|
|
58
60
|
current_alchemy_user.respond_to?(:language) &&
|
|
59
61
|
current_alchemy_user.language.present? &&
|
|
60
62
|
current_alchemy_user.language.respond_to?(:to_sym)
|
|
@@ -62,7 +64,7 @@ module Alchemy
|
|
|
62
64
|
|
|
63
65
|
# Try to get the locale from browser headers.
|
|
64
66
|
def locale_from_browser
|
|
65
|
-
request.env[
|
|
67
|
+
request.env["HTTP_ACCEPT_LANGUAGE"].try(:scan, /\A[a-z]{2}/).try(:first)
|
|
66
68
|
end
|
|
67
69
|
end
|
|
68
70
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
|
|
5
|
+
module Alchemy
|
|
6
|
+
module Admin
|
|
7
|
+
# = Preview window URL configuration
|
|
8
|
+
#
|
|
9
|
+
# By default Alchemy uses its internal page preview renderer,
|
|
10
|
+
# but you can configure it to be any URL instead.
|
|
11
|
+
#
|
|
12
|
+
# Basic Auth is supported.
|
|
13
|
+
#
|
|
14
|
+
# == Example config/alchemy/config.yml
|
|
15
|
+
#
|
|
16
|
+
# preview:
|
|
17
|
+
# host: https://www.my-static-site.com
|
|
18
|
+
# auth:
|
|
19
|
+
# username: <%= ENV["BASIC_AUTH_USERNAME"] %>
|
|
20
|
+
# password: <%= ENV["BASIC_AUTH_PASSWORD"] %>
|
|
21
|
+
#
|
|
22
|
+
# Preview config per site is supported as well.
|
|
23
|
+
#
|
|
24
|
+
# == Example config/alchemy/config.yml
|
|
25
|
+
#
|
|
26
|
+
# preview:
|
|
27
|
+
# My site name:
|
|
28
|
+
# host: https://www.my-static-site.com
|
|
29
|
+
# auth:
|
|
30
|
+
# username: <%= ENV["BASIC_AUTH_USERNAME"] %>
|
|
31
|
+
# password: <%= ENV["BASIC_AUTH_PASSWORD"] %>
|
|
32
|
+
#
|
|
33
|
+
class PreviewUrl
|
|
34
|
+
class MissingProtocolError < StandardError; end
|
|
35
|
+
|
|
36
|
+
def initialize(routes:)
|
|
37
|
+
@routes = routes.url_helpers
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def url_for(page)
|
|
41
|
+
@preview_config = preview_config_for(page)
|
|
42
|
+
|
|
43
|
+
if @preview_config && uri
|
|
44
|
+
uri_class.build(
|
|
45
|
+
host: uri.host,
|
|
46
|
+
path: page.url_path,
|
|
47
|
+
userinfo: userinfo,
|
|
48
|
+
).to_s
|
|
49
|
+
else
|
|
50
|
+
routes.admin_page_path(page)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
attr_reader :routes
|
|
57
|
+
|
|
58
|
+
def preview_config_for(page)
|
|
59
|
+
preview_config = Alchemy::Config.get(:preview)
|
|
60
|
+
return unless preview_config
|
|
61
|
+
|
|
62
|
+
preview_config[page.site.name] || preview_config
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def uri
|
|
66
|
+
return unless @preview_config["host"]
|
|
67
|
+
|
|
68
|
+
URI(@preview_config["host"])
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def uri_class
|
|
72
|
+
if uri.class == URI::Generic
|
|
73
|
+
raise MissingProtocolError, "Please provide the protocol with preview['host']"
|
|
74
|
+
else
|
|
75
|
+
uri.class
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def userinfo
|
|
80
|
+
auth = @preview_config["auth"]
|
|
81
|
+
auth ? "#{auth["username"]}:#{auth["password"]}" : nil
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -53,13 +53,13 @@ module Alchemy
|
|
|
53
53
|
|
|
54
54
|
# Defaults
|
|
55
55
|
#
|
|
56
|
-
@@user_class_name =
|
|
56
|
+
@@user_class_name = "User"
|
|
57
57
|
@@user_class_primary_key = :id
|
|
58
|
-
@@current_user_method =
|
|
59
|
-
@@signup_path =
|
|
60
|
-
@@login_path =
|
|
61
|
-
@@logout_path =
|
|
62
|
-
@@logout_method =
|
|
58
|
+
@@current_user_method = "current_user"
|
|
59
|
+
@@signup_path = "/signup"
|
|
60
|
+
@@login_path = "/login"
|
|
61
|
+
@@logout_path = "/logout"
|
|
62
|
+
@@logout_method = "delete"
|
|
63
63
|
|
|
64
64
|
# Returns the user class
|
|
65
65
|
#
|
|
@@ -76,8 +76,9 @@ module Alchemy
|
|
|
76
76
|
# Prefix with :: when getting to avoid constant name conflicts
|
|
77
77
|
def self.user_class_name
|
|
78
78
|
if !@@user_class_name.is_a?(String)
|
|
79
|
-
raise TypeError,
|
|
79
|
+
raise TypeError, "Alchemy.user_class_name must be a String, not a Class."
|
|
80
80
|
end
|
|
81
|
+
|
|
81
82
|
"::#{@@user_class_name}"
|
|
82
83
|
end
|
|
83
84
|
|
|
@@ -14,10 +14,10 @@ module Alchemy
|
|
|
14
14
|
def dependencies
|
|
15
15
|
case @name.to_s
|
|
16
16
|
when /^alchemy\/pages\/show/
|
|
17
|
-
PageLayout.all.map { |p| "alchemy/page_layouts/_#{p[
|
|
17
|
+
PageLayout.all.map { |p| "alchemy/page_layouts/_#{p["name"]}" }
|
|
18
18
|
when /^alchemy\/page_layouts\/_(\w+)/
|
|
19
19
|
page_layout = PageLayout.get($1)
|
|
20
|
-
layout_elements = page_layout.fetch(
|
|
20
|
+
layout_elements = page_layout.fetch("elements", [])
|
|
21
21
|
layout_elements.map { |name| "alchemy/elements/_#{name}_view" } +
|
|
22
22
|
layout_elements.map { |name| "alchemy/elements/_#{name}" }
|
|
23
23
|
when /^alchemy\/elements\/_(\w+)_view/, /^alchemy\/elements\/_(\w+)/
|
|
@@ -32,9 +32,10 @@ module Alchemy
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
34
|
def essence_types(name)
|
|
35
|
-
element = Element.definitions.detect { |e| e[
|
|
35
|
+
element = Element.definitions.detect { |e| e["name"] == name }
|
|
36
36
|
return [] unless element
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
element.fetch("contents", []).collect { |c| c["type"] }
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
41
|
end
|
data/lib/alchemy/config.rb
CHANGED
|
@@ -32,9 +32,7 @@ module Alchemy
|
|
|
32
32
|
# any not nil value is the new default
|
|
33
33
|
def deprecated_configs
|
|
34
34
|
{
|
|
35
|
-
|
|
36
|
-
require_ssl: nil,
|
|
37
|
-
auto_logout_time: nil,
|
|
35
|
+
redirect_to_public_child: nil,
|
|
38
36
|
}
|
|
39
37
|
end
|
|
40
38
|
|
|
@@ -78,11 +76,11 @@ module Alchemy
|
|
|
78
76
|
if deprecated_configs.key?(name.to_sym)
|
|
79
77
|
config = deprecated_configs[name.to_sym]
|
|
80
78
|
if config.nil?
|
|
81
|
-
Alchemy::Deprecation.warn("#{name} configuration is deprecated and will be removed from Alchemy 5.
|
|
79
|
+
Alchemy::Deprecation.warn("#{name} configuration is deprecated and will be removed from Alchemy 5.1")
|
|
82
80
|
else
|
|
83
81
|
value = show[name.to_s]
|
|
84
82
|
if value != config
|
|
85
|
-
Alchemy::Deprecation.warn("Setting #{name} configuration to #{value} is deprecated and will be always #{config} in Alchemy 5.
|
|
83
|
+
Alchemy::Deprecation.warn("Setting #{name} configuration to #{value} is deprecated and will be always #{config} in Alchemy 5.1")
|
|
86
84
|
end
|
|
87
85
|
end
|
|
88
86
|
end
|
|
@@ -28,7 +28,9 @@ module Alchemy
|
|
|
28
28
|
# matches the current I18n.locale then the prefix os omitted.
|
|
29
29
|
# Also, if only one published language exists.
|
|
30
30
|
#
|
|
31
|
-
def prefix_locale?(locale = Language.current
|
|
31
|
+
def prefix_locale?(locale = Language.current&.code)
|
|
32
|
+
return false unless locale
|
|
33
|
+
|
|
32
34
|
multi_language? && locale != ::I18n.default_locale.to_s
|
|
33
35
|
end
|
|
34
36
|
|
|
@@ -8,7 +8,7 @@ module Alchemy
|
|
|
8
8
|
before_action :set_current_alchemy_site
|
|
9
9
|
before_action :set_alchemy_language
|
|
10
10
|
|
|
11
|
-
helper
|
|
11
|
+
helper "alchemy/pages"
|
|
12
12
|
|
|
13
13
|
helper_method :current_alchemy_user,
|
|
14
14
|
:alchemy_user_signed_in?,
|
|
@@ -36,6 +36,7 @@ module Alchemy
|
|
|
36
36
|
def current_alchemy_user
|
|
37
37
|
current_user_method = Alchemy.current_user_method
|
|
38
38
|
raise NoCurrentUserFoundError if !respond_to?(current_user_method, true)
|
|
39
|
+
|
|
39
40
|
send current_user_method
|
|
40
41
|
end
|
|
41
42
|
|
|
@@ -66,8 +67,8 @@ module Alchemy
|
|
|
66
67
|
else
|
|
67
68
|
# find the best language and remember it for later
|
|
68
69
|
@language = load_alchemy_language_from_params ||
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
load_alchemy_language_from_session ||
|
|
71
|
+
Language.default
|
|
71
72
|
end
|
|
72
73
|
store_current_alchemy_language(@language)
|
|
73
74
|
end
|
|
@@ -81,7 +82,7 @@ module Alchemy
|
|
|
81
82
|
# Load language from session if it's present on current site.
|
|
82
83
|
# Otherwise return nil so we can load the default language from current site.
|
|
83
84
|
def load_alchemy_language_from_session
|
|
84
|
-
if session[:alchemy_language_id].present?
|
|
85
|
+
if session[:alchemy_language_id].present? && Site.current
|
|
85
86
|
Site.current.languages.find_by(id: session[:alchemy_language_id])
|
|
86
87
|
end
|
|
87
88
|
end
|
|
@@ -96,7 +97,7 @@ module Alchemy
|
|
|
96
97
|
# Also stores language in +Language.current+
|
|
97
98
|
#
|
|
98
99
|
def store_current_alchemy_language(language)
|
|
99
|
-
if language
|
|
100
|
+
if language&.id
|
|
100
101
|
session[:alchemy_language_id] = language.id
|
|
101
102
|
Language.current = language
|
|
102
103
|
end
|
data/lib/alchemy/deprecation.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "alchemy/logger"
|
|
4
4
|
|
|
5
5
|
module Alchemy
|
|
6
6
|
# Loads elements from given page
|
|
@@ -86,7 +86,7 @@ module Alchemy
|
|
|
86
86
|
Alchemy::Page.find_by(
|
|
87
87
|
language: Alchemy::Language.current,
|
|
88
88
|
page_layout: page_or_layout,
|
|
89
|
-
restricted: false
|
|
89
|
+
restricted: false,
|
|
90
90
|
)
|
|
91
91
|
end
|
|
92
92
|
end
|
|
@@ -104,10 +104,10 @@ module Alchemy
|
|
|
104
104
|
|
|
105
105
|
def random_function
|
|
106
106
|
case ActiveRecord::Base.connection_config[:adapter]
|
|
107
|
-
when
|
|
108
|
-
|
|
107
|
+
when "postgresql", "sqlite3"
|
|
108
|
+
"RANDOM()"
|
|
109
109
|
else
|
|
110
|
-
|
|
110
|
+
"RAND()"
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
end
|
data/lib/alchemy/engine.rb
CHANGED
|
@@ -1,32 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Alchemy
|
|
2
3
|
class Engine < Rails::Engine
|
|
3
4
|
isolate_namespace Alchemy
|
|
4
|
-
engine_name
|
|
5
|
-
config.mount_at =
|
|
5
|
+
engine_name "alchemy"
|
|
6
|
+
config.mount_at = "/"
|
|
6
7
|
|
|
7
|
-
initializer
|
|
8
|
-
Alchemy::LOOKUP_CONTEXT = ActionView::LookupContext.new(Rails.root.join(
|
|
8
|
+
initializer "alchemy.lookup_context" do
|
|
9
|
+
Alchemy::LOOKUP_CONTEXT = ActionView::LookupContext.new(Rails.root.join("app", "views", "alchemy"))
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
initializer
|
|
12
|
+
initializer "alchemy.admin.preview_url" do
|
|
13
|
+
Alchemy::Admin::PREVIEW_URL = Alchemy::Admin::PreviewUrl.new(routes: Alchemy::Engine.routes)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
initializer "alchemy.dependency_tracker" do
|
|
12
17
|
[:erb, :slim, :haml].each do |handler|
|
|
13
18
|
ActionView::DependencyTracker.register_tracker(handler, CacheDigests::TemplateTracker)
|
|
14
19
|
end
|
|
15
20
|
end
|
|
16
21
|
|
|
17
|
-
initializer
|
|
22
|
+
initializer "alchemy.non_digest_assets" do
|
|
18
23
|
NonStupidDigestAssets.whitelist += [/^tinymce\//]
|
|
19
24
|
end
|
|
20
25
|
|
|
21
26
|
# Gutentag downcases all tgas before save.
|
|
22
27
|
# We support having tags with uppercase characters.
|
|
23
28
|
# The Gutentag search is case insensitive.
|
|
24
|
-
initializer
|
|
29
|
+
initializer "alchemy.gutentag_normalizer" do
|
|
25
30
|
Gutentag.normaliser = ->(value) { value.to_s }
|
|
26
31
|
end
|
|
27
32
|
|
|
33
|
+
# Custom Ransack sort arrows
|
|
34
|
+
initializer "alchemy.ransack" do
|
|
35
|
+
Ransack.configure do |config|
|
|
36
|
+
config.custom_arrows = {
|
|
37
|
+
up_arrow: '<i class="fa fas fa-xs fa-arrow-up"></i>',
|
|
38
|
+
down_arrow: '<i class="fa fas fa-xs fa-arrow-down"></i>',
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
28
43
|
config.after_initialize do
|
|
29
|
-
require_relative
|
|
44
|
+
require_relative "./userstamp"
|
|
30
45
|
end
|
|
31
46
|
end
|
|
32
47
|
end
|
data/lib/alchemy/errors.rb
CHANGED
|
@@ -23,13 +23,6 @@ module Alchemy
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
class DefaultLanguageNotDeletable < StandardError
|
|
27
|
-
# Raised if one tries to delete the default language.
|
|
28
|
-
def message
|
|
29
|
-
"Default language is not deletable!"
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
26
|
class ElementDefinitionError < StandardError
|
|
34
27
|
# Raised if element definition can not be found.
|
|
35
28
|
def initialize(attributes)
|
data/lib/alchemy/essence.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "active_record"
|
|
4
4
|
|
|
5
5
|
module Alchemy #:nodoc:
|
|
6
6
|
# A bogus association that skips eager loading for essences not having an ingredient association
|
|
@@ -40,7 +40,7 @@ module Alchemy #:nodoc:
|
|
|
40
40
|
register_as_essence_association!
|
|
41
41
|
|
|
42
42
|
configuration = {
|
|
43
|
-
ingredient_column:
|
|
43
|
+
ingredient_column: "body",
|
|
44
44
|
}.update(options)
|
|
45
45
|
|
|
46
46
|
@_classes_with_ingredient_association ||= []
|
|
@@ -48,7 +48,7 @@ module Alchemy #:nodoc:
|
|
|
48
48
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
49
49
|
attr_writer :validation_errors
|
|
50
50
|
include Alchemy::Essence::InstanceMethods
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
validate :validate_ingredient, on: :update, if: -> { validations.any? }
|
|
53
53
|
|
|
54
54
|
has_one :content, as: :essence, class_name: "Alchemy::Content", inverse_of: :essence
|
|
@@ -62,7 +62,7 @@ module Alchemy #:nodoc:
|
|
|
62
62
|
delegate :trashed?, to: :element, allow_nil: true
|
|
63
63
|
delegate :public?, to: :element, allow_nil: true
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
after_save :touch_element
|
|
66
66
|
|
|
67
67
|
def acts_as_essence_class
|
|
68
68
|
#{name}
|
|
@@ -109,7 +109,7 @@ module Alchemy #:nodoc:
|
|
|
109
109
|
def register_as_essence_association!
|
|
110
110
|
klass_name = model_name.to_s
|
|
111
111
|
arguments = [:has_many, klass_name.demodulize.tableize.to_sym, through: :contents,
|
|
112
|
-
|
|
112
|
+
source: :essence, source_type: klass_name]
|
|
113
113
|
%w(Page Element).each { |k| "Alchemy::#{k}".constantize.send(*arguments) }
|
|
114
114
|
end
|
|
115
115
|
end
|
|
@@ -171,7 +171,7 @@ module Alchemy #:nodoc:
|
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
def validations
|
|
174
|
-
@validations ||= definition.present? ? definition[
|
|
174
|
+
@validations ||= definition.present? ? definition["validate"] || [] : []
|
|
175
175
|
end
|
|
176
176
|
|
|
177
177
|
def validation_errors
|
|
@@ -187,6 +187,7 @@ module Alchemy #:nodoc:
|
|
|
187
187
|
|
|
188
188
|
def validate_uniqueness(validate = true)
|
|
189
189
|
return if !validate || !public?
|
|
190
|
+
|
|
190
191
|
if duplicates.any?
|
|
191
192
|
errors.add(ingredient_column, :taken)
|
|
192
193
|
validation_errors << :taken
|
|
@@ -194,7 +195,7 @@ module Alchemy #:nodoc:
|
|
|
194
195
|
end
|
|
195
196
|
|
|
196
197
|
def validate_format(format)
|
|
197
|
-
matcher = Config.get(
|
|
198
|
+
matcher = Config.get("format_matchers")[format] || format
|
|
198
199
|
if ingredient.to_s.match(Regexp.new(matcher)).nil?
|
|
199
200
|
errors.add(ingredient_column, :invalid)
|
|
200
201
|
validation_errors << :invalid
|
|
@@ -216,7 +217,7 @@ module Alchemy #:nodoc:
|
|
|
216
217
|
end
|
|
217
218
|
end
|
|
218
219
|
|
|
219
|
-
#
|
|
220
|
+
# Sets the value stored in the database column that is configured as ingredient column.
|
|
220
221
|
def ingredient=(value)
|
|
221
222
|
if respond_to?(ingredient_setter_method)
|
|
222
223
|
send(ingredient_setter_method, value)
|
|
@@ -225,19 +226,19 @@ module Alchemy #:nodoc:
|
|
|
225
226
|
|
|
226
227
|
# Returns the setter method for ingredient column
|
|
227
228
|
def ingredient_setter_method
|
|
228
|
-
ingredient_column.to_s +
|
|
229
|
+
ingredient_column.to_s + "="
|
|
229
230
|
end
|
|
230
231
|
|
|
231
232
|
# Essence definition from config/elements.yml
|
|
232
233
|
def definition
|
|
233
234
|
return {} if element.nil? || element.content_definitions.nil?
|
|
234
|
-
|
|
235
|
+
|
|
236
|
+
element.content_definitions.detect { |c| c["name"] == content.name } || {}
|
|
235
237
|
end
|
|
236
238
|
|
|
237
|
-
#
|
|
238
|
-
def
|
|
239
|
-
|
|
240
|
-
content.touch
|
|
239
|
+
# Touches element. Called after save.
|
|
240
|
+
def touch_element
|
|
241
|
+
element&.touch
|
|
241
242
|
end
|
|
242
243
|
|
|
243
244
|
# Returns the first x (default 30) characters of ingredient for the Element#preview_text method.
|
|
@@ -247,11 +248,11 @@ module Alchemy #:nodoc:
|
|
|
247
248
|
end
|
|
248
249
|
|
|
249
250
|
def open_link_in_new_window?
|
|
250
|
-
respond_to?(:link_target) && link_target ==
|
|
251
|
+
respond_to?(:link_target) && link_target == "blank"
|
|
251
252
|
end
|
|
252
253
|
|
|
253
254
|
def partial_name
|
|
254
|
-
self.class.name.split(
|
|
255
|
+
self.class.name.split("::").last.underscore
|
|
255
256
|
end
|
|
256
257
|
|
|
257
258
|
def acts_as_essence?
|