alchemy_cms 7.4.10 → 8.0.0.b
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.
Potentially problematic release.
This version of alchemy_cms might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +16 -5
- data/app/assets/builds/alchemy/admin/page-select.css +1 -1
- data/app/assets/builds/alchemy/admin/print.css +1 -1
- data/app/assets/builds/alchemy/admin.css +2 -2
- data/app/assets/builds/alchemy/dark-theme.css +1 -0
- data/app/assets/builds/alchemy/light-theme.css +1 -0
- data/app/assets/builds/alchemy/theme.css +1 -0
- data/app/assets/builds/alchemy/welcome.css +1 -1
- data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css +1 -1
- data/app/assets/builds/tinymce/skins/content/alchemy-dark/content.min.css +1 -0
- data/app/assets/builds/tinymce/skins/ui/alchemy/content.min.css +1 -0
- data/app/assets/builds/tinymce/skins/ui/alchemy/skin.min.css +1 -1
- data/app/assets/builds/tinymce/skins/ui/alchemy-dark/content.min.css +1 -0
- data/app/assets/builds/tinymce/skins/ui/alchemy-dark/skin.min.css +1 -0
- data/app/assets/config/alchemy_manifest.js +0 -2
- data/app/assets/images/alchemy/element_icons/default.svg +1 -0
- data/app/assets/images/alchemy/icons-sprite.svg +1 -0
- data/app/components/alchemy/admin/element_select.rb +39 -0
- data/app/components/alchemy/admin/resource/applied_filter.rb +29 -0
- data/app/components/alchemy/admin/resource/checkbox_filter.rb +36 -0
- data/app/components/alchemy/admin/resource/datepicker_filter.rb +42 -0
- data/app/components/alchemy/admin/resource/select_filter.rb +43 -0
- data/app/components/alchemy/admin/toolbar_button.rb +5 -2
- data/app/components/alchemy/ingredients/number_view.rb +18 -0
- data/app/controllers/alchemy/admin/attachments_controller.rb +10 -15
- data/app/controllers/alchemy/admin/clipboard_controller.rb +2 -6
- data/app/controllers/alchemy/admin/elements_controller.rb +3 -1
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +15 -15
- data/app/controllers/alchemy/admin/pictures_controller.rb +27 -37
- data/app/controllers/alchemy/admin/resources_controller.rb +16 -106
- data/app/controllers/alchemy/attachments_controller.rb +43 -14
- data/app/controllers/alchemy/messages_controller.rb +1 -1
- data/app/controllers/alchemy/pages_controller.rb +26 -4
- data/app/controllers/concerns/alchemy/admin/resource_filter.rb +93 -0
- data/app/decorators/alchemy/element_editor.rb +5 -48
- data/app/decorators/alchemy/ingredient_editor.rb +3 -53
- data/app/helpers/alchemy/admin/attachments_helper.rb +5 -5
- data/app/helpers/alchemy/admin/base_helper.rb +14 -84
- data/app/helpers/alchemy/admin/pages_helper.rb +1 -1
- data/app/helpers/alchemy/base_helper.rb +0 -30
- data/app/helpers/alchemy/elements_block_helper.rb +0 -14
- data/app/helpers/alchemy/pages_helper.rb +1 -1
- data/{lib → app/helpers}/alchemy/resources_helper.rb +5 -45
- data/app/javascript/alchemy_admin/components/action.js +2 -0
- data/app/javascript/alchemy_admin/components/alchemy_html_element.js +3 -3
- data/app/javascript/alchemy_admin/components/auto_submit.js +20 -0
- data/app/javascript/alchemy_admin/components/datepicker.js +18 -7
- data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +8 -7
- data/app/javascript/alchemy_admin/components/element_editor.js +25 -15
- data/app/javascript/alchemy_admin/components/element_select.js +43 -0
- data/app/javascript/alchemy_admin/components/index.js +3 -0
- data/app/javascript/alchemy_admin/components/link_buttons.js +6 -2
- data/app/javascript/alchemy_admin/components/remote_select.js +9 -2
- data/app/javascript/alchemy_admin/components/tags_autocomplete.js +5 -1
- data/app/javascript/alchemy_admin/components/tinymce.js +93 -14
- data/app/javascript/alchemy_admin/components/update_check.js +42 -0
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +15 -8
- data/app/javascript/alchemy_admin/components/uploader/progress.js +12 -6
- data/app/javascript/alchemy_admin/components/uploader.js +4 -2
- data/app/javascript/alchemy_admin/confirm_dialog.js +27 -57
- data/app/javascript/alchemy_admin/dialog.js +1 -1
- data/app/javascript/alchemy_admin/dirty.js +3 -2
- data/app/javascript/alchemy_admin/file_editors.js +1 -1
- data/app/javascript/alchemy_admin/i18n.js +15 -16
- data/app/javascript/alchemy_admin/image_loader.js +4 -2
- data/app/javascript/alchemy_admin/initializer.js +1 -49
- data/app/javascript/alchemy_admin/picture_editors.js +7 -4
- data/app/javascript/alchemy_admin/picture_selector.js +4 -4
- data/app/javascript/alchemy_admin/utils/ajax.js +51 -44
- data/app/javascript/alchemy_admin.js +3 -8
- data/app/jobs/alchemy/delete_picture_job.rb +12 -0
- data/app/models/alchemy/admin/filters/base.rb +38 -0
- data/app/models/alchemy/admin/filters/checkbox.rb +24 -0
- data/app/models/alchemy/admin/filters/datepicker.rb +53 -0
- data/app/models/alchemy/admin/filters/select.rb +70 -0
- data/app/models/alchemy/admin/resource_name.rb +27 -0
- data/app/models/alchemy/attachment.rb +49 -44
- data/app/models/alchemy/base_record.rb +2 -0
- data/app/models/alchemy/element/definitions.rb +1 -1
- data/app/models/alchemy/element/element_ingredients.rb +6 -6
- data/app/models/alchemy/element/presenters.rb +3 -12
- data/app/models/alchemy/element.rb +10 -27
- data/app/models/alchemy/element_definition.rb +190 -0
- data/app/models/alchemy/ingredient.rb +10 -43
- data/app/models/alchemy/ingredient_definition.rb +134 -0
- data/app/models/alchemy/ingredient_validator.rb +7 -3
- data/app/models/alchemy/ingredients/number.rb +19 -0
- data/app/models/alchemy/language.rb +2 -21
- data/app/models/alchemy/message.rb +3 -7
- data/app/models/alchemy/node.rb +1 -1
- data/app/models/alchemy/page/{page_layouts.rb → definitions.rb} +12 -19
- data/app/models/alchemy/page/fixed_attributes.rb +1 -1
- data/app/models/alchemy/page/page_elements.rb +13 -14
- data/app/models/alchemy/page/page_naming.rb +3 -11
- data/app/models/alchemy/page/page_natures.rb +20 -15
- data/app/models/alchemy/page/page_scopes.rb +1 -1
- data/app/models/alchemy/page.rb +12 -39
- data/app/models/alchemy/page_definition.rb +115 -0
- data/app/models/alchemy/picture.rb +71 -99
- data/app/models/alchemy/picture_variant.rb +115 -5
- data/{lib → app/models}/alchemy/resource.rb +4 -18
- data/{lib → app/models}/alchemy/searchable_resource.rb +15 -0
- data/app/models/alchemy/site/layout.rb +5 -5
- data/app/models/alchemy/site.rb +1 -21
- data/app/models/alchemy/storage_adapter/active_storage/attachment_url.rb +41 -0
- data/app/models/alchemy/storage_adapter/active_storage/picture_url.rb +55 -0
- data/app/models/alchemy/storage_adapter/active_storage/preprocessor.rb +40 -0
- data/app/models/alchemy/storage_adapter/active_storage.rb +173 -0
- data/app/models/alchemy/{attachment/url.rb → storage_adapter/dragonfly/attachment_url.rb} +12 -12
- data/app/models/alchemy/storage_adapter/dragonfly/picture_url.rb +75 -0
- data/app/models/alchemy/{picture → storage_adapter/dragonfly}/preprocessor.rb +4 -4
- data/app/models/alchemy/storage_adapter/dragonfly.rb +205 -0
- data/app/models/alchemy/storage_adapter.rb +74 -0
- data/app/models/concerns/alchemy/picture_thumbnails.rb +19 -6
- data/app/models/concerns/alchemy/relatable_resource.rb +28 -0
- data/app/serializers/alchemy/element_serializer.rb +0 -1
- data/app/services/alchemy/dragonfly_to_image_processing.rb +100 -0
- data/app/stylesheets/alchemy/_custom-properties.scss +162 -0
- data/app/stylesheets/alchemy/_defaults.scss +3 -0
- data/app/stylesheets/alchemy/_extends.scss +69 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/_mixins.scss +40 -68
- data/app/stylesheets/alchemy/_themes.scss +540 -0
- data/app/stylesheets/alchemy/_variables.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/archive.scss +45 -42
- data/app/stylesheets/alchemy/admin/attachments.scss +17 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/base.scss +20 -15
- data/app/stylesheets/alchemy/admin/buttons.scss +135 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/clipboard.scss +2 -2
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/dashboard.scss +13 -16
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/dialogs.scss +33 -16
- data/app/stylesheets/alchemy/admin/element-select.scss +11 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/elements.scss +239 -133
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/errors.scss +5 -5
- data/app/stylesheets/alchemy/admin/filters.scss +57 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/flatpickr.scss +54 -76
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/form_fields.scss +10 -11
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/forms.scss +28 -21
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/frame.scss +20 -18
- data/app/stylesheets/alchemy/admin/hints.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/icons.scss +1 -1
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/image_library.scss +21 -61
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/images.scss +1 -1
- data/app/stylesheets/alchemy/admin/labels.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/lists.scss +3 -3
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/navigation.scss +55 -59
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/node-select.scss +1 -10
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/nodes.scss +21 -18
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/notices.scss +20 -19
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/page-select.scss +18 -2
- data/app/stylesheets/alchemy/admin/pagination.scss +137 -0
- data/app/stylesheets/alchemy/admin/preview_window.scss +46 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/print.scss +1 -1
- data/app/stylesheets/alchemy/admin/resource_info.scss +148 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/search.scss +10 -7
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/selects.scss +85 -46
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/shoelace.scss +37 -68
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/sitemap.scss +39 -34
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/tables.scss +9 -7
- data/app/stylesheets/alchemy/admin/tags.scss +143 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/toolbar.scss +6 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/typography.scss +3 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/upload.scss +7 -5
- data/app/stylesheets/alchemy/admin.scss +44 -0
- data/app/stylesheets/alchemy/dark-theme.scss +5 -0
- data/app/stylesheets/alchemy/light-theme.scss +6 -0
- data/app/stylesheets/alchemy/theme.scss +13 -0
- data/app/stylesheets/alchemy/welcome.scss +75 -0
- data/app/stylesheets/tinymce/skins/content/alchemy/content.scss +69 -0
- data/app/{assets/stylesheets/tinymce/skins/content/alchemy → stylesheets/tinymce/skins/content/alchemy-dark}/content.scss +12 -12
- data/app/stylesheets/tinymce/skins/ui/alchemy/content.scss +1 -0
- data/app/{assets/stylesheets → stylesheets}/tinymce/skins/ui/alchemy/skin.scss +158 -176
- data/app/stylesheets/tinymce/skins/ui/alchemy-dark/content.scss +1 -0
- data/app/stylesheets/tinymce/skins/ui/alchemy-dark/skin.scss +3784 -0
- data/app/views/alchemy/admin/attachments/_files_list.html.erb +22 -12
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/assign.js.erb +4 -3
- data/app/views/alchemy/admin/attachments/show.html.erb +55 -43
- data/app/views/alchemy/admin/{elements/_clipboard_button.html.erb → clipboard/_button.html.erb} +3 -5
- data/app/views/alchemy/admin/clipboard/_update_nested_element_button.turbo_stream.erb +11 -0
- data/app/views/alchemy/admin/clipboard/clear.turbo_stream.erb +4 -0
- data/app/views/alchemy/admin/clipboard/index.html.erb +15 -13
- data/app/views/alchemy/admin/clipboard/insert.turbo_stream.erb +18 -0
- data/app/views/alchemy/admin/clipboard/remove.turbo_stream.erb +9 -0
- data/app/views/alchemy/admin/crop.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/info.html.erb +17 -31
- data/app/views/alchemy/admin/elements/_element.html.erb +4 -8
- data/app/views/alchemy/admin/elements/_form.html.erb +9 -9
- data/app/views/alchemy/admin/elements/_header.html.erb +5 -1
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +4 -6
- data/app/views/alchemy/admin/elements/create.turbo_stream.erb +2 -1
- data/app/views/alchemy/admin/elements/index.html.erb +2 -2
- data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +3 -16
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +0 -9
- data/app/views/alchemy/admin/languages/_form.html.erb +1 -1
- data/app/views/alchemy/admin/languages/_table.html.erb +1 -1
- data/app/views/alchemy/admin/languages/index.html.erb +5 -2
- data/app/views/alchemy/admin/layoutpages/index.html.erb +1 -12
- data/app/views/alchemy/admin/pages/_form.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_page.html.erb +2 -3
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +1 -15
- data/app/views/alchemy/admin/pages/index.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +9 -12
- data/app/views/alchemy/admin/partials/_search_form.html.erb +4 -9
- data/app/views/alchemy/admin/pictures/_archive.html.erb +16 -29
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +3 -7
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_form.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_infos.html.erb +21 -52
- data/app/views/alchemy/admin/pictures/_library_sidebar.html.erb +7 -0
- data/app/views/alchemy/admin/pictures/_picture.html.erb +14 -20
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +20 -16
- data/app/views/alchemy/admin/pictures/_sorting_select.html.erb +13 -0
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +1 -6
- data/app/views/alchemy/admin/pictures/index.html.erb +5 -19
- data/app/views/alchemy/admin/pictures/show.html.erb +10 -5
- data/app/views/alchemy/admin/resources/_applied_filters.html.erb +8 -0
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +5 -25
- data/app/views/alchemy/admin/resources/_pagination.html.erb +6 -0
- data/app/views/alchemy/admin/resources/_per_page_select.html.erb +4 -2
- data/app/views/alchemy/admin/resources/_resource_table.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_resource_usage_info.html.erb +36 -0
- data/app/views/alchemy/admin/resources/_table_header.html.erb +1 -15
- data/app/views/alchemy/admin/sites/index.html.erb +5 -1
- data/app/views/alchemy/admin/styleguide/index.html.erb +118 -58
- data/app/views/alchemy/admin/tags/index.html.erb +1 -1
- data/app/views/alchemy/admin/tinymce/_setup.html.erb +7 -7
- data/app/{javascript/alchemy_admin/locales/en.js → views/alchemy/admin/translations/_en.js} +5 -2
- data/app/views/alchemy/admin/uploader/_button.html.erb +1 -1
- data/app/views/alchemy/admin/uploader/_setup.html.erb +4 -4
- data/app/views/alchemy/base/error_notice.html.erb +1 -1
- data/app/views/alchemy/ingredients/_number_editor.html.erb +24 -0
- data/app/views/alchemy/no_index.html.erb +31 -0
- data/app/views/alchemy/welcome.html.erb +12 -10
- data/app/views/kaminari/alchemy/_first_page.html.erb +5 -3
- data/app/views/kaminari/alchemy/_last_page.html.erb +5 -3
- data/app/views/kaminari/alchemy/_next_page.html.erb +5 -3
- data/app/views/kaminari/alchemy/_paginator.html.erb +18 -13
- data/app/views/kaminari/alchemy/_prev_page.html.erb +5 -3
- data/app/views/layouts/alchemy/admin.html.erb +25 -24
- data/config/alchemy/config.yml +3 -2
- data/config/initializers/dragonfly.rb +0 -1
- data/config/initializers/mime_types.rb +1 -0
- data/config/locales/alchemy.en.yml +57 -21
- data/config/routes.rb +0 -2
- data/db/migrate/20250905140323_add_created_at_index_to_pictures_and_attachments.rb +14 -0
- data/lib/alchemy/admin/preview_url.rb +4 -5
- data/lib/alchemy/cache_digests/template_tracker.rb +6 -9
- data/lib/alchemy/config_missing.rb +14 -0
- data/lib/alchemy/configuration/base_option.rb +24 -0
- data/lib/alchemy/configuration/boolean_option.rb +16 -0
- data/lib/alchemy/configuration/class_option.rb +15 -0
- data/lib/alchemy/configuration/class_set_option.rb +46 -0
- data/lib/alchemy/configuration/integer_list_option.rb +13 -0
- data/lib/alchemy/configuration/integer_option.rb +12 -0
- data/lib/alchemy/configuration/list_option.rb +22 -0
- data/lib/alchemy/configuration/regexp_option.rb +11 -0
- data/lib/alchemy/configuration/string_list_option.rb +13 -0
- data/lib/alchemy/configuration/string_option.rb +11 -0
- data/lib/alchemy/configuration.rb +115 -0
- data/lib/alchemy/configuration_methods.rb +3 -1
- data/lib/alchemy/configurations/default_language.rb +12 -0
- data/lib/alchemy/configurations/default_site.rb +10 -0
- data/lib/alchemy/configurations/format_matchers.rb +11 -0
- data/lib/alchemy/configurations/mailer.rb +16 -0
- data/lib/alchemy/configurations/main.rb +223 -0
- data/lib/alchemy/configurations/page_cache.rb +19 -0
- data/lib/alchemy/configurations/preview.rb +32 -0
- data/lib/alchemy/configurations/sitemap.rb +10 -0
- data/lib/alchemy/configurations/uploader.rb +34 -0
- data/lib/alchemy/engine.rb +81 -24
- data/lib/alchemy/hints.rb +3 -7
- data/lib/alchemy/install/tasks.rb +0 -12
- data/lib/alchemy/on_page_layout.rb +2 -2
- data/lib/alchemy/propshaft/tinymce_asset.rb +15 -0
- data/lib/alchemy/seeder.rb +2 -2
- data/lib/alchemy/tasks/tidy.rb +18 -0
- data/lib/alchemy/tasks/usage.rb +4 -4
- data/lib/alchemy/test_support/config_stubbing.rb +1 -7
- data/lib/alchemy/test_support/factories/attachment_factory.rb +13 -2
- data/lib/alchemy/test_support/factories/language_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/page_factory.rb +2 -3
- data/lib/alchemy/test_support/factories/picture_factory.rb +31 -2
- data/lib/alchemy/test_support/factories/site_factory.rb +2 -2
- data/lib/alchemy/test_support/having_crop_action_examples.rb +2 -2
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +80 -26
- data/lib/alchemy/test_support/relatable_resource_examples.rb +58 -0
- data/lib/alchemy/test_support/shared_ingredient_examples.rb +5 -5
- data/lib/alchemy/tinymce.rb +0 -1
- data/lib/alchemy/upgrader/eight_zero.rb +14 -0
- data/lib/alchemy/upgrader.rb +33 -20
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +185 -172
- data/lib/alchemy_cms.rb +1 -7
- data/lib/generators/alchemy/ingredient/ingredient_generator.rb +0 -3
- data/lib/generators/alchemy/install/files/_article.html.erb +6 -4
- data/lib/generators/alchemy/install/files/alchemy.en.yml +22 -3
- data/lib/generators/alchemy/install/files/application.html.erb +5 -0
- data/lib/generators/alchemy/install/install_generator.rb +25 -23
- data/lib/generators/alchemy/install/templates/alchemy.rb.tt +200 -0
- data/lib/generators/alchemy/install/templates/dragonfly.rb.tt +0 -1
- data/lib/generators/alchemy/install/templates/elements.yml.tt +3 -1
- data/lib/generators/alchemy/install/templates/menus.yml.tt +1 -1
- data/lib/generators/alchemy/install/templates/page_layouts.yml.tt +2 -2
- data/lib/generators/alchemy/page_layouts/page_layouts_generator.rb +2 -2
- data/lib/tasks/alchemy/assets.rake +14 -0
- data/lib/tasks/alchemy/tidy.rake +6 -0
- data/lib/tasks/alchemy/upgrade.rake +12 -47
- data/vendor/assets/stylesheets/tinymce/skins/content/dark/content.min.css +1 -0
- data/vendor/assets/stylesheets/tinymce/skins/content/default/content.min.css +1 -0
- data/vendor/assets/stylesheets/tinymce/skins/ui/oxide/skin.min.css +1 -0
- data/vendor/assets/stylesheets/tinymce/skins/ui/oxide-dark/content.min.css +1 -0
- data/vendor/assets/stylesheets/tinymce/skins/ui/oxide-dark/skin.min.css +1 -0
- data/vendor/javascript/clipboard.min.js +1 -1
- data/vendor/javascript/cropperjs.min.js +1 -1
- data/vendor/javascript/handlebars.min.js +3 -3
- data/vendor/javascript/jquery.min.js +1 -1
- data/vendor/javascript/select2.min.js +3 -3
- data/vendor/javascript/shoelace.min.js +92 -76
- data/vendor/javascript/sortable.min.js +2 -2
- data/vendor/javascript/tinymce.min.js +1 -1
- data/vendor/javascript/ungap-custom-elements.min.js +2 -2
- metadata +223 -208
- data/CHANGELOG.md +0 -2041
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -73
- data/Gemfile +0 -71
- data/Rakefile +0 -102
- data/SECURITY.md +0 -13
- data/alchemy_cms.gemspec +0 -88
- data/app/assets/builds/alchemy/admin/page-select.css.map +0 -1
- data/app/assets/builds/alchemy/admin/print.css.map +0 -1
- data/app/assets/builds/alchemy/admin.css.map +0 -1
- data/app/assets/builds/alchemy/custom-properties.css +0 -1
- data/app/assets/builds/alchemy/custom-properties.css.map +0 -1
- data/app/assets/builds/alchemy/welcome.css.map +0 -1
- data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css.map +0 -1
- data/app/assets/builds/tinymce/skins/ui/alchemy/skin.min.css.map +0 -1
- data/app/assets/javascripts/alchemy/admin.js +0 -10
- data/app/assets/stylesheets/alchemy/_defaults.scss +0 -3
- data/app/assets/stylesheets/alchemy/_deprecated_variables.scss +0 -45
- data/app/assets/stylesheets/alchemy/_deprecation.scss +0 -17
- data/app/assets/stylesheets/alchemy/_extends.scss +0 -62
- data/app/assets/stylesheets/alchemy/_variables.scss +0 -201
- data/app/assets/stylesheets/alchemy/admin/attachments.scss +0 -40
- data/app/assets/stylesheets/alchemy/admin/buttons.scss +0 -123
- data/app/assets/stylesheets/alchemy/admin/hints.scss +0 -5
- data/app/assets/stylesheets/alchemy/admin/labels.scss +0 -3
- data/app/assets/stylesheets/alchemy/admin/pagination.scss +0 -92
- data/app/assets/stylesheets/alchemy/admin/preview_window.scss +0 -33
- data/app/assets/stylesheets/alchemy/admin/resource_info.scss +0 -42
- data/app/assets/stylesheets/alchemy/admin/tags.scss +0 -158
- data/app/assets/stylesheets/alchemy/admin.scss +0 -42
- data/app/assets/stylesheets/alchemy/custom-properties.css +0 -98
- data/app/assets/stylesheets/alchemy/welcome.scss +0 -57
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.css +0 -711
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.css +0 -705
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.min.css +0 -7
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.min.css +0 -7
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.css +0 -29
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.min.css +0 -7
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.css +0 -677
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.min.css +0 -7
- data/app/controllers/alchemy/elements_controller.rb +0 -32
- data/app/helpers/alchemy/admin/elements_helper.rb +0 -25
- data/app/models/alchemy/element/dom_id.rb +0 -31
- data/app/models/alchemy/picture/calculations.rb +0 -49
- data/app/models/alchemy/picture/transformations.rb +0 -115
- data/app/models/alchemy/picture/url.rb +0 -54
- data/app/views/alchemy/admin/attachments/destroy.js.erb +0 -1
- data/app/views/alchemy/admin/clipboard/clear.js.erb +0 -3
- data/app/views/alchemy/admin/clipboard/insert.js.erb +0 -29
- data/app/views/alchemy/admin/clipboard/remove.js.erb +0 -10
- data/app/views/alchemy/admin/resources/_filter.html.erb +0 -12
- data/app/views/alchemy/admin/resources/_resource.html.erb +0 -34
- data/app/views/alchemy/admin/resources/_table.html.erb +0 -29
- data/app/views/alchemy/elements/show.html.erb +0 -1
- data/app/views/alchemy/elements/show.js.erb +0 -1
- data/app/views/alchemy/ingredients/_audio_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_boolean_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_datetime_view.html.erb +0 -3
- data/app/views/alchemy/ingredients/_file_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_headline_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_html_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_link_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_node_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_page_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_picture_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_richtext_view.html.erb +0 -3
- data/app/views/alchemy/ingredients/_select_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_text_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_video_view.html.erb +0 -3
- data/babel.config.js +0 -12
- data/bin/importmap +0 -4
- data/bin/rails +0 -9
- data/bin/rspec +0 -3
- data/bin/setup +0 -30
- data/bin/start +0 -17
- data/bun.lockb +0 -0
- data/bundles/shoelace.js +0 -12
- data/bundles/tinymce.js +0 -22
- data/config/initializers/assets.rb +0 -4
- data/eslint.config.js +0 -17
- data/lib/alchemy/config.rb +0 -114
- data/lib/alchemy/element_definition.rb +0 -73
- data/lib/alchemy/page_layout.rb +0 -73
- data/lib/alchemy/resource_filter.rb +0 -40
- data/lib/alchemy/upgrader/seven_point_four.rb +0 -26
- data/lib/alchemy/upgrader/seven_point_three.rb +0 -52
- data/lib/alchemy/upgrader/tasks/.keep +0 -0
- data/lib/generators/alchemy/ingredient/templates/view.html.erb +0 -1
- data/lib/generators/alchemy/install/files/alchemy_admin.js +0 -1
- data/lib/generators/alchemy/install/files/all.js +0 -11
- data/lib/generators/alchemy/install/files/article.css +0 -25
- data/rollup.config.mjs +0 -108
- data/vendor/assets/images/remixicon.symbol.svg +0 -11
- /data/app/{assets/stylesheets → stylesheets}/alchemy/_fonts.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/attachment-select.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/flash.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/list_filter.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/spinner.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/tinymce/skins/skintool.json +0 -0
- /data/app/{assets/stylesheets → stylesheets}/tinymce/skins/ui/alchemy/fonts/tinymce-mobile.woff +0 -0
@@ -4,13 +4,13 @@ module Alchemy
|
|
4
4
|
class Page < BaseRecord
|
5
5
|
# Module concerning page layouts
|
6
6
|
#
|
7
|
-
module
|
7
|
+
module Definitions
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
10
|
module ClassMethods
|
11
11
|
# Register a custom page layouts repository
|
12
12
|
#
|
13
|
-
# The default repository is Alchemy::
|
13
|
+
# The default repository is Alchemy::PageDefinition
|
14
14
|
#
|
15
15
|
def layouts_repository=(klass)
|
16
16
|
@_layouts_repository = klass
|
@@ -19,8 +19,10 @@ module Alchemy
|
|
19
19
|
# Returns page layouts ready for Rails' select form helper.
|
20
20
|
#
|
21
21
|
def layouts_for_select(language_id, layoutpages: false)
|
22
|
-
|
23
|
-
|
22
|
+
layouts = selectable_layouts(language_id, layoutpages: layoutpages)
|
23
|
+
layouts.map do |layout|
|
24
|
+
[layout.human_name, layout.name]
|
25
|
+
end
|
24
26
|
end
|
25
27
|
|
26
28
|
# Returns all layouts that can be used for creating a new page.
|
@@ -36,9 +38,9 @@ module Alchemy
|
|
36
38
|
@language_id = language_id
|
37
39
|
layouts_repository.all.select do |layout|
|
38
40
|
if layoutpages
|
39
|
-
layout
|
41
|
+
layout.layoutpage && layout_available?(layout)
|
40
42
|
else
|
41
|
-
!layout
|
43
|
+
!layout.layoutpage && layout_available?(layout)
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
@@ -62,28 +64,19 @@ module Alchemy
|
|
62
64
|
private
|
63
65
|
|
64
66
|
def layouts_repository
|
65
|
-
@_layouts_repository ||=
|
66
|
-
end
|
67
|
-
|
68
|
-
# Maps given layouts for Rails select form helper.
|
69
|
-
#
|
70
|
-
def mapped_layouts_for_select(layouts)
|
71
|
-
layouts.each do |layout|
|
72
|
-
@map_array << [human_layout_name(layout["name"]), layout["name"]]
|
73
|
-
end
|
74
|
-
@map_array
|
67
|
+
@_layouts_repository ||= PageDefinition
|
75
68
|
end
|
76
69
|
|
77
70
|
# Returns true if the given layout is unique and not already taken or it should be hidden.
|
78
71
|
#
|
79
72
|
def layout_available?(layout)
|
80
|
-
!layout
|
73
|
+
!layout.hide && !already_taken?(layout) && available_on_site?(layout)
|
81
74
|
end
|
82
75
|
|
83
76
|
# Returns true if this layout is unique and already taken by another page.
|
84
77
|
#
|
85
78
|
def already_taken?(layout)
|
86
|
-
layout
|
79
|
+
layout.unique && page_with_layout_existing?(layout.name)
|
87
80
|
end
|
88
81
|
|
89
82
|
# Returns true if one page already has the given layout
|
@@ -106,7 +99,7 @@ module Alchemy
|
|
106
99
|
return false unless Alchemy::Current.site
|
107
100
|
|
108
101
|
Alchemy::Current.site.definition.blank? ||
|
109
|
-
Alchemy::Current.site.definition.fetch("page_layouts", []).include?(layout
|
102
|
+
Alchemy::Current.site.definition.fetch("page_layouts", []).include?(layout.name)
|
110
103
|
end
|
111
104
|
end
|
112
105
|
end
|
@@ -81,8 +81,8 @@ module Alchemy
|
|
81
81
|
#
|
82
82
|
def available_element_definitions(only_element_named = nil)
|
83
83
|
@_available_element_definitions ||= if only_element_named
|
84
|
-
|
85
|
-
element_definitions_by_name(
|
84
|
+
element_definition = Element.definition_by_name(only_element_named)
|
85
|
+
element_definitions_by_name(element_definition.nestable_elements)
|
86
86
|
else
|
87
87
|
element_definitions.dup
|
88
88
|
end
|
@@ -100,7 +100,7 @@ module Alchemy
|
|
100
100
|
# All names of elements that can actually be placed on current page.
|
101
101
|
#
|
102
102
|
def available_element_names
|
103
|
-
@_available_element_names ||= available_element_definitions.map
|
103
|
+
@_available_element_names ||= available_element_definitions.map(&:name)
|
104
104
|
end
|
105
105
|
|
106
106
|
# Available element definitions excluding nested unique elements.
|
@@ -109,7 +109,7 @@ module Alchemy
|
|
109
109
|
@_available_elements = if parent
|
110
110
|
parents_unique_nested_elements = parent.nested_elements.where(unique: true).pluck(:name)
|
111
111
|
available_element_definitions(parent.name).reject do |e|
|
112
|
-
parents_unique_nested_elements.include?
|
112
|
+
parents_unique_nested_elements.include?(e.name)
|
113
113
|
end
|
114
114
|
else
|
115
115
|
available_element_definitions
|
@@ -129,10 +129,9 @@ module Alchemy
|
|
129
129
|
#
|
130
130
|
def descendent_element_definitions
|
131
131
|
definitions = element_definitions_by_name(element_definition_names)
|
132
|
-
definitions.select {
|
133
|
-
|
134
|
-
end
|
135
|
-
definitions.uniq { |d| d["name"] }
|
132
|
+
definitions.select { _1.nestable_elements.any? }.flat_map do |d|
|
133
|
+
element_definitions_by_name(d.nestable_elements)
|
134
|
+
end.uniq(&:name)
|
136
135
|
end
|
137
136
|
|
138
137
|
# All names of elements that are defined in the page definition.
|
@@ -145,7 +144,7 @@ module Alchemy
|
|
145
144
|
# elements: [headline, contactform]
|
146
145
|
#
|
147
146
|
def element_definition_names
|
148
|
-
definition
|
147
|
+
definition.elements || []
|
149
148
|
end
|
150
149
|
|
151
150
|
# Element definitions with given name(s)
|
@@ -161,7 +160,7 @@ module Alchemy
|
|
161
160
|
if names.to_s == "all"
|
162
161
|
Element.definitions
|
163
162
|
else
|
164
|
-
Element.definitions.select {
|
163
|
+
Element.definitions.select { names.include?(_1.name) }
|
165
164
|
end
|
166
165
|
end
|
167
166
|
|
@@ -181,7 +180,7 @@ module Alchemy
|
|
181
180
|
# And if so, it generates them.
|
182
181
|
#
|
183
182
|
def generate_elements
|
184
|
-
definition.
|
183
|
+
definition.autogenerate&.each do |element_name|
|
185
184
|
Element.create(page: self, page_version: draft_version, name: element_name)
|
186
185
|
end
|
187
186
|
end
|
@@ -190,7 +189,7 @@ module Alchemy
|
|
190
189
|
#
|
191
190
|
def delete_unique_element_definitions!
|
192
191
|
@_available_element_definitions.delete_if do |element|
|
193
|
-
element
|
192
|
+
element.unique && @_existing_element_names.include?(element.name)
|
194
193
|
end
|
195
194
|
end
|
196
195
|
|
@@ -198,8 +197,8 @@ module Alchemy
|
|
198
197
|
#
|
199
198
|
def delete_outnumbered_element_definitions!
|
200
199
|
@_available_element_definitions.delete_if do |element|
|
201
|
-
outnumbered = @_existing_element_names.select { |name| name == element
|
202
|
-
element
|
200
|
+
outnumbered = @_existing_element_names.select { |name| name == element.name }
|
201
|
+
element.amount && outnumbered.count >= element.amount
|
203
202
|
end
|
204
203
|
end
|
205
204
|
end
|
@@ -17,8 +17,7 @@ module Alchemy
|
|
17
17
|
presence: true, uniqueness: {scope: [:parent_id], case_sensitive: false, unless: -> { parent_id.nil? }}
|
18
18
|
validates :urlname,
|
19
19
|
uniqueness: {scope: [:language_id, :layoutpage], if: -> { urlname.present? }, case_sensitive: false},
|
20
|
-
exclusion: {in: RESERVED_URLNAMES}
|
21
|
-
length: {minimum: 3, if: -> { urlname.present? }}
|
20
|
+
exclusion: {in: RESERVED_URLNAMES}
|
22
21
|
|
23
22
|
before_save :set_title,
|
24
23
|
if: -> { title.blank? }
|
@@ -74,17 +73,10 @@ module Alchemy
|
|
74
73
|
self[:title] = name
|
75
74
|
end
|
76
75
|
|
77
|
-
#
|
76
|
+
# Returns the full nested urlname.
|
78
77
|
#
|
79
|
-
# Names shorter than 3 will be filled up with dashes,
|
80
|
-
# so it does not collidate with the language code.
|
81
|
-
#
|
82
|
-
def converted_url_name
|
83
|
-
url_name = convert_to_urlname(slug.blank? ? name : slug)
|
84
|
-
url_name.rjust(3, "-")
|
85
|
-
end
|
86
|
-
|
87
78
|
def nested_url_name
|
79
|
+
converted_url_name = convert_to_urlname(slug.blank? ? name : slug)
|
88
80
|
if parent&.language_root?
|
89
81
|
converted_url_name
|
90
82
|
else
|
@@ -13,8 +13,21 @@ module Alchemy
|
|
13
13
|
language.public? && !!public_version&.public?
|
14
14
|
end
|
15
15
|
|
16
|
+
# Cache-Control max-age duration in seconds.
|
17
|
+
#
|
18
|
+
# You can set this via the `ALCHEMY_PAGE_CACHE_MAX_AGE` environment variable,
|
19
|
+
# in the `Alchemy.config.page_cache_max_age` configuration option,
|
20
|
+
# or in the pages definition in `config/alchemy/page_layouts.yml` file.
|
21
|
+
#
|
22
|
+
# Defaults to 600 seconds.
|
16
23
|
def expiration_time
|
17
|
-
|
24
|
+
return 0 unless cache_page?
|
25
|
+
|
26
|
+
if definition.cache.to_s.match?(/\d+/)
|
27
|
+
definition.cache.to_i
|
28
|
+
else
|
29
|
+
Alchemy.config.page_cache.max_age
|
30
|
+
end
|
18
31
|
end
|
19
32
|
|
20
33
|
def rootpage?
|
@@ -38,13 +51,13 @@ module Alchemy
|
|
38
51
|
# @returns Array
|
39
52
|
#
|
40
53
|
def has_limited_editors?
|
41
|
-
definition
|
54
|
+
definition.editable_by.present?
|
42
55
|
end
|
43
56
|
|
44
57
|
def editor_roles
|
45
58
|
return unless has_limited_editors?
|
46
59
|
|
47
|
-
definition
|
60
|
+
definition.editable_by
|
48
61
|
end
|
49
62
|
|
50
63
|
# True if page locked_at timestamp and locked_by id are set
|
@@ -80,10 +93,10 @@ module Alchemy
|
|
80
93
|
|
81
94
|
# Returns the self#page_layout definition from config/alchemy/page_layouts.yml file.
|
82
95
|
def definition
|
83
|
-
definition =
|
96
|
+
definition = PageDefinition.get(page_layout)
|
84
97
|
if definition.nil?
|
85
98
|
log_warning "Page definition for `#{page_layout}` not found. Please check `page_layouts.yml` file."
|
86
|
-
return
|
99
|
+
return PageDefinition.new
|
87
100
|
end
|
88
101
|
definition
|
89
102
|
end
|
@@ -144,17 +157,9 @@ module Alchemy
|
|
144
157
|
# @returns Boolean
|
145
158
|
#
|
146
159
|
def cache_page?
|
147
|
-
return false
|
148
|
-
|
149
|
-
page_layout = PageLayout.get(self.page_layout)
|
150
|
-
page_layout["cache"] != false && page_layout["searchresults"] != true
|
151
|
-
end
|
152
|
-
|
153
|
-
private
|
160
|
+
return false if !public? || restricted?
|
154
161
|
|
155
|
-
|
156
|
-
Alchemy::Config.get(:cache_pages) &&
|
157
|
-
Rails.application.config.action_controller.perform_caching
|
162
|
+
definition.cache != false && definition.searchresults != true
|
158
163
|
end
|
159
164
|
end
|
160
165
|
end
|
@@ -124,7 +124,7 @@ module Alchemy
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def ransackable_scopes(_auth_object)
|
127
|
-
[:published, :contentpages, :from_current_site, :searchables, :layoutpages]
|
127
|
+
[:published, :not_public, :restricted, :contentpages, :from_current_site, :searchables, :layoutpages, :by_page_layout]
|
128
128
|
end
|
129
129
|
end
|
130
130
|
end
|
data/app/models/alchemy/page.rb
CHANGED
@@ -36,7 +36,7 @@
|
|
36
36
|
#
|
37
37
|
|
38
38
|
require_dependency "alchemy/page/fixed_attributes"
|
39
|
-
require_dependency "alchemy/page/
|
39
|
+
require_dependency "alchemy/page/definitions"
|
40
40
|
require_dependency "alchemy/page/page_scopes"
|
41
41
|
require_dependency "alchemy/page/page_natures"
|
42
42
|
require_dependency "alchemy/page/page_naming"
|
@@ -44,7 +44,6 @@ require_dependency "alchemy/page/page_elements"
|
|
44
44
|
|
45
45
|
module Alchemy
|
46
46
|
class Page < BaseRecord
|
47
|
-
include Alchemy::Hints
|
48
47
|
include Alchemy::Logger
|
49
48
|
include Alchemy::Taggable
|
50
49
|
|
@@ -90,7 +89,7 @@ module Alchemy
|
|
90
89
|
|
91
90
|
acts_as_nested_set(dependent: :destroy, scope: [:layoutpage, :language_id])
|
92
91
|
|
93
|
-
stampable stamper_class_name: Alchemy.
|
92
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
94
93
|
|
95
94
|
belongs_to :language
|
96
95
|
|
@@ -116,7 +115,7 @@ module Alchemy
|
|
116
115
|
has_many :site_languages, through: :site, source: :languages
|
117
116
|
has_many :folded_pages, dependent: :destroy
|
118
117
|
has_many :legacy_urls, class_name: "Alchemy::LegacyPageUrl", dependent: :destroy
|
119
|
-
has_many :nodes, class_name: "Alchemy::Node", inverse_of: :page
|
118
|
+
has_many :nodes, class_name: "Alchemy::Node", inverse_of: :page, dependent: :restrict_with_error
|
120
119
|
has_many :versions, class_name: "Alchemy::PageVersion", inverse_of: :page, dependent: :destroy
|
121
120
|
has_one :draft_version, -> { drafts }, class_name: "Alchemy::PageVersion"
|
122
121
|
has_one :public_version, -> { published }, class_name: "Alchemy::PageVersion", autosave: -> { persisted? }
|
@@ -133,11 +132,6 @@ module Alchemy
|
|
133
132
|
before_create -> { versions.build },
|
134
133
|
if: -> { versions.none? }
|
135
134
|
|
136
|
-
before_destroy if: -> { nodes.any? } do
|
137
|
-
errors.add(:nodes, :still_present)
|
138
|
-
throw(:abort)
|
139
|
-
end
|
140
|
-
|
141
135
|
before_save :set_language_code,
|
142
136
|
if: -> { language.present? }
|
143
137
|
|
@@ -156,7 +150,7 @@ module Alchemy
|
|
156
150
|
after_update :touch_nodes
|
157
151
|
|
158
152
|
# Concerns
|
159
|
-
include
|
153
|
+
include Definitions
|
160
154
|
include PageScopes
|
161
155
|
include PageNatures
|
162
156
|
include PageNaming
|
@@ -164,6 +158,7 @@ module Alchemy
|
|
164
158
|
|
165
159
|
# site_name accessor
|
166
160
|
delegate :name, to: :site, prefix: true, allow_nil: true
|
161
|
+
delegate :has_hint?, :hint, to: :definition
|
167
162
|
|
168
163
|
# Class methods
|
169
164
|
#
|
@@ -183,37 +178,10 @@ module Alchemy
|
|
183
178
|
@_url_path_class = klass
|
184
179
|
end
|
185
180
|
|
186
|
-
def alchemy_resource_filters
|
187
|
-
[
|
188
|
-
{
|
189
|
-
name: :by_page_layout,
|
190
|
-
values: PageLayout.all.map { |p| [Alchemy.t(p["name"], scope: "page_layout_names"), p["name"]] }
|
191
|
-
},
|
192
|
-
{
|
193
|
-
name: :status,
|
194
|
-
values: %w[published not_public restricted]
|
195
|
-
}
|
196
|
-
]
|
197
|
-
end
|
198
|
-
|
199
181
|
def searchable_alchemy_resource_attributes
|
200
182
|
%w[name urlname title]
|
201
183
|
end
|
202
184
|
|
203
|
-
# Used to store the current page previewed in the edit page template.
|
204
|
-
# @deprecated Use {Alchemy::Current#preview_page=} instead.
|
205
|
-
def current_preview=(page)
|
206
|
-
Current.preview_page = page
|
207
|
-
end
|
208
|
-
deprecate "current_preview=": :"Alchemy::Current.preview_page=", deprecator: Alchemy::Deprecation
|
209
|
-
|
210
|
-
# Returns the current page previewed in the edit page template.
|
211
|
-
# @deprecated Use {Alchemy::Current#preview_page} instead.
|
212
|
-
def current_preview
|
213
|
-
Current.preview_page
|
214
|
-
end
|
215
|
-
deprecate current_preview: :"Alchemy::Current.preview_page", deprecator: Alchemy::Deprecation
|
216
|
-
|
217
185
|
# @return the language root page for given language id.
|
218
186
|
# @param language_id [Fixnum]
|
219
187
|
#
|
@@ -265,13 +233,13 @@ module Alchemy
|
|
265
233
|
|
266
234
|
clipboard_pages = all_from_clipboard(clipboard)
|
267
235
|
allowed_page_layouts = Alchemy::Page.selectable_layouts(language_id, layoutpages: layoutpages)
|
268
|
-
allowed_page_layout_names = allowed_page_layouts.collect
|
236
|
+
allowed_page_layout_names = allowed_page_layouts.collect(&:name)
|
269
237
|
clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) }
|
270
238
|
end
|
271
239
|
|
272
240
|
def link_target_options
|
273
241
|
options = [[Alchemy.t(:default, scope: "link_target_options"), ""]]
|
274
|
-
link_target_options =
|
242
|
+
link_target_options = Alchemy.config.link_target_options
|
275
243
|
link_target_options.each do |option|
|
276
244
|
# add an underscore to the options to provide the default syntax
|
277
245
|
# @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target
|
@@ -280,6 +248,11 @@ module Alchemy
|
|
280
248
|
end
|
281
249
|
options
|
282
250
|
end
|
251
|
+
|
252
|
+
# Allow all string and text attributes to be searchable by Ransack.
|
253
|
+
def ransackable_attributes(_auth_object = nil)
|
254
|
+
searchable_alchemy_resource_attributes + ["updated_at"]
|
255
|
+
end
|
283
256
|
end
|
284
257
|
|
285
258
|
# Instance methods
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
class PageDefinition
|
5
|
+
include ActiveModel::Model
|
6
|
+
include ActiveModel::Attributes
|
7
|
+
include Alchemy::Hints
|
8
|
+
|
9
|
+
extend ActiveModel::Translation
|
10
|
+
|
11
|
+
attribute :name, :string
|
12
|
+
attribute :elements, default: []
|
13
|
+
attribute :autogenerate, default: []
|
14
|
+
attribute :layoutpage, :boolean, default: false
|
15
|
+
attribute :unique, :boolean, default: false
|
16
|
+
attribute :cache, default: true
|
17
|
+
attribute :insert_elements_at, :string, default: "bottom"
|
18
|
+
attribute :fixed_attributes, default: {}
|
19
|
+
attribute :searchable, :boolean, default: true
|
20
|
+
attribute :searchresults, :boolean, default: false
|
21
|
+
attribute :hide, :boolean, default: false
|
22
|
+
attribute :editable_by
|
23
|
+
attribute :hint
|
24
|
+
|
25
|
+
validates :name,
|
26
|
+
presence: true,
|
27
|
+
format: {
|
28
|
+
with: /\A[a-z_-]+\z/
|
29
|
+
}
|
30
|
+
|
31
|
+
delegate :[], to: :attributes
|
32
|
+
delegate :blank?, to: :name
|
33
|
+
|
34
|
+
class << self
|
35
|
+
# Returns all page layouts.
|
36
|
+
#
|
37
|
+
# They are defined in +config/alchemy/page_layout.yml+ file.
|
38
|
+
#
|
39
|
+
def all
|
40
|
+
@definitions ||= read_definitions_file.map { new(**_1) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def map(...)
|
44
|
+
all.map(...)
|
45
|
+
end
|
46
|
+
alias_method :collect, :map
|
47
|
+
|
48
|
+
# Add additional page definitions to collection.
|
49
|
+
#
|
50
|
+
# Useful for extending the page layouts from an Alchemy module.
|
51
|
+
#
|
52
|
+
# === Usage Example
|
53
|
+
#
|
54
|
+
# Call +Alchemy::PageDefinition.add(your_definition)+ in your engine.rb file.
|
55
|
+
#
|
56
|
+
# @param [Array || Hash]
|
57
|
+
# You can pass a single layout definition as Hash, or a collection of page layouts as Array.
|
58
|
+
#
|
59
|
+
def add(definition)
|
60
|
+
all
|
61
|
+
@definitions += Array.wrap(definition).map { new(**_1) }
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns one page definition by given name.
|
65
|
+
#
|
66
|
+
def get(name)
|
67
|
+
return new if name.blank?
|
68
|
+
|
69
|
+
all.detect { _1.name.casecmp(name).zero? }
|
70
|
+
end
|
71
|
+
|
72
|
+
def reset!
|
73
|
+
@definitions = nil
|
74
|
+
end
|
75
|
+
|
76
|
+
# The absolute +page_layouts.yml+ file path
|
77
|
+
# @return [Pathname]
|
78
|
+
def layouts_file_path
|
79
|
+
Rails.root.join("config", "alchemy", "page_layouts.yml")
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Reads the layout definitions from +config/alchemy/page_layouts.yml+.
|
85
|
+
#
|
86
|
+
def read_definitions_file
|
87
|
+
if File.exist?(layouts_file_path)
|
88
|
+
Array.wrap(
|
89
|
+
YAML.safe_load(
|
90
|
+
ERB.new(File.read(layouts_file_path)).result,
|
91
|
+
permitted_classes: YAML_PERMITTED_CLASSES,
|
92
|
+
aliases: true
|
93
|
+
) || []
|
94
|
+
)
|
95
|
+
else
|
96
|
+
raise LoadError, "Could not find page_layouts.yml file! Please run `rails generate alchemy:install`"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def human_name
|
102
|
+
Alchemy::Page.human_layout_name(name)
|
103
|
+
end
|
104
|
+
|
105
|
+
def attributes
|
106
|
+
super.with_indifferent_access
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def hint_translation_scope
|
112
|
+
:page_hints
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|