alchemy_cms 4.6.7 → 5.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +33 -1
- data/.github/workflows/stale.yml +1 -1
- data/.gitignore +20 -2
- data/.hound.yml +2 -1
- data/.prettierrc +6 -0
- data/.rubocop.yml +31 -10
- data/CHANGELOG.md +89 -32
- data/Gemfile +24 -22
- data/README.md +31 -19
- data/Rakefile +10 -8
- data/alchemy_cms.gemspec +6 -5
- data/app/assets/javascripts/alchemy/admin.js +1 -5
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +2 -1
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -2
- data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +17 -17
- data/app/assets/javascripts/alchemy/node_select.js +39 -0
- data/app/assets/javascripts/alchemy/templates/index.js +1 -0
- data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
- data/app/assets/stylesheets/alchemy/admin.scss +3 -2
- data/app/assets/stylesheets/alchemy/base.scss +0 -1
- data/app/assets/stylesheets/alchemy/elements.scss +1 -1
- data/app/assets/stylesheets/alchemy/forms.scss +5 -0
- data/app/assets/stylesheets/alchemy/node-select.scss +43 -0
- data/app/assets/stylesheets/alchemy/nodes.scss +1 -1
- data/app/assets/stylesheets/alchemy/sitemap.scss +5 -1
- data/app/assets/stylesheets/alchemy/tables.scss +1 -24
- data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +3 -3
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +7 -7
- data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
- data/app/controllers/alchemy/admin/base_controller.rb +16 -42
- data/app/controllers/alchemy/admin/clipboard_controller.rb +5 -4
- data/app/controllers/alchemy/admin/contents_controller.rb +1 -2
- data/app/controllers/alchemy/admin/dashboard_controller.rb +10 -9
- data/app/controllers/alchemy/admin/elements_controller.rb +20 -20
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +12 -14
- data/app/controllers/alchemy/admin/languages_controller.rb +35 -2
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -2
- data/app/controllers/alchemy/admin/nodes_controller.rb +5 -4
- data/app/controllers/alchemy/admin/pages_controller.rb +50 -62
- data/app/controllers/alchemy/admin/pictures_controller.rb +16 -16
- data/app/controllers/alchemy/admin/resources_controller.rb +21 -13
- data/app/controllers/alchemy/admin/sites_controller.rb +18 -0
- data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
- data/app/controllers/alchemy/admin/tags_controller.rb +5 -3
- data/app/controllers/alchemy/admin/trash_controller.rb +6 -6
- data/app/controllers/alchemy/api/base_controller.rb +2 -2
- data/app/controllers/alchemy/api/contents_controller.rb +4 -4
- data/app/controllers/alchemy/api/elements_controller.rb +8 -8
- data/app/controllers/alchemy/api/nodes_controller.rb +37 -1
- data/app/controllers/alchemy/api/pages_controller.rb +14 -23
- data/app/controllers/alchemy/attachments_controller.rb +5 -5
- data/app/controllers/alchemy/base_controller.rb +10 -9
- data/app/controllers/alchemy/messages_controller.rb +16 -23
- data/app/controllers/alchemy/pages_controller.rb +13 -11
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +3 -2
- data/app/controllers/concerns/alchemy/admin/current_language.rb +23 -0
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -5
- data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +4 -4
- data/app/controllers/concerns/alchemy/page_redirects.rb +2 -9
- data/app/controllers/concerns/alchemy/site_redirects.rb +2 -2
- data/app/decorators/alchemy/element_editor.rb +39 -0
- data/app/helpers/alchemy/admin/attachments_helper.rb +6 -6
- data/app/helpers/alchemy/admin/base_helper.rb +36 -35
- data/app/helpers/alchemy/admin/contents_helper.rb +3 -3
- data/app/helpers/alchemy/admin/elements_helper.rb +3 -88
- data/app/helpers/alchemy/admin/essences_helper.rb +8 -117
- data/app/helpers/alchemy/admin/form_helper.rb +1 -1
- data/app/helpers/alchemy/admin/navigation_helper.rb +24 -23
- data/app/helpers/alchemy/admin/pages_helper.rb +4 -4
- data/app/helpers/alchemy/admin/pictures_helper.rb +3 -3
- data/app/helpers/alchemy/admin/tags_helper.rb +8 -7
- data/app/helpers/alchemy/base_helper.rb +13 -8
- data/app/helpers/alchemy/elements_block_helper.rb +2 -31
- data/app/helpers/alchemy/elements_helper.rb +12 -58
- data/app/helpers/alchemy/pages_helper.rb +24 -174
- data/app/helpers/alchemy/url_helper.rb +2 -1
- data/app/mailers/alchemy/base_mailer.rb +1 -1
- data/app/mailers/alchemy/messages_mailer.rb +1 -1
- data/app/models/alchemy/attachment.rb +21 -19
- data/app/models/alchemy/base_record.rb +2 -5
- data/app/models/alchemy/content/factory.rb +24 -31
- data/app/models/alchemy/content.rb +33 -38
- data/app/models/alchemy/element/definitions.rb +4 -4
- data/app/models/alchemy/element/element_contents.rb +9 -6
- data/app/models/alchemy/element/element_essences.rb +4 -3
- data/app/models/alchemy/element/presenters.rb +3 -2
- data/app/models/alchemy/element.rb +46 -54
- data/app/models/alchemy/element_to_page.rb +1 -1
- data/app/models/alchemy/essence_boolean.rb +1 -3
- data/app/models/alchemy/essence_date.rb +2 -3
- data/app/models/alchemy/essence_file.rb +4 -4
- data/app/models/alchemy/essence_html.rb +1 -3
- data/app/models/alchemy/essence_link.rb +1 -3
- data/app/models/alchemy/essence_node.rb +18 -0
- data/app/models/alchemy/essence_page.rb +3 -16
- data/app/models/alchemy/essence_picture.rb +17 -16
- data/app/models/alchemy/essence_picture_view.rb +7 -6
- data/app/models/alchemy/essence_richtext.rb +1 -3
- data/app/models/alchemy/essence_select.rb +1 -3
- data/app/models/alchemy/essence_text.rb +0 -2
- data/app/models/alchemy/folded_page.rb +1 -0
- data/app/models/alchemy/language/code.rb +4 -4
- data/app/models/alchemy/language.rb +21 -35
- data/app/models/alchemy/legacy_page_url.rb +1 -1
- data/app/models/alchemy/message.rb +3 -3
- data/app/models/alchemy/node.rb +28 -5
- data/app/models/alchemy/page/fixed_attributes.rb +3 -2
- data/app/models/alchemy/page/page_elements.rb +35 -44
- data/app/models/alchemy/page/page_naming.rb +20 -70
- data/app/models/alchemy/page/page_natures.rb +7 -34
- data/app/models/alchemy/page/page_scopes.rb +23 -29
- data/app/models/alchemy/page/url_path.rb +0 -2
- data/app/models/alchemy/page.rb +47 -128
- data/app/models/alchemy/picture/transformations.rb +9 -7
- data/app/models/alchemy/picture/url.rb +5 -5
- data/app/models/alchemy/picture.rb +19 -28
- data/app/models/alchemy/site/layout.rb +2 -2
- data/app/models/alchemy/site.rb +6 -36
- data/app/models/concerns/alchemy/touch_elements.rb +24 -0
- data/app/serializers/alchemy/content_serializer.rb +0 -3
- data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
- data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
- data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
- data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
- data/app/serializers/alchemy/node_serializer.rb +2 -0
- data/app/serializers/alchemy/page_tree_serializer.rb +9 -13
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
- data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
- data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
- data/app/views/alchemy/admin/contents/create.js.erb +1 -3
- data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
- data/app/views/alchemy/admin/elements/create.js.erb +1 -1
- data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
- data/app/views/alchemy/admin/elements/index.html.erb +3 -3
- data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
- data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
- data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
- data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
- data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
- data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
- data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
- data/app/views/alchemy/admin/languages/index.html.erb +23 -4
- data/app/views/alchemy/admin/languages/new.html.erb +1 -0
- data/app/views/alchemy/admin/layoutpages/index.html.erb +3 -3
- data/app/views/alchemy/admin/nodes/_form.html.erb +18 -15
- data/app/views/alchemy/admin/nodes/_node.html.erb +1 -5
- data/app/views/alchemy/admin/nodes/index.html.erb +3 -4
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
- data/app/views/alchemy/admin/pages/_form.html.erb +0 -1
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
- data/app/views/alchemy/admin/pages/_page.html.erb +11 -19
- data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/info.html.erb +0 -9
- data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
- data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
- data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
- data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
- data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
- data/app/views/alchemy/admin/sites/index.html.erb +21 -9
- data/app/views/alchemy/admin/sites/new.html.erb +1 -0
- data/app/views/alchemy/admin/tags/index.html.erb +2 -2
- data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
- data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
- data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
- data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
- data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
- data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
- data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
- data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
- data/app/views/alchemy/pages/show.rss.builder +3 -2
- data/app/views/layouts/alchemy/admin.html.erb +1 -0
- data/babel.config.js +12 -0
- data/bin/rails +5 -4
- data/config/alchemy/config.yml +15 -18
- data/config/brakeman.ignore +1 -1
- data/config/initializers/assets.rb +2 -1
- data/config/initializers/dragonfly.rb +2 -1
- data/config/initializers/mime_types.rb +1 -0
- data/config/initializers/mini_profiler.rb +3 -2
- data/config/initializers/simple_form.rb +6 -6
- data/config/locales/alchemy.en.yml +23 -8
- data/config/routes.rb +25 -24
- data/config/spring.rb +3 -2
- data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
- data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
- data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
- data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
- data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
- data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
- data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
- data/lib/alchemy/admin/locale.rb +3 -1
- data/lib/alchemy/admin/preview_url.rb +64 -0
- data/lib/alchemy/auth_accessors.rb +8 -7
- data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
- data/lib/alchemy/config.rb +1 -5
- data/lib/alchemy/configuration_methods.rb +3 -1
- data/lib/alchemy/controller_actions.rb +6 -5
- data/lib/alchemy/deprecation.rb +2 -1
- data/lib/alchemy/elements_finder.rb +5 -5
- data/lib/alchemy/engine.rb +22 -14
- data/lib/alchemy/errors.rb +0 -7
- data/lib/alchemy/essence.rb +17 -16
- data/lib/alchemy/filetypes.rb +5 -5
- data/lib/alchemy/forms/builder.rb +4 -4
- data/lib/alchemy/hints.rb +1 -1
- data/lib/alchemy/i18n.rb +2 -1
- data/lib/alchemy/modules.rb +12 -12
- data/lib/alchemy/name_conversions.rb +5 -5
- data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
- data/lib/alchemy/page_layout.rb +15 -12
- data/lib/alchemy/paths.rb +1 -1
- data/lib/alchemy/permissions.rb +7 -6
- data/lib/alchemy/resource.rb +25 -17
- data/lib/alchemy/resources_helper.rb +12 -18
- data/lib/alchemy/routing_constraints.rb +1 -1
- data/lib/alchemy/seeder.rb +42 -14
- data/lib/alchemy/shell.rb +13 -10
- data/lib/alchemy/taggable.rb +1 -0
- data/lib/alchemy/tasks/tidy.rb +4 -3
- data/lib/alchemy/test_support/config_stubbing.rb +1 -0
- data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
- data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
- data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
- data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
- data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
- data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
- data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
- data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
- data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
- data/lib/alchemy/test_support/factories/language_factory.rb +16 -14
- data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
- data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
- data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
- data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
- data/lib/alchemy/test_support/factories.rb +1 -1
- data/lib/alchemy/test_support/integration_helpers.rb +1 -0
- data/lib/alchemy/test_support/shared_contexts.rb +5 -4
- data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
- data/lib/alchemy/tinymce.rb +15 -13
- data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
- data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
- data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
- data/lib/alchemy/upgrader.rb +8 -7
- data/lib/alchemy/userstamp.rb +1 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +52 -51
- data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
- data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
- data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
- data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
- data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
- data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
- data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
- data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
- data/lib/generators/alchemy/install/install_generator.rb +110 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/menus.yml.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +2 -2
- data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
- data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
- data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
- data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
- data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +1 -1
- data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +1 -1
- data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
- data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
- data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
- data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
- data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
- data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
- data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
- data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
- data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
- data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
- data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
- data/lib/tasks/alchemy/db.rake +3 -19
- data/lib/tasks/alchemy/install.rake +3 -2
- data/lib/tasks/alchemy/tidy.rake +9 -8
- data/lib/tasks/alchemy/upgrade.rake +18 -120
- data/package/admin.js +14 -0
- data/package/src/__tests__/i18n.spec.js +70 -0
- data/package/src/i18n.js +48 -0
- data/package/src/node_tree.js +72 -0
- data/package/src/translations.js +32 -0
- data/package/src/utils/__tests__/ajax.spec.js +124 -0
- data/package/src/utils/__tests__/events.spec.js +38 -0
- data/package/src/utils/ajax.js +48 -0
- data/package/src/utils/events.js +16 -0
- data/package.json +45 -0
- data/vendor/assets/fonts/fa-regular-400.eot +0 -0
- data/vendor/assets/fonts/fa-regular-400.svg +798 -358
- data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
- data/vendor/assets/fonts/fa-solid-900.eot +0 -0
- data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
- data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
- data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
- data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
- data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
- data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
- data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
- data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
- data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
- data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
- data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
- data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
- metadata +117 -98
- data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
- data/app/assets/javascripts/alchemy/alchemy.node_tree.js +0 -66
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
- data/app/assets/javascripts/alchemy/alchemy.utils.js +0 -45
- data/app/helpers/alchemy/essences_helper.rb +0 -119
- data/app/models/concerns/alchemy/content_touching.rb +0 -23
- data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
- data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
- data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -37
- data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
- data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
- data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
- data/app/views/alchemy/navigation/_link.html.erb +0 -19
- data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
- data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
- data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
- data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
- data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
- data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
- data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
- data/lib/alchemy/error_tracking/airbrake_handler.rb +0 -13
- data/lib/alchemy/error_tracking.rb +0 -14
- data/lib/alchemy/ssl_protection.rb +0 -34
- data/lib/alchemy/tasks/helpers.rb +0 -81
- data/lib/alchemy/test_support/controller_requests.rb +0 -93
- data/lib/alchemy/upgrader/four_point_four.rb +0 -52
- data/lib/alchemy/upgrader/four_point_one.rb +0 -42
- data/lib/alchemy/upgrader/four_point_six.rb +0 -50
- data/lib/alchemy/upgrader/four_point_two.rb +0 -86
- data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -45
- data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -166
- data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -32
- data/lib/alchemy/upgrader/tasks/fixed_element_name_finder.rb +0 -31
- data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
- data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
- data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
- data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
- data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
- data/lib/tasks/alchemy/convert.rake +0 -98
- data/vendor/assets/javascripts/sortable/Sortable.min.js +0 -2
- data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
- data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
data/app/models/alchemy/page.rb
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
# rgt :integer
|
|
18
18
|
# parent_id :integer
|
|
19
19
|
# depth :integer
|
|
20
|
-
# visible :boolean default(FALSE)
|
|
21
20
|
# locked_by :integer
|
|
22
21
|
# restricted :boolean default(FALSE)
|
|
23
22
|
# robot_index :boolean default(TRUE)
|
|
@@ -44,11 +43,10 @@ module Alchemy
|
|
|
44
43
|
|
|
45
44
|
DEFAULT_ATTRIBUTES_FOR_COPY = {
|
|
46
45
|
autogenerate_elements: false,
|
|
47
|
-
visible: false,
|
|
48
46
|
public_on: nil,
|
|
49
47
|
public_until: nil,
|
|
50
48
|
locked_at: nil,
|
|
51
|
-
locked_by: nil
|
|
49
|
+
locked_by: nil,
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
SKIPPED_ATTRIBUTES_ON_COPY = %w(
|
|
@@ -78,16 +76,15 @@ module Alchemy
|
|
|
78
76
|
:tag_list,
|
|
79
77
|
:title,
|
|
80
78
|
:urlname,
|
|
81
|
-
:visible,
|
|
82
79
|
:layoutpage,
|
|
83
|
-
:menu_id
|
|
80
|
+
:menu_id,
|
|
84
81
|
]
|
|
85
82
|
|
|
86
|
-
acts_as_nested_set(dependent: :destroy)
|
|
83
|
+
acts_as_nested_set(dependent: :destroy, scope: [:layoutpage, :language_id])
|
|
87
84
|
|
|
88
|
-
stampable stamper_class_name: Alchemy.
|
|
85
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
|
89
86
|
|
|
90
|
-
belongs_to :language
|
|
87
|
+
belongs_to :language
|
|
91
88
|
|
|
92
89
|
belongs_to :creator,
|
|
93
90
|
primary_key: Alchemy.user_class_primary_key,
|
|
@@ -110,43 +107,33 @@ module Alchemy
|
|
|
110
107
|
has_one :site, through: :language
|
|
111
108
|
has_many :site_languages, through: :site, source: :languages
|
|
112
109
|
has_many :folded_pages
|
|
113
|
-
has_many :legacy_urls, class_name:
|
|
114
|
-
has_many :nodes, class_name:
|
|
110
|
+
has_many :legacy_urls, class_name: "Alchemy::LegacyPageUrl"
|
|
111
|
+
has_many :nodes, class_name: "Alchemy::Node", inverse_of: :page
|
|
115
112
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
validates_presence_of :
|
|
113
|
+
before_validation :set_language,
|
|
114
|
+
if: -> { language.nil? }
|
|
115
|
+
|
|
116
|
+
validates_presence_of :page_layout
|
|
117
|
+
validates_format_of :page_layout, with: /\A[a-z0-9_-]+\z/, unless: -> { page_layout.blank? }
|
|
118
|
+
validates_presence_of :parent, unless: -> { layoutpage? || language_root? }
|
|
120
119
|
|
|
121
120
|
before_save :set_language_code,
|
|
122
|
-
if: -> { language.present? }
|
|
123
|
-
unless: :systempage?
|
|
121
|
+
if: -> { language.present? }
|
|
124
122
|
|
|
125
123
|
before_save :set_restrictions_to_child_pages,
|
|
126
|
-
if: :restricted_changed
|
|
127
|
-
unless: :systempage?
|
|
124
|
+
if: :restricted_changed?
|
|
128
125
|
|
|
129
126
|
before_save :inherit_restricted_status,
|
|
130
|
-
if: -> { parent && parent.restricted? }
|
|
131
|
-
unless: :systempage?
|
|
127
|
+
if: -> { parent && parent.restricted? }
|
|
132
128
|
|
|
133
129
|
before_save :set_published_at,
|
|
134
|
-
if: -> { public_on.present? && published_at.nil? }
|
|
135
|
-
unless: :systempage?
|
|
130
|
+
if: -> { public_on.present? && published_at.nil? }
|
|
136
131
|
|
|
137
132
|
before_save :set_fixed_attributes,
|
|
138
133
|
if: -> { fixed_attributes.any? }
|
|
139
134
|
|
|
140
|
-
before_create :set_language_from_parent_or_default,
|
|
141
|
-
if: -> { language_id.blank? },
|
|
142
|
-
unless: :systempage?
|
|
143
|
-
|
|
144
135
|
after_update :create_legacy_url,
|
|
145
|
-
if: :
|
|
146
|
-
unless: -> { definition['redirects_to_external'] }
|
|
147
|
-
|
|
148
|
-
after_update :attach_to_menu!,
|
|
149
|
-
if: :should_attach_to_menu?
|
|
136
|
+
if: :saved_change_to_urlname?
|
|
150
137
|
|
|
151
138
|
after_update -> { nodes.update_all(updated_at: Time.current) }
|
|
152
139
|
|
|
@@ -159,26 +146,9 @@ module Alchemy
|
|
|
159
146
|
# site_name accessor
|
|
160
147
|
delegate :name, to: :site, prefix: true, allow_nil: true
|
|
161
148
|
|
|
162
|
-
attr_accessor :menu_id
|
|
163
|
-
|
|
164
|
-
deprecate visible: "Page slugs will be visible in URLs of child pages all the time. " \
|
|
165
|
-
"Please use Menus and Tags instead to re-organize your pages if your page tree does not reflect the URL hierarchy.",
|
|
166
|
-
deprecator: Alchemy::Deprecation
|
|
167
|
-
|
|
168
149
|
# Class methods
|
|
169
150
|
#
|
|
170
151
|
class << self
|
|
171
|
-
# The root page of the page tree
|
|
172
|
-
#
|
|
173
|
-
# Internal use only. You wouldn't use this page ever.
|
|
174
|
-
#
|
|
175
|
-
# Automatically created when accessed the first time.
|
|
176
|
-
#
|
|
177
|
-
def root
|
|
178
|
-
super || create!(name: 'Root')
|
|
179
|
-
end
|
|
180
|
-
alias_method :rootpage, :root
|
|
181
|
-
|
|
182
152
|
# Used to store the current page previewed in the edit page template.
|
|
183
153
|
#
|
|
184
154
|
def current_preview=(page)
|
|
@@ -222,29 +192,12 @@ module Alchemy
|
|
|
222
192
|
end
|
|
223
193
|
end
|
|
224
194
|
|
|
225
|
-
def layout_root_for(language_id)
|
|
226
|
-
where({parent_id: Page.root.id, layoutpage: true, language_id: language_id}).limit(1).first
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def find_or_create_layout_root_for(language_id)
|
|
230
|
-
layoutroot = layout_root_for(language_id)
|
|
231
|
-
return layoutroot if layoutroot
|
|
232
|
-
language = Language.find(language_id)
|
|
233
|
-
Page.create!(
|
|
234
|
-
name: "Layoutroot for #{language.name}",
|
|
235
|
-
layoutpage: true,
|
|
236
|
-
language: language,
|
|
237
|
-
autogenerate_elements: false,
|
|
238
|
-
parent_id: Page.root.id
|
|
239
|
-
)
|
|
240
|
-
end
|
|
241
|
-
|
|
242
195
|
def copy_and_paste(source, new_parent, new_name)
|
|
243
196
|
page = copy(source, {
|
|
244
197
|
parent_id: new_parent.id,
|
|
245
198
|
language: new_parent.language,
|
|
246
199
|
name: new_name,
|
|
247
|
-
title: new_name
|
|
200
|
+
title: new_name,
|
|
248
201
|
})
|
|
249
202
|
if source.children.any?
|
|
250
203
|
source.copy_children_to(page)
|
|
@@ -254,34 +207,29 @@ module Alchemy
|
|
|
254
207
|
|
|
255
208
|
def all_from_clipboard(clipboard)
|
|
256
209
|
return [] if clipboard.blank?
|
|
257
|
-
|
|
210
|
+
|
|
211
|
+
where(id: clipboard.collect { |p| p["id"] })
|
|
258
212
|
end
|
|
259
213
|
|
|
260
214
|
def all_from_clipboard_for_select(clipboard, language_id, layoutpage = false)
|
|
261
215
|
return [] if clipboard.blank?
|
|
216
|
+
|
|
262
217
|
clipboard_pages = all_from_clipboard(clipboard)
|
|
263
218
|
allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage)
|
|
264
|
-
allowed_page_layout_names = allowed_page_layouts.collect { |p| p[
|
|
219
|
+
allowed_page_layout_names = allowed_page_layouts.collect { |p| p["name"] }
|
|
265
220
|
clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) }
|
|
266
221
|
end
|
|
267
222
|
|
|
268
223
|
def link_target_options
|
|
269
|
-
options = [[Alchemy.t(:default, scope:
|
|
224
|
+
options = [[Alchemy.t(:default, scope: "link_target_options"), ""]]
|
|
270
225
|
link_target_options = Config.get(:link_target_options)
|
|
271
226
|
link_target_options.each do |option|
|
|
272
|
-
options << [Alchemy.t(option, scope:
|
|
273
|
-
|
|
227
|
+
options << [Alchemy.t(option, scope: "link_target_options",
|
|
228
|
+
default: option.to_s.humanize), option]
|
|
274
229
|
end
|
|
275
230
|
options
|
|
276
231
|
end
|
|
277
232
|
|
|
278
|
-
# Returns an array of all pages in the same branch from current.
|
|
279
|
-
# I.e. used to find the active page in navigation.
|
|
280
|
-
def ancestors_for(current)
|
|
281
|
-
return [] if current.nil?
|
|
282
|
-
current.self_and_ancestors.contentpages
|
|
283
|
-
end
|
|
284
|
-
|
|
285
233
|
private
|
|
286
234
|
|
|
287
235
|
# Aggregates the attributes from given source for copy of page.
|
|
@@ -296,7 +244,7 @@ module Alchemy
|
|
|
296
244
|
differences.stringify_keys!
|
|
297
245
|
attributes = source.attributes.merge(differences)
|
|
298
246
|
attributes.merge!(DEFAULT_ATTRIBUTES_FOR_COPY)
|
|
299
|
-
attributes[
|
|
247
|
+
attributes["name"] = new_name_for_copy(differences["name"], source.name)
|
|
300
248
|
attributes.except(*SKIPPED_ATTRIBUTES_ON_COPY)
|
|
301
249
|
end
|
|
302
250
|
|
|
@@ -312,7 +260,8 @@ module Alchemy
|
|
|
312
260
|
#
|
|
313
261
|
def new_name_for_copy(custom_name, source_name)
|
|
314
262
|
return custom_name if custom_name.present?
|
|
315
|
-
|
|
263
|
+
|
|
264
|
+
"#{source_name} (#{Alchemy.t("Copy")})"
|
|
316
265
|
end
|
|
317
266
|
end
|
|
318
267
|
|
|
@@ -340,13 +289,7 @@ module Alchemy
|
|
|
340
289
|
# Use this for your custom element loading logic.
|
|
341
290
|
#
|
|
342
291
|
# @return [ActiveRecord::Relation]
|
|
343
|
-
def find_elements(options = {}
|
|
344
|
-
if show_non_public
|
|
345
|
-
Alchemy::Deprecation.warn "Passing true as second argument to page#find_elements to include" \
|
|
346
|
-
" invisible elements has been removed. Please implement your own ElementsFinder" \
|
|
347
|
-
" and pass it with options[:finder]."
|
|
348
|
-
end
|
|
349
|
-
|
|
292
|
+
def find_elements(options = {})
|
|
350
293
|
finder = options[:finder] || Alchemy::ElementsFinder.new(options)
|
|
351
294
|
finder.elements(page: self)
|
|
352
295
|
end
|
|
@@ -384,9 +327,10 @@ module Alchemy
|
|
|
384
327
|
# only public pages (true), skip public pages (false)
|
|
385
328
|
#
|
|
386
329
|
def previous(options = {})
|
|
387
|
-
pages = self_and_siblings.where(
|
|
330
|
+
pages = self_and_siblings.where("lft < ?", lft)
|
|
388
331
|
select_page(pages, options.merge(order: :desc))
|
|
389
332
|
end
|
|
333
|
+
|
|
390
334
|
alias_method :previous_page, :previous
|
|
391
335
|
|
|
392
336
|
# Returns the next page on the same level or nil.
|
|
@@ -397,9 +341,10 @@ module Alchemy
|
|
|
397
341
|
# only public pages (true), skip public pages (false)
|
|
398
342
|
#
|
|
399
343
|
def next(options = {})
|
|
400
|
-
pages = self_and_siblings.where(
|
|
344
|
+
pages = self_and_siblings.where("lft > ?", lft)
|
|
401
345
|
select_page(pages, options.merge(order: :asc))
|
|
402
346
|
end
|
|
347
|
+
|
|
403
348
|
alias_method :next_page, :next
|
|
404
349
|
|
|
405
350
|
# Locks the page to given user
|
|
@@ -445,9 +390,10 @@ module Alchemy
|
|
|
445
390
|
def copy_children_to(new_parent)
|
|
446
391
|
children.each do |child|
|
|
447
392
|
next if child == new_parent
|
|
393
|
+
|
|
448
394
|
new_child = Page.copy(child, {
|
|
449
395
|
language_id: new_parent.language_id,
|
|
450
|
-
language_code: new_parent.language_code
|
|
396
|
+
language_code: new_parent.language_code,
|
|
451
397
|
})
|
|
452
398
|
new_child.move_to_child_of(new_parent)
|
|
453
399
|
child.copy_children_to(new_child) unless child.children.blank?
|
|
@@ -466,22 +412,22 @@ module Alchemy
|
|
|
466
412
|
update_columns(
|
|
467
413
|
published_at: current_time,
|
|
468
414
|
public_on: already_public_for?(current_time) ? public_on : current_time,
|
|
469
|
-
public_until: still_public_for?(current_time) ? public_until : nil
|
|
415
|
+
public_until: still_public_for?(current_time) ? public_until : nil,
|
|
470
416
|
)
|
|
471
417
|
end
|
|
472
418
|
|
|
473
419
|
# Updates an Alchemy::Page based on a new ordering to be applied to it
|
|
474
420
|
#
|
|
475
421
|
# Note: Page's urls should not be updated (and a legacy URL created) if nesting is OFF
|
|
476
|
-
# or if
|
|
422
|
+
# or if the URL is the same
|
|
477
423
|
#
|
|
478
424
|
# @param [TreeNode]
|
|
479
425
|
# A tree node with new lft, rgt, depth, url, parent_id and restricted indexes to be updated
|
|
480
426
|
#
|
|
481
427
|
def update_node!(node)
|
|
482
|
-
hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
|
|
428
|
+
hash = { lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted }
|
|
483
429
|
|
|
484
|
-
if
|
|
430
|
+
if urlname != node.url
|
|
485
431
|
LegacyPageUrl.create(page_id: id, urlname: urlname)
|
|
486
432
|
hash[:urlname] = node.url
|
|
487
433
|
end
|
|
@@ -506,6 +452,7 @@ module Alchemy
|
|
|
506
452
|
#
|
|
507
453
|
def editable_by?(user)
|
|
508
454
|
return true unless has_limited_editors?
|
|
455
|
+
|
|
509
456
|
(editor_roles & user.alchemy_roles).any?
|
|
510
457
|
end
|
|
511
458
|
|
|
@@ -531,7 +478,7 @@ module Alchemy
|
|
|
531
478
|
# does not respond to +#name+ it returns +'unknown'+
|
|
532
479
|
#
|
|
533
480
|
def creator_name
|
|
534
|
-
creator.try(:name) || Alchemy.t(
|
|
481
|
+
creator.try(:name) || Alchemy.t("unknown")
|
|
535
482
|
end
|
|
536
483
|
|
|
537
484
|
# Returns the name of the last updater of this page.
|
|
@@ -540,7 +487,7 @@ module Alchemy
|
|
|
540
487
|
# does not respond to +#name+ it returns +'unknown'+
|
|
541
488
|
#
|
|
542
489
|
def updater_name
|
|
543
|
-
updater.try(:name) || Alchemy.t(
|
|
490
|
+
updater.try(:name) || Alchemy.t("unknown")
|
|
544
491
|
end
|
|
545
492
|
|
|
546
493
|
# Returns the name of the user currently editing this page.
|
|
@@ -549,7 +496,7 @@ module Alchemy
|
|
|
549
496
|
# does not respond to +#name+ it returns +'unknown'+
|
|
550
497
|
#
|
|
551
498
|
def locker_name
|
|
552
|
-
locker.try(:name) || Alchemy.t(
|
|
499
|
+
locker.try(:name) || Alchemy.t("unknown")
|
|
553
500
|
end
|
|
554
501
|
|
|
555
502
|
# Menus (aka. root nodes) this page is attached to
|
|
@@ -573,8 +520,8 @@ module Alchemy
|
|
|
573
520
|
.limit(1).first
|
|
574
521
|
end
|
|
575
522
|
|
|
576
|
-
def
|
|
577
|
-
self.language = parent
|
|
523
|
+
def set_language
|
|
524
|
+
self.language = parent&.language || Language.current
|
|
578
525
|
set_language_code
|
|
579
526
|
end
|
|
580
527
|
|
|
@@ -582,41 +529,13 @@ module Alchemy
|
|
|
582
529
|
self.language_code = language.code
|
|
583
530
|
end
|
|
584
531
|
|
|
585
|
-
def should_create_legacy_url?
|
|
586
|
-
if active_record_5_1?
|
|
587
|
-
saved_change_to_urlname?
|
|
588
|
-
else
|
|
589
|
-
urlname_changed?
|
|
590
|
-
end
|
|
591
|
-
end
|
|
592
|
-
|
|
593
532
|
# Stores the old urlname in a LegacyPageUrl
|
|
594
533
|
def create_legacy_url
|
|
595
|
-
|
|
596
|
-
former_urlname = urlname_before_last_save
|
|
597
|
-
else
|
|
598
|
-
former_urlname = urlname_was
|
|
599
|
-
end
|
|
600
|
-
legacy_urls.find_or_create_by(urlname: former_urlname)
|
|
534
|
+
legacy_urls.find_or_create_by(urlname: urlname_before_last_save)
|
|
601
535
|
end
|
|
602
536
|
|
|
603
537
|
def set_published_at
|
|
604
538
|
self.published_at = Time.current
|
|
605
539
|
end
|
|
606
|
-
|
|
607
|
-
def attach_to_menu!
|
|
608
|
-
current_site_id = Alchemy::Site.current.id
|
|
609
|
-
node = Alchemy::Node.find_by!(id: menu_id, site_id: current_site_id)
|
|
610
|
-
node.children.create!(
|
|
611
|
-
site_id: current_site_id,
|
|
612
|
-
language_id: language_id,
|
|
613
|
-
page_id: id,
|
|
614
|
-
name: name
|
|
615
|
-
)
|
|
616
|
-
end
|
|
617
|
-
|
|
618
|
-
def should_attach_to_menu?
|
|
619
|
-
menu_id.present? && nodes.none?
|
|
620
|
-
end
|
|
621
540
|
end
|
|
622
541
|
end
|
|
@@ -49,6 +49,7 @@ module Alchemy
|
|
|
49
49
|
#
|
|
50
50
|
def crop(size, crop_from = nil, crop_size = nil, upsample = false)
|
|
51
51
|
raise "No size given!" if size.empty?
|
|
52
|
+
|
|
52
53
|
render_to = sizes_from_string(size)
|
|
53
54
|
if crop_from && crop_size
|
|
54
55
|
top_left = point_from_string(crop_from)
|
|
@@ -79,7 +80,7 @@ module Alchemy
|
|
|
79
80
|
height = 0 if height.nil?
|
|
80
81
|
{
|
|
81
82
|
width: width,
|
|
82
|
-
height: height
|
|
83
|
+
height: height,
|
|
83
84
|
}
|
|
84
85
|
end
|
|
85
86
|
|
|
@@ -109,7 +110,7 @@ module Alchemy
|
|
|
109
110
|
def image_size
|
|
110
111
|
{
|
|
111
112
|
width: image_file_width,
|
|
112
|
-
height: image_file_height
|
|
113
|
+
height: image_file_height,
|
|
113
114
|
}
|
|
114
115
|
end
|
|
115
116
|
|
|
@@ -118,6 +119,7 @@ module Alchemy
|
|
|
118
119
|
#
|
|
119
120
|
def can_be_cropped_to(string, upsample = false)
|
|
120
121
|
return true if upsample
|
|
122
|
+
|
|
121
123
|
is_bigger_than sizes_from_string(string)
|
|
122
124
|
end
|
|
123
125
|
|
|
@@ -147,7 +149,7 @@ module Alchemy
|
|
|
147
149
|
y = 0 if y.nil?
|
|
148
150
|
{
|
|
149
151
|
x: x,
|
|
150
|
-
y: y
|
|
152
|
+
y: y,
|
|
151
153
|
}
|
|
152
154
|
end
|
|
153
155
|
|
|
@@ -158,7 +160,7 @@ module Alchemy
|
|
|
158
160
|
def get_top_left_crop_corner(dimensions)
|
|
159
161
|
{
|
|
160
162
|
x: (image_file_width - dimensions[:width]) / 2,
|
|
161
|
-
y: (image_file_height - dimensions[:height]) / 2
|
|
163
|
+
y: (image_file_height - dimensions[:height]) / 2,
|
|
162
164
|
}
|
|
163
165
|
end
|
|
164
166
|
|
|
@@ -182,7 +184,7 @@ module Alchemy
|
|
|
182
184
|
def size_when_fitting(target, dimensions = get_base_dimensions)
|
|
183
185
|
zoom = [
|
|
184
186
|
dimensions[:width].to_f / target[:width],
|
|
185
|
-
dimensions[:height].to_f / target[:height]
|
|
187
|
+
dimensions[:height].to_f / target[:height],
|
|
186
188
|
].max
|
|
187
189
|
|
|
188
190
|
if zoom == 0.0
|
|
@@ -205,7 +207,7 @@ module Alchemy
|
|
|
205
207
|
x1: point[:x],
|
|
206
208
|
y1: point[:y],
|
|
207
209
|
x2: point[:x] + mask[:width],
|
|
208
|
-
y2: point[:y] + mask[:height]
|
|
210
|
+
y2: point[:y] + mask[:height],
|
|
209
211
|
}
|
|
210
212
|
end
|
|
211
213
|
|
|
@@ -252,7 +254,7 @@ module Alchemy
|
|
|
252
254
|
def reduce_to_image(dimensions)
|
|
253
255
|
{
|
|
254
256
|
width: [dimensions[:width], image_file_width].min,
|
|
255
|
-
height: [dimensions[:height], image_file_height].min
|
|
257
|
+
height: [dimensions[:height], image_file_height].min,
|
|
256
258
|
}
|
|
257
259
|
end
|
|
258
260
|
end
|
|
@@ -12,7 +12,7 @@ module Alchemy
|
|
|
12
12
|
:format,
|
|
13
13
|
:quality,
|
|
14
14
|
:size,
|
|
15
|
-
:upsample
|
|
15
|
+
:upsample,
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
# Returns a path to picture for use inside a image_tag helper.
|
|
@@ -66,8 +66,8 @@ module Alchemy
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
options = {
|
|
69
|
-
flatten: target_format !=
|
|
70
|
-
}.merge(options)
|
|
69
|
+
flatten: target_format != "gif" && image_file_format == "gif",
|
|
70
|
+
}.with_indifferent_access.merge(options)
|
|
71
71
|
|
|
72
72
|
encoding_options = []
|
|
73
73
|
|
|
@@ -77,13 +77,13 @@ module Alchemy
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
if options[:flatten]
|
|
80
|
-
encoding_options <<
|
|
80
|
+
encoding_options << "-flatten"
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
convertion_needed = target_format != image_file_format || encoding_options.present?
|
|
84
84
|
|
|
85
85
|
if has_convertible_format? && convertion_needed
|
|
86
|
-
image = image.encode(target_format, encoding_options.join(
|
|
86
|
+
image = image.encode(target_format, encoding_options.join(" "))
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
image
|
|
@@ -26,13 +26,13 @@ module Alchemy
|
|
|
26
26
|
|
|
27
27
|
include Alchemy::NameConversions
|
|
28
28
|
include Alchemy::Taggable
|
|
29
|
-
include Alchemy::
|
|
29
|
+
include Alchemy::TouchElements
|
|
30
30
|
include Alchemy::Picture::Transformations
|
|
31
31
|
include Alchemy::Picture::Url
|
|
32
32
|
|
|
33
33
|
has_many :essence_pictures,
|
|
34
|
-
class_name:
|
|
35
|
-
foreign_key:
|
|
34
|
+
class_name: "Alchemy::EssencePicture",
|
|
35
|
+
foreign_key: "picture_id",
|
|
36
36
|
inverse_of: :ingredient_association
|
|
37
37
|
|
|
38
38
|
has_many :contents, through: :essence_pictures
|
|
@@ -62,35 +62,24 @@ module Alchemy
|
|
|
62
62
|
# We need to define this method here to have it available in the validations below.
|
|
63
63
|
class << self
|
|
64
64
|
def allowed_filetypes
|
|
65
|
-
Config.get(:uploader).fetch(
|
|
65
|
+
Config.get(:uploader).fetch("allowed_filetypes", {}).fetch("alchemy/pictures", [])
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
validates_presence_of :image_file
|
|
70
|
-
validates_size_of :image_file, maximum: Config.get(:uploader)[
|
|
70
|
+
validates_size_of :image_file, maximum: Config.get(:uploader)["file_size_limit"].megabytes
|
|
71
71
|
validates_property :format,
|
|
72
72
|
of: :image_file,
|
|
73
73
|
in: allowed_filetypes,
|
|
74
74
|
case_sensitive: false,
|
|
75
75
|
message: Alchemy.t("not a valid image")
|
|
76
76
|
|
|
77
|
-
stampable stamper_class_name: Alchemy.
|
|
77
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
|
78
78
|
|
|
79
|
-
scope :named, ->(name) {
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
scope :recent, -> {
|
|
84
|
-
where("#{table_name}.created_at > ?", Time.current - 24.hours).order(:created_at)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
scope :deletable, -> {
|
|
88
|
-
where("#{table_name}.id NOT IN (SELECT picture_id FROM #{EssencePicture.table_name})")
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
scope :without_tag, -> {
|
|
92
|
-
left_outer_joins(:taggings).where(gutentag_taggings: {id: nil})
|
|
93
|
-
}
|
|
79
|
+
scope :named, ->(name) { where("#{table_name}.name LIKE ?", "%#{name}%") }
|
|
80
|
+
scope :recent, -> { where("#{table_name}.created_at > ?", Time.current - 24.hours).order(:created_at) }
|
|
81
|
+
scope :deletable, -> { where("#{table_name}.id NOT IN (SELECT picture_id FROM #{EssencePicture.table_name})") }
|
|
82
|
+
scope :without_tag, -> { left_outer_joins(:taggings).where(gutentag_taggings: { id: nil }) }
|
|
94
83
|
|
|
95
84
|
# Class methods
|
|
96
85
|
|
|
@@ -102,6 +91,7 @@ module Alchemy
|
|
|
102
91
|
def last_upload
|
|
103
92
|
last_picture = Picture.last
|
|
104
93
|
return Picture.all unless last_picture
|
|
94
|
+
|
|
105
95
|
Picture.where(upload_hash: last_picture.upload_hash)
|
|
106
96
|
end
|
|
107
97
|
|
|
@@ -123,11 +113,11 @@ module Alchemy
|
|
|
123
113
|
pictures.order(:name)
|
|
124
114
|
end
|
|
125
115
|
|
|
126
|
-
def filtered_by(filter =
|
|
116
|
+
def filtered_by(filter = "")
|
|
127
117
|
case filter
|
|
128
|
-
when
|
|
129
|
-
when
|
|
130
|
-
when
|
|
118
|
+
when "recent" then recent
|
|
119
|
+
when "last_upload" then last_upload
|
|
120
|
+
when "without_tag" then without_tag
|
|
131
121
|
else
|
|
132
122
|
all
|
|
133
123
|
end
|
|
@@ -166,7 +156,7 @@ module Alchemy
|
|
|
166
156
|
{
|
|
167
157
|
name: image_file_name,
|
|
168
158
|
size: image_file_size,
|
|
169
|
-
error: errors[:image_file].join
|
|
159
|
+
error: errors[:image_file].join,
|
|
170
160
|
}
|
|
171
161
|
end
|
|
172
162
|
|
|
@@ -176,7 +166,7 @@ module Alchemy
|
|
|
176
166
|
if name.blank?
|
|
177
167
|
"image_#{id}"
|
|
178
168
|
else
|
|
179
|
-
::CGI.escape(name.gsub(/\.(gif|png|jpe?g|tiff?)/i,
|
|
169
|
+
::CGI.escape(name.gsub(/\.(gif|png|jpe?g|tiff?)/i, "").tr(".", " "))
|
|
180
170
|
end
|
|
181
171
|
end
|
|
182
172
|
|
|
@@ -190,6 +180,7 @@ module Alchemy
|
|
|
190
180
|
#
|
|
191
181
|
def humanized_name
|
|
192
182
|
return "" if image_file_name.blank?
|
|
183
|
+
|
|
193
184
|
convert_to_humanized_name(image_file_name, suffix)
|
|
194
185
|
end
|
|
195
186
|
|
|
@@ -213,7 +204,7 @@ module Alchemy
|
|
|
213
204
|
#
|
|
214
205
|
def convertible?
|
|
215
206
|
Config.get(:image_output_format) &&
|
|
216
|
-
Config.get(:image_output_format) !=
|
|
207
|
+
Config.get(:image_output_format) != "original" &&
|
|
217
208
|
has_convertible_format?
|
|
218
209
|
end
|
|
219
210
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Alchemy
|
|
4
4
|
module Site::Layout
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
|
-
SITE_DEFINITIONS_FILE = Rails.root.join(
|
|
6
|
+
SITE_DEFINITIONS_FILE = Rails.root.join("config/alchemy/site_layouts.yml")
|
|
7
7
|
|
|
8
8
|
module ClassMethods
|
|
9
9
|
# Returns the site layouts definition defined in +site_layouts.yml+ file
|
|
@@ -28,7 +28,7 @@ module Alchemy
|
|
|
28
28
|
# Returns site's layout definition
|
|
29
29
|
#
|
|
30
30
|
def definition
|
|
31
|
-
self.class.definitions.detect { |l| l[
|
|
31
|
+
self.class.definitions.detect { |l| l["name"] == partial_name }
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
# Returns the name for the layout partial
|
data/app/models/alchemy/site.rb
CHANGED
|
@@ -23,10 +23,12 @@ module Alchemy
|
|
|
23
23
|
# associations
|
|
24
24
|
has_many :languages
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
before_destroy if: -> { languages.any? } do
|
|
27
|
+
errors.add(:languages, :still_present)
|
|
28
|
+
throw(:abort)
|
|
29
|
+
end
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
before_create :create_default_language!, unless: -> { languages.any? }
|
|
31
|
+
scope :published, -> { where(public: true) }
|
|
30
32
|
|
|
31
33
|
# concerns
|
|
32
34
|
include Alchemy::Site::Layout
|
|
@@ -64,7 +66,7 @@ module Alchemy
|
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
def default
|
|
67
|
-
Site.first
|
|
69
|
+
Site.first
|
|
68
70
|
end
|
|
69
71
|
|
|
70
72
|
def find_for_host(host)
|
|
@@ -81,38 +83,6 @@ module Alchemy
|
|
|
81
83
|
site.aliases.split.include?(host) if site.aliases.present?
|
|
82
84
|
end
|
|
83
85
|
end
|
|
84
|
-
|
|
85
|
-
private
|
|
86
|
-
|
|
87
|
-
def create_default_site!
|
|
88
|
-
default_site = Alchemy::Config.get(:default_site)
|
|
89
|
-
if default_site
|
|
90
|
-
create!(name: default_site['name'], host: default_site['host'])
|
|
91
|
-
else
|
|
92
|
-
raise DefaultSiteNotFoundError
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
private
|
|
98
|
-
|
|
99
|
-
# If no languages are present, create a default language based
|
|
100
|
-
# on the host app's Alchemy configuration.
|
|
101
|
-
def create_default_language!
|
|
102
|
-
default_language = Alchemy::Config.get(:default_language)
|
|
103
|
-
if default_language
|
|
104
|
-
languages.build(
|
|
105
|
-
name: default_language['name'],
|
|
106
|
-
language_code: default_language['code'],
|
|
107
|
-
locale: default_language['code'],
|
|
108
|
-
frontpage_name: default_language['frontpage_name'],
|
|
109
|
-
page_layout: default_language['page_layout'],
|
|
110
|
-
public: true,
|
|
111
|
-
default: true
|
|
112
|
-
)
|
|
113
|
-
else
|
|
114
|
-
raise DefaultLanguageNotFoundError
|
|
115
|
-
end
|
|
116
86
|
end
|
|
117
87
|
end
|
|
118
88
|
end
|