alchemy_cms 7.4.6 → 8.0.0.a
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/CHANGELOG.md +86 -0
- data/Gemfile +13 -6
- data/README.md +13 -5
- data/alchemy_cms.gemspec +14 -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/custom-properties.css +1 -1
- 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/ui/alchemy/content.min.css +1 -0
- data/app/assets/builds/tinymce/skins/ui/alchemy/skin.min.css +1 -1
- data/app/assets/config/alchemy_manifest.js +0 -2
- data/app/assets/images/alchemy/icons-sprite.svg +1 -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 +8 -15
- data/app/controllers/alchemy/admin/clipboard_controller.rb +2 -6
- data/app/controllers/alchemy/admin/elements_controller.rb +1 -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 +9 -5
- 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 +7 -2
- data/app/controllers/concerns/alchemy/admin/resource_filter.rb +92 -0
- data/app/decorators/alchemy/element_editor.rb +5 -48
- data/app/decorators/alchemy/ingredient_editor.rb +3 -53
- data/app/helpers/alchemy/admin/base_helper.rb +14 -84
- data/app/helpers/alchemy/admin/elements_helper.rb +4 -4
- 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/datepicker.js +10 -2
- data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +7 -7
- data/app/javascript/alchemy_admin/components/element_editor.js +1 -1
- data/app/javascript/alchemy_admin/components/index.js +1 -0
- data/app/javascript/alchemy_admin/components/remote_select.js +4 -1
- data/app/javascript/alchemy_admin/components/tags_autocomplete.js +5 -1
- data/app/javascript/alchemy_admin/components/tinymce.js +4 -2
- 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/dirty.js +3 -2
- data/app/javascript/alchemy_admin/i18n.js +15 -16
- data/app/javascript/alchemy_admin/initializer.js +1 -49
- data/app/javascript/alchemy_admin/utils/ajax.js +51 -44
- data/app/javascript/alchemy_admin.js +3 -8
- 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 +51 -34
- 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 +9 -27
- data/app/models/alchemy/element_definition.rb +160 -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 +0 -14
- 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_natures.rb +7 -7
- data/app/models/alchemy/page/page_scopes.rb +1 -1
- data/app/models/alchemy/page.rb +11 -33
- data/app/models/alchemy/page_definition.rb +115 -0
- data/app/models/alchemy/picture.rb +69 -79
- 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 +0 -15
- 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/{picture/url.rb → storage_adapter/dragonfly/picture_url.rb} +28 -12
- data/app/models/alchemy/{picture → storage_adapter/dragonfly}/preprocessor.rb +4 -4
- data/app/models/alchemy/storage_adapter/dragonfly.rb +183 -0
- data/app/models/alchemy/storage_adapter.rb +74 -0
- data/app/models/concerns/alchemy/picture_thumbnails.rb +19 -6
- data/app/serializers/alchemy/element_serializer.rb +0 -1
- data/app/services/alchemy/dragonfly_to_image_processing.rb +100 -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 +36 -49
- data/app/stylesheets/alchemy/_variables.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/archive.scss +20 -37
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/base.scss +16 -14
- data/app/stylesheets/alchemy/admin/buttons.scss +160 -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 +23 -16
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/elements.scss +150 -105
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/errors.scss +5 -5
- data/app/stylesheets/alchemy/admin/filters.scss +58 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/flatpickr.scss +53 -60
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/form_fields.scss +21 -7
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/forms.scss +31 -19
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/frame.scss +20 -16
- data/app/stylesheets/alchemy/admin/hints.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/icons.scss +10 -1
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/image_library.scss +10 -8
- 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 +61 -55
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/nodes.scss +21 -18
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/notices.scss +18 -18
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/page-select.scss +2 -2
- data/app/stylesheets/alchemy/admin/pagination.scss +144 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/preview_window.scss +8 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/print.scss +1 -1
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/resource_info.scss +8 -5
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/search.scss +9 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/selects.scss +49 -37
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/shoelace.scss +5 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/sitemap.scss +38 -33
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/tables.scss +6 -4
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/tags.scss +6 -4
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/toolbar.scss +12 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/typography.scss +2 -2
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/upload.scss +7 -5
- data/app/stylesheets/alchemy/admin.scss +44 -0
- data/app/stylesheets/alchemy/custom-properties.css +244 -0
- data/app/stylesheets/alchemy/welcome.scss +75 -0
- data/app/{assets/stylesheets → stylesheets}/tinymce/skins/content/alchemy/content.scss +8 -9
- data/app/stylesheets/tinymce/skins/ui/alchemy/content.scss +1 -0
- data/app/{assets/stylesheets → stylesheets}/tinymce/skins/ui/alchemy/skin.scss +133 -136
- data/app/views/alchemy/admin/attachments/_files_list.html.erb +2 -2
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
- 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/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 +1 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +1 -0
- 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 +4 -7
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +2 -1
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/index.html.erb +2 -7
- data/app/views/alchemy/admin/resources/_applied_filters.html.erb +8 -0
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +11 -21
- 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/_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 +8 -0
- 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/redirect.js.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 +5 -9
- data/bun.lockb +0 -0
- data/bundles/remixicon.mjs +153 -0
- 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 +32 -14
- data/config/routes.rb +0 -2
- data/eslint.config.js +2 -1
- 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 +216 -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 +65 -17
- data/lib/alchemy/hints.rb +3 -7
- 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/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 +30 -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/shared_ingredient_examples.rb +5 -5
- data/lib/alchemy/upgrader/.keep +0 -0
- 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 +192 -170
- 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 +5 -14
- data/lib/generators/alchemy/install/templates/alchemy.rb.tt +196 -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/upgrade.rake +12 -47
- data/vendor/javascript/tinymce.min.js +1 -1
- data/vitest.config.js +21 -0
- metadata +181 -180
- 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.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/buttons.scss +0 -124
- 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.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/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/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/config/initializers/assets.rb +0 -4
- 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/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/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/attachments.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/node-select.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,57 @@ 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 linked by file content
|
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
|
142
159
|
|
143
160
|
default_ingredient_texts:
|
144
161
|
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."
|
@@ -681,7 +698,7 @@ en:
|
|
681
698
|
time:
|
682
699
|
formats:
|
683
700
|
alchemy:
|
684
|
-
default: "%m
|
701
|
+
default: "%Y-%m-%d %H:%M"
|
685
702
|
ingredient_date: "%Y-%m-%d"
|
686
703
|
page_status: "%m.%d.%Y %H:%M"
|
687
704
|
short_datetime: "%d %b %H:%M"
|
@@ -719,6 +736,7 @@ en:
|
|
719
736
|
attributes:
|
720
737
|
image_file:
|
721
738
|
blank: "Please attach a picture."
|
739
|
+
too_big: must not be larger than %{maximum}MB
|
722
740
|
alchemy/user:
|
723
741
|
attributes:
|
724
742
|
email:
|
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]
|
data/eslint.config.js
CHANGED
@@ -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
|