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
@@ -89,6 +89,7 @@ en:
|
|
89
89
|
image/tiff: TIFF Image
|
90
90
|
image/x-psd: Photoshop File
|
91
91
|
image/svg+xml: SVG Image
|
92
|
+
image/webp: WebP Image
|
92
93
|
text/plain: Plain Text Document
|
93
94
|
text/x-vcard: vCard
|
94
95
|
video/mp4: MPEG-4 Video
|
@@ -104,41 +105,59 @@ en:
|
|
104
105
|
filters:
|
105
106
|
page:
|
106
107
|
by_page_layout:
|
108
|
+
all: All page types
|
107
109
|
name: Page Type
|
108
110
|
status:
|
111
|
+
all: Do not filter
|
109
112
|
name: Status
|
110
113
|
values:
|
111
114
|
not_public: Unpublished
|
112
115
|
published: Published
|
113
116
|
restricted: Restricted
|
117
|
+
not_public:
|
118
|
+
name: Unpublished
|
119
|
+
published:
|
120
|
+
name: Published
|
121
|
+
restricted:
|
122
|
+
name: Restricted
|
123
|
+
updated_at_lteq:
|
124
|
+
name: Updated before
|
125
|
+
updated_at_gteq:
|
126
|
+
name: Updated after
|
114
127
|
picture:
|
115
128
|
by_file_format:
|
129
|
+
all: Show all file types
|
116
130
|
name: File Type
|
117
131
|
values:
|
132
|
+
<<: *mime_types
|
118
133
|
gif: GIF Image
|
119
134
|
jpeg: JPG Image
|
120
135
|
png: PNG Image
|
121
136
|
svg: SVG Image
|
122
137
|
tiff: TIFF Image
|
123
138
|
webp: WebP Image
|
124
|
-
|
125
|
-
name:
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
139
|
+
last_upload:
|
140
|
+
name: Last upload only
|
141
|
+
recent:
|
142
|
+
name: Recently uploaded only
|
143
|
+
without_tag:
|
144
|
+
name: Without tag
|
145
|
+
deletable:
|
146
|
+
name: Not used
|
131
147
|
attachment:
|
132
148
|
by_file_type:
|
133
149
|
name: File Type
|
134
150
|
values:
|
135
151
|
<<: *mime_types
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
152
|
+
all: Show all file types
|
153
|
+
last_upload:
|
154
|
+
name: Last upload only
|
155
|
+
recent:
|
156
|
+
name: Recently uploaded only
|
157
|
+
without_tag:
|
158
|
+
name: Without tag
|
159
|
+
deletable:
|
160
|
+
name: Not used
|
142
161
|
|
143
162
|
default_ingredient_texts:
|
144
163
|
lorem: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
@@ -207,6 +226,11 @@ en:
|
|
207
226
|
elements:
|
208
227
|
toolbar:
|
209
228
|
hide: Hide
|
229
|
+
pictures:
|
230
|
+
sorting_select:
|
231
|
+
label: "Sorting"
|
232
|
+
by_latest: "Latest"
|
233
|
+
alphabetical: "A-Z"
|
210
234
|
add_nested_element: "Add %{name}"
|
211
235
|
anchor: "Anchor"
|
212
236
|
anchor_link_headline: You can link to an anchor from the current page.
|
@@ -316,7 +340,6 @@ en:
|
|
316
340
|
"Size": "Size"
|
317
341
|
"Successfully deleted element": "Successfully deleted %{element}"
|
318
342
|
"Tags": "Tags"
|
319
|
-
"These pictures could not be deleted, because they were in use": "These pictures could not be deleted, because they were in use: %{names}"
|
320
343
|
"This page is locked": "This page is currently locked by %{name}"
|
321
344
|
"Title": "Title"
|
322
345
|
"Trash": "Trash"
|
@@ -544,6 +567,7 @@ en:
|
|
544
567
|
password: "Password"
|
545
568
|
paste: "paste"
|
546
569
|
pictures_in_page: "%{page} in %{pictures}"
|
570
|
+
pictures_will_be_deleted_now: Pictures will be deleted now
|
547
571
|
place_link: "Add link"
|
548
572
|
player_version: "Flash Player version"
|
549
573
|
"please enter subject and mail address": "Please enter recipient and subject."
|
@@ -604,6 +628,12 @@ en:
|
|
604
628
|
tag_list: Tags
|
605
629
|
tags_get_created_if_used_the_first_time: "Tags get created if used the first time."
|
606
630
|
this_picture_is_used_on_these_pages: "This picture is used on following pages"
|
631
|
+
used_on_these_pages:
|
632
|
+
attachment: "This file is used on following pages"
|
633
|
+
picture: "This picture is used on following pages"
|
634
|
+
not_in_use_yet:
|
635
|
+
attachment: "This file is not in use yet."
|
636
|
+
picture: "This picture is not in use yet."
|
607
637
|
title: "Title"
|
608
638
|
to_alchemy: "To Alchemy"
|
609
639
|
unknown: "unknown"
|
@@ -681,7 +711,7 @@ en:
|
|
681
711
|
time:
|
682
712
|
formats:
|
683
713
|
alchemy:
|
684
|
-
default: "%m
|
714
|
+
default: "%Y-%m-%d %H:%M"
|
685
715
|
ingredient_date: "%Y-%m-%d"
|
686
716
|
page_status: "%m.%d.%Y %H:%M"
|
687
717
|
short_datetime: "%d %b %H:%M"
|
@@ -719,6 +749,7 @@ en:
|
|
719
749
|
attributes:
|
720
750
|
image_file:
|
721
751
|
blank: "Please attach a picture."
|
752
|
+
too_big: must not be larger than %{maximum}MB
|
722
753
|
alchemy/user:
|
723
754
|
attributes:
|
724
755
|
email:
|
@@ -755,16 +786,19 @@ en:
|
|
755
786
|
node_ingredients_present: "This menu item is in use inside an Alchemy element on the following pages: %{page_names}."
|
756
787
|
alchemy/site:
|
757
788
|
attributes:
|
758
|
-
|
759
|
-
|
789
|
+
base:
|
790
|
+
restrict_dependent_destroy:
|
791
|
+
has_many: "There are still %{record} attached to this site. Please remove them first."
|
760
792
|
alchemy/language:
|
761
793
|
attributes:
|
762
|
-
|
763
|
-
|
794
|
+
base:
|
795
|
+
restrict_dependent_destroy:
|
796
|
+
has_many: "There are still %{record} attached to this language. Please remove them first."
|
764
797
|
alchemy/page:
|
765
798
|
attributes:
|
766
|
-
|
767
|
-
|
799
|
+
base:
|
800
|
+
restrict_dependent_destroy:
|
801
|
+
has_many: "There are still %{record} attached to this page. Please remove them first."
|
768
802
|
models:
|
769
803
|
gutentag/tag:
|
770
804
|
one: Tag
|
@@ -851,6 +885,7 @@ en:
|
|
851
885
|
public: "Public"
|
852
886
|
locale: Localization
|
853
887
|
code: ISO Code
|
888
|
+
nodes: Menu nodes
|
854
889
|
alchemy/legacy_page_url:
|
855
890
|
urlname: "URL-Path"
|
856
891
|
alchemy/node:
|
@@ -869,6 +904,7 @@ en:
|
|
869
904
|
meta_description: "Description"
|
870
905
|
meta_keywords: "Keywords"
|
871
906
|
name: "Name"
|
907
|
+
nodes: "Menu nodes"
|
872
908
|
page_layout: "Page type"
|
873
909
|
public: "public"
|
874
910
|
restricted: "restricted"
|
data/config/routes.rb
CHANGED
@@ -68,7 +68,6 @@ Alchemy::Engine.routes.draw do
|
|
68
68
|
|
69
69
|
resources :attachments, except: [:new] do
|
70
70
|
member do
|
71
|
-
get :download
|
72
71
|
put :assign
|
73
72
|
end
|
74
73
|
end
|
@@ -114,7 +113,6 @@ Alchemy::Engine.routes.draw do
|
|
114
113
|
as: :show_attachment
|
115
114
|
|
116
115
|
resources :messages, only: [:index, :new, :create]
|
117
|
-
resources :elements, only: :show
|
118
116
|
|
119
117
|
namespace :api, defaults: {format: "json"} do
|
120
118
|
resources :attachments, only: [:index]
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class AddCreatedAtIndexToPicturesAndAttachments < ActiveRecord::Migration[7.1]
|
2
|
+
disable_ddl_transaction! if connection.adapter_name.match?(/postgres/i)
|
3
|
+
|
4
|
+
def change
|
5
|
+
add_index :alchemy_pictures, :created_at, if_not_exists: true, algorithm: algorithm
|
6
|
+
add_index :alchemy_attachments, :created_at, if_not_exists: true, algorithm: algorithm
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def algorithm
|
12
|
+
connection.adapter_name.match?(/postgres/i) ? :concurrently : nil
|
13
|
+
end
|
14
|
+
end
|
@@ -41,7 +41,6 @@ module Alchemy
|
|
41
41
|
|
42
42
|
def url_for(page)
|
43
43
|
@preview_config = preview_config_for(page)
|
44
|
-
|
45
44
|
if @preview_config && uri
|
46
45
|
uri_class.build(
|
47
46
|
host: uri.host,
|
@@ -60,10 +59,10 @@ module Alchemy
|
|
60
59
|
attr_reader :routes
|
61
60
|
|
62
61
|
def preview_config_for(page)
|
63
|
-
preview_config = Alchemy
|
62
|
+
preview_config = Alchemy.config.preview
|
64
63
|
return unless preview_config
|
65
64
|
|
66
|
-
preview_config
|
65
|
+
preview_config.for_site(page.site) || preview_config
|
67
66
|
end
|
68
67
|
|
69
68
|
def uri
|
@@ -81,8 +80,8 @@ module Alchemy
|
|
81
80
|
end
|
82
81
|
|
83
82
|
def userinfo
|
84
|
-
auth = @preview_config
|
85
|
-
auth ? "#{auth["username"]}:#{auth["password"]}" : nil
|
83
|
+
auth = @preview_config.auth
|
84
|
+
auth.username ? "#{auth["username"]}:#{auth["password"]}" : nil
|
86
85
|
end
|
87
86
|
end
|
88
87
|
end
|
@@ -14,15 +14,12 @@ module Alchemy
|
|
14
14
|
def dependencies
|
15
15
|
case @name.to_s
|
16
16
|
when /^alchemy\/pages\/show/
|
17
|
-
|
17
|
+
PageDefinition.all.map { "alchemy/page_layouts/_#{_1.name}" }
|
18
18
|
when /^alchemy\/page_layouts\/_(\w+)/
|
19
|
-
|
20
|
-
|
21
|
-
layout_elements.map { |name| "alchemy/elements/_#{name}" }
|
19
|
+
page_definition = PageDefinition.get($1)
|
20
|
+
page_definition.elements.map { "alchemy/elements/_#{_1}" }
|
22
21
|
when /^alchemy\/elements\/_(\w+)/
|
23
|
-
ingredient_types($1).map {
|
24
|
-
"alchemy/ingredients/_#{type.underscore}_view"
|
25
|
-
}.uniq
|
22
|
+
ingredient_types($1).map { "alchemy/ingredients/_#{_1.underscore}_view" }.tap(&:uniq!)
|
26
23
|
else
|
27
24
|
ActionView::DependencyTracker::ERBTracker.call(@name, @template)
|
28
25
|
end
|
@@ -31,10 +28,10 @@ module Alchemy
|
|
31
28
|
private
|
32
29
|
|
33
30
|
def ingredient_types(name)
|
34
|
-
element = Element.definitions.detect {
|
31
|
+
element = Element.definitions.detect { _1.name == name }
|
35
32
|
return [] unless element
|
36
33
|
|
37
|
-
element.
|
34
|
+
element.ingredients.map(&:type)
|
38
35
|
end
|
39
36
|
end
|
40
37
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
module ConfigMissing
|
5
|
+
def const_missing(missing_const_name)
|
6
|
+
if missing_const_name == :Config
|
7
|
+
Alchemy::Deprecation.warn("Alchemy::Config is deprecated. Use Alchemy.config instead.")
|
8
|
+
Alchemy.config
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
class Configuration
|
5
|
+
class BaseOption
|
6
|
+
def self.value_class
|
7
|
+
raise NotImplementedError
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(value:, name:, **args)
|
11
|
+
@name = name
|
12
|
+
@value = validate(value) unless value.nil?
|
13
|
+
end
|
14
|
+
attr_reader :name, :value
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def validate(value)
|
19
|
+
raise TypeError, "#{name} must be set as a #{self.class.value_class.name}, given #{value.inspect}" unless value.is_a?(self.class.value_class)
|
20
|
+
value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/configuration/base_option"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
class Configuration
|
7
|
+
class BooleanOption < BaseOption
|
8
|
+
private
|
9
|
+
|
10
|
+
def validate(value)
|
11
|
+
raise TypeError, "#{name} must be a Boolean, given #{value.inspect}" unless value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
12
|
+
value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/configuration/base_option"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
class Configuration
|
7
|
+
class ClassSetOption < BaseOption
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def value = self
|
11
|
+
|
12
|
+
def <<(klass)
|
13
|
+
@value << klass.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def concat(klasses)
|
17
|
+
klasses.each do |klass|
|
18
|
+
self << klass
|
19
|
+
end
|
20
|
+
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
delegate :clear, :empty?, to: :@value
|
25
|
+
|
26
|
+
def delete(object)
|
27
|
+
@value.delete(object.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def each
|
31
|
+
@value.each do |klass|
|
32
|
+
yield klass.constantize
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def as_json = @value
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def validate(value)
|
41
|
+
raise TypeError, "each #{name} must be set as a String" unless value.all? { _1.is_a?(String) }
|
42
|
+
value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/configuration/base_option"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
class Configuration
|
7
|
+
class ListOption < BaseOption
|
8
|
+
def self.item_class
|
9
|
+
raise NotImplementedError
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def validate(value)
|
15
|
+
unless value.is_a?(Array) && value.all? { _1.is_a?(self.class.item_class) }
|
16
|
+
raise TypeError, "#{@name} must be an Array of #{self.class.item_class.name.downcase.pluralize}, given #{value.inspect}"
|
17
|
+
end
|
18
|
+
value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support"
|
4
|
+
require "active_support/core_ext/string"
|
5
|
+
|
6
|
+
require "alchemy/configuration/boolean_option"
|
7
|
+
require "alchemy/configuration/class_option"
|
8
|
+
require "alchemy/configuration/class_set_option"
|
9
|
+
require "alchemy/configuration/integer_option"
|
10
|
+
require "alchemy/configuration/integer_list_option"
|
11
|
+
require "alchemy/configuration/regexp_option"
|
12
|
+
require "alchemy/configuration/string_list_option"
|
13
|
+
require "alchemy/configuration/string_option"
|
14
|
+
|
15
|
+
module Alchemy
|
16
|
+
class Configuration
|
17
|
+
def initialize(configuration_hash = {})
|
18
|
+
set(configuration_hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
def set(configuration_hash)
|
22
|
+
configuration_hash.each do |key, value|
|
23
|
+
send(:"#{key}=", value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
alias_method :get, :send
|
28
|
+
alias_method :[], :get
|
29
|
+
|
30
|
+
def show = self
|
31
|
+
|
32
|
+
def fetch(key, default = nil)
|
33
|
+
get(key) || default
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_from_yaml(file)
|
37
|
+
set(
|
38
|
+
YAML.safe_load(
|
39
|
+
ERB.new(File.read(file)).result,
|
40
|
+
permitted_classes: YAML_PERMITTED_CLASSES,
|
41
|
+
aliases: true
|
42
|
+
) || {}
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_h
|
47
|
+
self.class.defined_options.map do |option|
|
48
|
+
[option, send(option)]
|
49
|
+
end.concat(
|
50
|
+
self.class.defined_configurations.map do |configuration|
|
51
|
+
[configuration, send(configuration).to_h]
|
52
|
+
end
|
53
|
+
).to_h
|
54
|
+
end
|
55
|
+
|
56
|
+
class << self
|
57
|
+
def defined_configurations = []
|
58
|
+
|
59
|
+
def defined_options = []
|
60
|
+
|
61
|
+
def configuration(name, configuration_class)
|
62
|
+
# The defined configurations on a class are all those defined directly on
|
63
|
+
# that class as well as those defined on ancestors.
|
64
|
+
# We store these as a class instance variable on each class which has a
|
65
|
+
# configuration. super() collects configurations defined on ancestors.
|
66
|
+
singleton_configurations = (@defined_singleton_configurations ||= [])
|
67
|
+
singleton_configurations << name.to_sym
|
68
|
+
|
69
|
+
define_singleton_method :defined_configurations do
|
70
|
+
super() + singleton_configurations
|
71
|
+
end
|
72
|
+
|
73
|
+
define_method(name) do
|
74
|
+
unless instance_variable_get(:"@#{name}")
|
75
|
+
send(:"#{name}=", configuration_class.new)
|
76
|
+
end
|
77
|
+
instance_variable_get(:"@#{name}")
|
78
|
+
end
|
79
|
+
|
80
|
+
define_method(:"#{name}=") do |value|
|
81
|
+
if value.is_a?(configuration_class)
|
82
|
+
instance_variable_set(:"@#{name}", value)
|
83
|
+
else
|
84
|
+
send(name).set(value)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def option(name, type, default: nil, **args)
|
90
|
+
klass = "Alchemy::Configuration::#{type.to_s.camelize}Option".constantize
|
91
|
+
# The defined options on a class are all those defined directly on
|
92
|
+
# that class as well as those defined on ancestors.
|
93
|
+
# We store these as a class instance variable on each class which has a
|
94
|
+
# option. super() collects options defined on ancestors.
|
95
|
+
singleton_options = (@defined_singleton_options ||= [])
|
96
|
+
singleton_options << name.to_sym
|
97
|
+
|
98
|
+
define_singleton_method :defined_options do
|
99
|
+
super() + singleton_options
|
100
|
+
end
|
101
|
+
|
102
|
+
define_method(name) do
|
103
|
+
unless instance_variable_defined?(:"@#{name}")
|
104
|
+
send(:"#{name}=", default)
|
105
|
+
end
|
106
|
+
instance_variable_get(:"@#{name}").value
|
107
|
+
end
|
108
|
+
|
109
|
+
define_method(:"#{name}=") do |value|
|
110
|
+
instance_variable_set(:"@#{name}", klass.new(value:, name:, **args))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -12,9 +12,11 @@ module Alchemy
|
|
12
12
|
#
|
13
13
|
# Config file is in +config/alchemy/config.yml+
|
14
14
|
#
|
15
|
+
# @deprecated - Use Alchemy.config.get instead
|
15
16
|
def configuration(name)
|
16
|
-
|
17
|
+
Alchemy.config.get(name)
|
17
18
|
end
|
19
|
+
deprecate configuration: "Alchemy.config.get", deprecator: Alchemy::Deprecation
|
18
20
|
|
19
21
|
# Returns true if more than one language is published on current site.
|
20
22
|
#
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
module Configurations
|
5
|
+
class DefaultLanguage < Alchemy::Configuration
|
6
|
+
option :name, :string, default: "English"
|
7
|
+
option :code, :string, default: "en"
|
8
|
+
option :page_layout, :string, default: "index"
|
9
|
+
option :frontpage_name, :string, default: "Index"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
module Configurations
|
5
|
+
class FormatMatchers < Alchemy::Configuration
|
6
|
+
option :email, :regexp, default: /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
|
7
|
+
option :url, :regexp, default: /\A[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?\z/ix
|
8
|
+
option :link_url, :regexp, default: /^(tel:|mailto:|\/|[a-z]+:\/\/)/
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
module Configurations
|
5
|
+
class Mailer < Alchemy::Configuration
|
6
|
+
option :page_layout_name, :string, default: "contact"
|
7
|
+
option :forward_to_page, :boolean, default: false
|
8
|
+
option :mail_success_page, :string, default: "thanks"
|
9
|
+
option :mail_from, :string, default: "your.mail@your-domain.com"
|
10
|
+
option :mail_to, :string, default: "your.mail@your-domain.com"
|
11
|
+
option :subject, :string, default: "A new contact form message"
|
12
|
+
option :fields, :string_list, default: %w[salutation firstname lastname address zip city phone email message]
|
13
|
+
option :validate_fields, :string_list, default: %w[lastname email]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|