alchemy_cms 7.4.5 → 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 +92 -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/picture_descriptions_controller.rb +5 -1
- data/app/controllers/alchemy/admin/pictures_controller.rb +10 -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/picture_descriptions_form_helper.rb +16 -0
- 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 +4 -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/growl.js +1 -0
- 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/picture_descriptions/_form.html.erb +5 -7
- data/app/views/alchemy/admin/picture_descriptions/edit.html.erb +2 -2
- 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/_form.html.erb +2 -2
- data/app/views/alchemy/admin/pictures/_picture_description_field.html.erb +21 -13
- 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/500.turbo_stream.erb +3 -0
- 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/db/migrate/20250626160259_add_unique_index_to_picture_descriptions.rb +7 -0
- 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 +184 -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
@@ -4,8 +4,6 @@ module Alchemy
|
|
4
4
|
class Ingredient < BaseRecord
|
5
5
|
class DefinitionError < StandardError; end
|
6
6
|
|
7
|
-
include Hints
|
8
|
-
|
9
7
|
self.table_name = "alchemy_ingredients"
|
10
8
|
|
11
9
|
attribute :data, :json
|
@@ -16,7 +14,7 @@ module Alchemy
|
|
16
14
|
has_one :page, through: :element, class_name: "Alchemy::Page"
|
17
15
|
|
18
16
|
after_initialize :set_default_value,
|
19
|
-
if: -> { definition.
|
17
|
+
if: -> { definition.default && value.nil? }
|
20
18
|
|
21
19
|
validates :type, presence: true
|
22
20
|
validates :role, presence: true, uniqueness: {scope: :element_id, case_sensitive: false}
|
@@ -38,6 +36,8 @@ module Alchemy
|
|
38
36
|
scope :texts, -> { where(type: "Alchemy::Ingredients::Text") }
|
39
37
|
scope :videos, -> { where(type: "Alchemy::Ingredients::Video") }
|
40
38
|
|
39
|
+
delegate :has_hint?, :hint, to: :definition
|
40
|
+
|
41
41
|
class << self
|
42
42
|
# Defines getter and setter method aliases for related object
|
43
43
|
#
|
@@ -97,15 +97,15 @@ module Alchemy
|
|
97
97
|
|
98
98
|
# Settings for this ingredient from the +elements.yml+ definition.
|
99
99
|
def settings
|
100
|
-
definition
|
100
|
+
definition.settings
|
101
101
|
end
|
102
102
|
|
103
103
|
# Definition hash for this ingredient from +elements.yml+ file.
|
104
104
|
#
|
105
105
|
def definition
|
106
|
-
return
|
106
|
+
return IngredientDefinition.new unless element
|
107
107
|
|
108
|
-
element.ingredient_definition_for(role) ||
|
108
|
+
element.ingredient_definition_for(role) || IngredientDefinition.new
|
109
109
|
end
|
110
110
|
|
111
111
|
# The first 30 characters of the value
|
@@ -118,12 +118,6 @@ module Alchemy
|
|
118
118
|
value.to_s[0..maxlength - 1]
|
119
119
|
end
|
120
120
|
|
121
|
-
# The path to the view partial of the ingredient
|
122
|
-
# @return [String]
|
123
|
-
def to_partial_path
|
124
|
-
"alchemy/ingredients/#{partial_name}_view"
|
125
|
-
end
|
126
|
-
|
127
121
|
# The demodulized underscored class name of the ingredient
|
128
122
|
# @return [String]
|
129
123
|
def partial_name
|
@@ -132,17 +126,12 @@ module Alchemy
|
|
132
126
|
|
133
127
|
# @return [Boolean]
|
134
128
|
def has_validations?
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
# @return [Boolean]
|
139
|
-
def has_hint?
|
140
|
-
!!definition[:hint]
|
129
|
+
definition.validate.any?
|
141
130
|
end
|
142
131
|
|
143
132
|
# @return [Boolean]
|
144
133
|
def deprecated?
|
145
|
-
!!definition
|
134
|
+
!!definition.deprecated
|
146
135
|
end
|
147
136
|
|
148
137
|
# @return [Boolean]
|
@@ -152,7 +141,7 @@ module Alchemy
|
|
152
141
|
|
153
142
|
# @return [Boolean]
|
154
143
|
def preview_ingredient?
|
155
|
-
!!definition
|
144
|
+
!!definition.as_element_title
|
156
145
|
end
|
157
146
|
|
158
147
|
# The view component of the ingredient with mapped options.
|
@@ -169,30 +158,8 @@ module Alchemy
|
|
169
158
|
@_view_component_class ||= "#{self.class.name}View".constantize
|
170
159
|
end
|
171
160
|
|
172
|
-
def hint_translation_attribute
|
173
|
-
role
|
174
|
-
end
|
175
|
-
|
176
|
-
def hint_translation_scope
|
177
|
-
"ingredient_hints"
|
178
|
-
end
|
179
|
-
|
180
161
|
def set_default_value
|
181
|
-
self.value = default_value
|
182
|
-
end
|
183
|
-
|
184
|
-
# Returns the default value from ingredient definition
|
185
|
-
#
|
186
|
-
# If the value is a symbol it gets passed through i18n
|
187
|
-
# inside the +alchemy.default_ingredient_texts+ scope
|
188
|
-
def default_value
|
189
|
-
default = definition[:default]
|
190
|
-
case default
|
191
|
-
when Symbol
|
192
|
-
Alchemy.t(default, scope: :default_ingredient_texts)
|
193
|
-
else
|
194
|
-
default
|
195
|
-
end
|
162
|
+
self.value = definition.default_value
|
196
163
|
end
|
197
164
|
end
|
198
165
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
class IngredientDefinition
|
5
|
+
include ActiveModel::Model
|
6
|
+
include ActiveModel::Attributes
|
7
|
+
include Alchemy::Hints
|
8
|
+
|
9
|
+
extend ActiveModel::Translation
|
10
|
+
|
11
|
+
attribute :role, :string
|
12
|
+
attribute :type, :string
|
13
|
+
attribute :as_element_title, :boolean, default: false
|
14
|
+
attribute :settings, default: {}
|
15
|
+
attribute :validate, default: []
|
16
|
+
attribute :group, :string
|
17
|
+
attribute :default
|
18
|
+
attribute :deprecated
|
19
|
+
attribute :hint
|
20
|
+
|
21
|
+
validates :role,
|
22
|
+
presence: true,
|
23
|
+
format: {
|
24
|
+
with: /\A[a-z_-]+\z/
|
25
|
+
}
|
26
|
+
|
27
|
+
validates :type,
|
28
|
+
presence: true,
|
29
|
+
format: {
|
30
|
+
with: /\A[A-Z][a-zA-Z]+\z/
|
31
|
+
}
|
32
|
+
|
33
|
+
delegate :blank?, to: :role
|
34
|
+
|
35
|
+
def attributes
|
36
|
+
super.with_indifferent_access
|
37
|
+
end
|
38
|
+
|
39
|
+
def settings
|
40
|
+
super.with_indifferent_access
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate
|
44
|
+
super.map do |validation|
|
45
|
+
case validation
|
46
|
+
when Hash
|
47
|
+
validation.with_indifferent_access
|
48
|
+
else
|
49
|
+
validation
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the default value from ingredient definition
|
55
|
+
#
|
56
|
+
# If the value is a symbol it gets passed through i18n
|
57
|
+
# inside the +alchemy.default_ingredient_texts+ scope
|
58
|
+
def default_value
|
59
|
+
case default
|
60
|
+
when Symbol
|
61
|
+
Alchemy.t(default, scope: :default_ingredient_texts)
|
62
|
+
when String
|
63
|
+
default
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns a deprecation notice for ingredients marked deprecated
|
68
|
+
#
|
69
|
+
# You can either use localizations or pass a String as notice
|
70
|
+
# in the ingredient definition.
|
71
|
+
#
|
72
|
+
# == Custom deprecation notices
|
73
|
+
#
|
74
|
+
# Use general ingredient deprecation notice
|
75
|
+
#
|
76
|
+
# - name: element_name
|
77
|
+
# ingredients:
|
78
|
+
# - role: old_ingredient
|
79
|
+
# type: Text
|
80
|
+
# deprecated: true
|
81
|
+
#
|
82
|
+
# Add a translation to your locale file for a per ingredient notice.
|
83
|
+
#
|
84
|
+
# en:
|
85
|
+
# alchemy:
|
86
|
+
# ingredient_deprecation_notices:
|
87
|
+
# old_ingredient: Foo baz widget is deprecated
|
88
|
+
#
|
89
|
+
# You can scope the translation per element as well.
|
90
|
+
#
|
91
|
+
# en:
|
92
|
+
# alchemy:
|
93
|
+
# ingredient_deprecation_notices:
|
94
|
+
# element_name:
|
95
|
+
# old_ingredient: Elements foo baz widget is deprecated
|
96
|
+
#
|
97
|
+
# or use the global translation that apply to all deprecated ingredients.
|
98
|
+
#
|
99
|
+
# en:
|
100
|
+
# alchemy:
|
101
|
+
# ingredient_deprecation_notice: Foo baz widget is deprecated
|
102
|
+
#
|
103
|
+
# or pass string as deprecation notice.
|
104
|
+
#
|
105
|
+
# - name: element_name
|
106
|
+
# ingredients:
|
107
|
+
# - role: old_ingredient
|
108
|
+
# type: Text
|
109
|
+
# deprecated: This ingredient will be removed soon.
|
110
|
+
#
|
111
|
+
def deprecation_notice(element_name: nil)
|
112
|
+
case deprecated
|
113
|
+
when String
|
114
|
+
deprecated
|
115
|
+
when TrueClass
|
116
|
+
Alchemy.t(
|
117
|
+
role,
|
118
|
+
scope: [:ingredient_deprecation_notices, element_name].compact,
|
119
|
+
default: Alchemy.t(:ingredient_deprecated)
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def hint_translation_scope
|
127
|
+
:ingredient_hints
|
128
|
+
end
|
129
|
+
|
130
|
+
def hint_translation_attribute
|
131
|
+
role
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -64,7 +64,7 @@ module Alchemy
|
|
64
64
|
attr_reader :ingredient
|
65
65
|
|
66
66
|
def validations
|
67
|
-
ingredient.definition.
|
67
|
+
ingredient.definition.validate
|
68
68
|
end
|
69
69
|
|
70
70
|
def validate_presence(*)
|
@@ -80,8 +80,12 @@ module Alchemy
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def validate_format(format)
|
83
|
-
matcher =
|
84
|
-
|
83
|
+
matcher = if format.is_a?(String) || format.is_a?(Symbol)
|
84
|
+
Alchemy.config.format_matchers.get(format)
|
85
|
+
else
|
86
|
+
format
|
87
|
+
end
|
88
|
+
if !ingredient.value.to_s.match?(matcher)
|
85
89
|
ingredient.errors.add(:value, :invalid)
|
86
90
|
end
|
87
91
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
module Ingredients
|
5
|
+
# A number
|
6
|
+
#
|
7
|
+
# Either a decimal or integer number
|
8
|
+
#
|
9
|
+
class Number < Alchemy::Ingredient
|
10
|
+
allow_settings %i[
|
11
|
+
input_type
|
12
|
+
step
|
13
|
+
min
|
14
|
+
max
|
15
|
+
unit
|
16
|
+
]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -71,20 +71,6 @@ module Alchemy
|
|
71
71
|
on_site(Current.site)
|
72
72
|
end
|
73
73
|
|
74
|
-
# Store the current language in the current thread.
|
75
|
-
# @deprecated Use {Alchemy::Current#language=} instead.
|
76
|
-
def current=(language)
|
77
|
-
Current.language = language
|
78
|
-
end
|
79
|
-
deprecate "current=": :"Alchemy::Current.language=", deprecator: Alchemy::Deprecation
|
80
|
-
|
81
|
-
# Current language from current thread or default.
|
82
|
-
# @deprecated Use {Alchemy::Current#language} instead.
|
83
|
-
def current
|
84
|
-
Current.language
|
85
|
-
end
|
86
|
-
deprecate current: :"Alchemy::Current.language", deprecator: Alchemy::Deprecation
|
87
|
-
|
88
74
|
# The root page of the current language.
|
89
75
|
def current_root_page
|
90
76
|
Current.language&.pages&.language_roots&.first
|
@@ -16,23 +16,19 @@ module Alchemy
|
|
16
16
|
class Message
|
17
17
|
include ActiveModel::Model
|
18
18
|
|
19
|
-
def self.config
|
20
|
-
Alchemy::Config.get(:mailer)
|
21
|
-
end
|
22
|
-
|
23
19
|
attr_accessor :contact_form_id, :ip
|
24
20
|
|
25
|
-
config
|
21
|
+
Alchemy.config.mailer.fields.each do |field|
|
26
22
|
attr_accessor field.to_sym
|
27
23
|
end
|
28
24
|
|
29
|
-
config
|
25
|
+
Alchemy.config.mailer.validate_fields.each do |field|
|
30
26
|
validates_presence_of field
|
31
27
|
|
32
28
|
case field.to_sym
|
33
29
|
when /email/
|
34
30
|
validates_format_of field,
|
35
|
-
with: Alchemy
|
31
|
+
with: Alchemy.config.format_matchers.email,
|
36
32
|
if: -> { send(field).present? }
|
37
33
|
when :email_confirmation
|
38
34
|
validates_confirmation_of :email
|
data/app/models/alchemy/node.rb
CHANGED
@@ -7,7 +7,7 @@ module Alchemy
|
|
7
7
|
before_destroy :check_if_related_node_ingredients_present
|
8
8
|
|
9
9
|
acts_as_nested_set scope: "language_id", touch: true
|
10
|
-
stampable stamper_class_name: Alchemy.
|
10
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
11
11
|
|
12
12
|
belongs_to :language, class_name: "Alchemy::Language"
|
13
13
|
belongs_to :page, class_name: "Alchemy::Page", optional: true, inverse_of: :nodes
|
@@ -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
|
@@ -38,13 +38,13 @@ module Alchemy
|
|
38
38
|
# @returns Array
|
39
39
|
#
|
40
40
|
def has_limited_editors?
|
41
|
-
definition
|
41
|
+
definition.editable_by.present?
|
42
42
|
end
|
43
43
|
|
44
44
|
def editor_roles
|
45
45
|
return unless has_limited_editors?
|
46
46
|
|
47
|
-
definition
|
47
|
+
definition.editable_by
|
48
48
|
end
|
49
49
|
|
50
50
|
# True if page locked_at timestamp and locked_by id are set
|
@@ -80,10 +80,10 @@ module Alchemy
|
|
80
80
|
|
81
81
|
# Returns the self#page_layout definition from config/alchemy/page_layouts.yml file.
|
82
82
|
def definition
|
83
|
-
definition =
|
83
|
+
definition = PageDefinition.get(page_layout)
|
84
84
|
if definition.nil?
|
85
85
|
log_warning "Page definition for `#{page_layout}` not found. Please check `page_layouts.yml` file."
|
86
|
-
return
|
86
|
+
return PageDefinition.new
|
87
87
|
end
|
88
88
|
definition
|
89
89
|
end
|
@@ -146,14 +146,14 @@ module Alchemy
|
|
146
146
|
def cache_page?
|
147
147
|
return false unless caching_enabled?
|
148
148
|
|
149
|
-
page_layout =
|
150
|
-
page_layout
|
149
|
+
page_layout = PageDefinition.get(self.page_layout)
|
150
|
+
page_layout.cache != false && page_layout.searchresults != true
|
151
151
|
end
|
152
152
|
|
153
153
|
private
|
154
154
|
|
155
155
|
def caching_enabled?
|
156
|
-
Alchemy
|
156
|
+
Alchemy.config.cache_pages &&
|
157
157
|
Rails.application.config.action_controller.perform_caching
|
158
158
|
end
|
159
159
|
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
|