alchemy_cms 7.1.13 → 7.2.0.b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +132 -39
- data/Gemfile +2 -11
- data/LICENSE +1 -1
- data/README.md +5 -6
- data/SECURITY.md +1 -1
- data/alchemy_cms.gemspec +3 -4
- data/app/assets/javascripts/alchemy/admin.js +0 -9
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +5 -15
- data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +5 -4
- data/app/assets/javascripts/alchemy/templates/index.js +0 -1
- data/app/assets/javascripts/alchemy/templates/node_folder.hbs +1 -1
- data/app/assets/javascripts/alchemy/templates/page_folder.hbs +1 -1
- data/app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js +20 -7
- data/app/assets/stylesheets/alchemy/_custom-properties.scss +12 -0
- data/app/assets/stylesheets/alchemy/_mixins.scss +10 -6
- data/app/assets/stylesheets/alchemy/_variables.scss +3 -0
- data/app/assets/stylesheets/alchemy/admin.scss +2 -2
- data/app/assets/stylesheets/alchemy/archive.scss +4 -3
- data/app/assets/stylesheets/alchemy/attachment-select.scss +19 -0
- data/app/assets/stylesheets/alchemy/base.scss +31 -18
- data/app/assets/stylesheets/alchemy/buttons.scss +3 -4
- data/app/assets/stylesheets/alchemy/dashboard.scss +1 -1
- data/app/assets/stylesheets/alchemy/dialogs.scss +2 -5
- data/app/assets/stylesheets/alchemy/elements.scss +74 -42
- data/app/assets/stylesheets/alchemy/flash.scss +20 -70
- data/app/assets/stylesheets/alchemy/forms.scss +41 -36
- data/app/assets/stylesheets/alchemy/frame.scss +12 -3
- data/app/assets/stylesheets/alchemy/icons.scss +34 -2
- data/app/assets/stylesheets/alchemy/image_library.scss +18 -9
- data/app/assets/stylesheets/alchemy/{filter_field.scss → list_filter.scss} +8 -7
- data/app/assets/stylesheets/alchemy/lists.scss +1 -1
- data/app/assets/stylesheets/alchemy/navigation.scss +9 -12
- data/app/assets/stylesheets/alchemy/node-select.scss +1 -1
- data/app/assets/stylesheets/alchemy/nodes.scss +15 -13
- data/app/assets/stylesheets/alchemy/notices.scss +56 -39
- data/app/assets/stylesheets/alchemy/page-select.scss +1 -4
- data/app/assets/stylesheets/alchemy/pagination.scss +11 -1
- data/app/assets/stylesheets/alchemy/preview_window.scss +3 -3
- data/app/assets/stylesheets/alchemy/search.scss +4 -4
- data/app/assets/stylesheets/alchemy/selects.scss +13 -7
- data/app/assets/stylesheets/alchemy/shoelace.scss +33 -2
- data/app/assets/stylesheets/alchemy/sitemap.scss +155 -159
- data/app/assets/stylesheets/alchemy/tables.scss +49 -12
- data/app/assets/stylesheets/alchemy/tags.scss +17 -11
- data/app/assets/stylesheets/alchemy/toolbar.scss +2 -2
- data/app/assets/stylesheets/alchemy/typography.scss +41 -22
- data/app/assets/stylesheets/alchemy/upload.scss +5 -4
- data/app/components/alchemy/admin/attachment_select.rb +39 -0
- data/app/components/alchemy/admin/icon.rb +72 -0
- data/app/components/alchemy/admin/link_dialog/anchor_tab.rb +41 -0
- data/app/components/alchemy/admin/link_dialog/base_tab.rb +75 -0
- data/app/components/alchemy/admin/link_dialog/external_tab.rb +42 -0
- data/app/components/alchemy/admin/link_dialog/file_tab.rb +45 -0
- data/app/components/alchemy/admin/link_dialog/internal_tab.rb +66 -0
- data/app/components/alchemy/admin/link_dialog/tabs.rb +33 -0
- data/app/components/alchemy/admin/list_filter.rb +42 -0
- data/app/components/alchemy/admin/message.rb +19 -0
- data/app/components/alchemy/admin/tags_autocomplete.rb +25 -0
- data/app/components/alchemy/admin/toolbar_button.rb +111 -0
- data/app/components/alchemy/ingredients/datetime_view.rb +2 -3
- data/app/components/alchemy/ingredients/link_view.rb +1 -7
- data/app/components/alchemy/ingredients/picture_view.rb +2 -2
- data/app/components/alchemy/ingredients/text_view.rb +1 -2
- data/app/controllers/alchemy/admin/base_controller.rb +3 -27
- data/app/controllers/alchemy/admin/elements_controller.rb +4 -2
- data/app/controllers/alchemy/admin/ingredients_controller.rb +2 -0
- data/app/controllers/alchemy/admin/languages_controller.rb +2 -2
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -19
- data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +12 -4
- data/app/controllers/alchemy/admin/nodes_controller.rb +26 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +16 -79
- data/app/controllers/alchemy/admin/picture_descriptions_controller.rb +15 -0
- data/app/controllers/alchemy/admin/pictures_controller.rb +18 -1
- data/app/controllers/alchemy/admin/resources_controller.rb +16 -11
- data/app/controllers/alchemy/api/attachments_controller.rb +44 -0
- data/app/controllers/alchemy/api/pages_controller.rb +10 -6
- data/app/controllers/alchemy/base_controller.rb +2 -2
- data/app/controllers/alchemy/messages_controller.rb +3 -3
- data/app/controllers/alchemy/pages_controller.rb +8 -6
- data/app/controllers/concerns/alchemy/admin/current_language.rb +1 -11
- data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +1 -1
- data/app/decorators/alchemy/element_editor.rb +2 -2
- data/app/helpers/alchemy/admin/base_helper.rb +8 -60
- data/app/helpers/alchemy/admin/elements_helper.rb +1 -1
- data/app/helpers/alchemy/admin/ingredients_helper.rb +1 -1
- data/app/helpers/alchemy/base_helper.rb +9 -91
- data/app/helpers/alchemy/elements_helper.rb +3 -3
- data/app/helpers/alchemy/pages_helper.rb +16 -9
- data/app/javascript/alchemy_admin/components/attachment_select.js +24 -0
- data/app/javascript/alchemy_admin/components/button.js +3 -0
- data/app/javascript/alchemy_admin/components/clipboard_button.js +3 -2
- data/app/javascript/alchemy_admin/components/dialog_link.js +10 -7
- data/app/javascript/alchemy_admin/components/dom_id_select.js +69 -0
- data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +42 -0
- data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +4 -2
- data/app/javascript/alchemy_admin/components/element_editor.js +21 -13
- data/app/javascript/alchemy_admin/components/elements_window.js +87 -0
- data/app/javascript/alchemy_admin/components/growl.js +13 -0
- data/app/javascript/alchemy_admin/components/icon.js +51 -0
- data/app/javascript/alchemy_admin/components/index.js +24 -0
- data/app/javascript/alchemy_admin/components/ingredient_group.js +6 -0
- data/app/javascript/alchemy_admin/components/link_buttons/link_button.js +21 -11
- data/app/javascript/alchemy_admin/components/link_buttons/unlink_button.js +2 -1
- data/app/javascript/alchemy_admin/components/link_buttons.js +1 -0
- data/app/javascript/alchemy_admin/components/list_filter.js +68 -0
- data/app/javascript/alchemy_admin/components/message.js +69 -0
- data/app/javascript/alchemy_admin/components/node_select.js +1 -1
- data/app/javascript/alchemy_admin/components/overlay.js +6 -6
- data/app/javascript/alchemy_admin/components/page_select.js +3 -7
- data/app/javascript/alchemy_admin/components/preview_window.js +121 -0
- data/app/javascript/alchemy_admin/components/remote_select.js +4 -1
- data/app/javascript/alchemy_admin/components/select.js +37 -1
- data/app/javascript/alchemy_admin/components/tags_autocomplete.js +57 -0
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +4 -3
- data/app/javascript/alchemy_admin/components/uploader/progress.js +1 -1
- data/app/javascript/alchemy_admin/confirm_dialog.js +133 -0
- data/app/javascript/alchemy_admin/dirty.js +19 -14
- data/app/javascript/alchemy_admin/fixed_elements.js +24 -0
- data/app/javascript/alchemy_admin/growler.js +15 -0
- data/app/javascript/alchemy_admin/gui.js +2 -4
- data/app/javascript/alchemy_admin/hotkeys.js +60 -0
- data/app/javascript/alchemy_admin/image_loader.js +2 -2
- data/app/javascript/alchemy_admin/ingredient_anchor_link.js +2 -3
- data/app/javascript/alchemy_admin/initializer.js +1 -8
- data/app/javascript/alchemy_admin/link_dialog.js +131 -0
- data/app/javascript/alchemy_admin/locales/en.js +3 -0
- data/app/javascript/alchemy_admin/node_tree.js +4 -3
- data/app/javascript/alchemy_admin/page_sorter.js +23 -14
- data/app/javascript/alchemy_admin/picture_editors.js +6 -5
- data/app/javascript/alchemy_admin/shoelace_theme.js +60 -0
- data/app/javascript/alchemy_admin/sitemap.js +9 -3
- data/app/javascript/alchemy_admin/sortable_elements.js +4 -6
- data/app/javascript/alchemy_admin.js +18 -42
- data/app/models/alchemy/current.rb +26 -0
- data/app/models/alchemy/element.rb +1 -1
- data/app/models/alchemy/ingredients/audio.rb +0 -11
- data/app/models/alchemy/ingredients/datetime.rb +1 -1
- data/app/models/alchemy/ingredients/headline.rb +8 -1
- data/app/models/alchemy/ingredients/picture.rb +6 -0
- data/app/models/alchemy/ingredients/video.rb +0 -12
- data/app/models/alchemy/language.rb +8 -6
- data/app/models/alchemy/node.rb +2 -2
- data/app/models/alchemy/page/page_elements.rb +8 -8
- data/app/models/alchemy/page/page_layouts.rb +3 -3
- data/app/models/alchemy/page/page_natures.rb +13 -9
- data/app/models/alchemy/page/page_scopes.rb +2 -2
- data/app/models/alchemy/page/publisher.rb +1 -0
- data/app/models/alchemy/page.rb +16 -31
- data/app/models/alchemy/picture.rb +8 -0
- data/app/models/alchemy/picture_description.rb +8 -0
- data/app/models/alchemy/picture_variant.rb +1 -1
- data/app/models/alchemy/site.rb +10 -7
- data/app/models/concerns/alchemy/picture_thumbnails.rb +5 -4
- data/app/serializers/alchemy/attachment_serializer.rb +8 -0
- data/app/serializers/alchemy/page_node_serializer.rb +9 -0
- data/app/views/alchemy/_menubar.html.erb +1 -1
- data/app/views/alchemy/_preview_mode_code.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -2
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
- data/app/views/alchemy/admin/attachments/edit.html.erb +3 -4
- data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
- data/app/views/alchemy/admin/clipboard/index.html.erb +1 -1
- data/app/views/alchemy/admin/clipboard/insert.js.erb +1 -1
- data/app/views/alchemy/admin/clipboard/remove.js.erb +1 -1
- data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/_sites.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/help.html.erb +48 -12
- data/app/views/alchemy/admin/dashboard/index.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/info.html.erb +5 -8
- data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element.html.erb +5 -5
- data/app/views/alchemy/admin/elements/_footer.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +6 -2
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +8 -6
- data/app/views/alchemy/admin/elements/create.js.erb +0 -5
- data/app/views/alchemy/admin/elements/index.html.erb +70 -34
- data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +1 -2
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +3 -5
- data/app/views/alchemy/admin/languages/_language.html.erb +1 -1
- data/app/views/alchemy/admin/languages/index.html.erb +2 -2
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +18 -18
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +4 -5
- data/app/views/alchemy/admin/layoutpages/index.html.erb +2 -2
- data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +10 -11
- data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +15 -17
- data/app/views/alchemy/admin/legacy_page_urls/_table.html.erb +16 -0
- data/app/views/alchemy/admin/legacy_page_urls/_update.turbo_stream.erb +12 -0
- data/app/views/alchemy/admin/legacy_page_urls/create.turbo_stream.erb +8 -0
- data/app/views/alchemy/admin/legacy_page_urls/destroy.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/legacy_page_urls/edit.html.erb +27 -0
- data/app/views/alchemy/admin/legacy_page_urls/show.html.erb +1 -0
- data/app/views/alchemy/admin/legacy_page_urls/update.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/nodes/_form.html.erb +12 -11
- data/app/views/alchemy/admin/nodes/_label.html.erb +1 -0
- data/app/views/alchemy/admin/nodes/_node.html.erb +19 -19
- data/app/views/alchemy/admin/nodes/_page_nodes.html.erb +48 -0
- data/app/views/alchemy/admin/nodes/_update.turbo_stream.erb +9 -0
- data/app/views/alchemy/admin/nodes/create.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/nodes/destroy.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/nodes/index.html.erb +3 -3
- data/app/views/alchemy/admin/pages/_form.html.erb +3 -4
- data/app/views/alchemy/admin/pages/_legacy_urls.html.erb +4 -15
- data/app/views/alchemy/admin/pages/_page.html.erb +39 -39
- data/app/views/alchemy/admin/pages/_table_row.html.erb +3 -3
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +2 -2
- data/app/views/alchemy/admin/pages/configure.html.erb +6 -0
- data/app/views/alchemy/admin/pages/edit.html.erb +15 -62
- data/app/views/alchemy/admin/pages/unlock.js.erb +3 -3
- data/app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb +3 -1
- data/app/views/alchemy/admin/partials/_flash_notices.html.erb +4 -2
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +5 -2
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +2 -2
- data/app/views/alchemy/admin/partials/_search_form.html.erb +2 -2
- data/app/views/alchemy/admin/partials/_site_select.html.erb +1 -1
- data/app/views/alchemy/admin/picture_descriptions/_form.html.erb +11 -0
- data/app/views/alchemy/admin/picture_descriptions/edit.html.erb +6 -0
- data/app/views/alchemy/admin/pictures/_form.html.erb +4 -3
- data/app/views/alchemy/admin/pictures/_infos.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_picture_description_field.html.erb +29 -0
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -2
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -2
- data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +3 -3
- data/app/views/alchemy/admin/pictures/show.html.erb +3 -3
- data/app/views/alchemy/admin/resources/_form.html.erb +3 -4
- data/app/views/alchemy/admin/resources/_per_page_select.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_tag_list.html.erb +2 -2
- data/app/views/alchemy/admin/resources/index.html.erb +2 -2
- data/app/views/alchemy/admin/sites/index.html.erb +1 -1
- data/app/views/alchemy/admin/styleguide/index.html.erb +29 -24
- data/app/views/alchemy/admin/tags/_tag.html.erb +1 -1
- data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
- data/app/views/alchemy/admin/tags/index.html.erb +1 -1
- data/app/views/alchemy/base/500.html.erb +7 -18
- data/app/views/alchemy/base/error_notice.html.erb +3 -1
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_datetime_editor.html.erb +2 -3
- data/app/views/alchemy/ingredients/_headline_editor.html.erb +13 -8
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +1 -1
- data/app/views/alchemy/language_links/_language.html.erb +1 -1
- data/app/views/kaminari/alchemy/_first_page.html.erb +2 -2
- data/app/views/kaminari/alchemy/_gap.html.erb +1 -1
- data/app/views/kaminari/alchemy/_last_page.html.erb +2 -2
- data/app/views/kaminari/alchemy/_next_page.html.erb +2 -2
- data/app/views/kaminari/alchemy/_prev_page.html.erb +2 -2
- data/app/views/layouts/alchemy/admin.html.erb +2 -1
- data/bundles/shoelace.js +3 -1
- data/config/locales/alchemy.en.yml +16 -3
- data/config/routes.rb +4 -2
- data/db/migrate/20240314105244_create_alchemy_picture_descriptions.rb +11 -0
- data/lib/alchemy/configuration_methods.rb +1 -1
- data/lib/alchemy/controller_actions.rb +3 -3
- data/lib/alchemy/element_definition.rb +10 -6
- data/lib/alchemy/engine.rb +19 -2
- data/lib/alchemy/page_layout.rb +10 -6
- data/lib/alchemy/permissions.rb +4 -3
- data/lib/alchemy/resource.rb +4 -14
- data/lib/alchemy/routing_constraints.rb +1 -1
- data/lib/alchemy/seeder.rb +2 -2
- data/lib/alchemy/test_support/capybara_helpers.rb +4 -0
- data/lib/alchemy/test_support/factories/language_factory.rb +1 -1
- data/lib/alchemy/test_support/shared_contexts.rb +8 -0
- data/lib/alchemy/tinymce.rb +2 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +36 -0
- data/lib/alchemy_cms.rb +0 -1
- data/lib/generators/alchemy/menus/templates/node.html.erb +2 -2
- data/lib/generators/alchemy/menus/templates/node.html.haml +2 -2
- data/lib/generators/alchemy/menus/templates/node.html.slim +2 -2
- data/lib/generators/alchemy/menus/templates/wrapper.html.erb +1 -1
- data/lib/generators/alchemy/menus/templates/wrapper.html.haml +1 -1
- data/lib/generators/alchemy/menus/templates/wrapper.html.slim +1 -1
- data/lib/tasks/alchemy/sitemap.rake +97 -0
- data/lib/tasks/alchemy/tidy.rake +1 -0
- data/package.json +8 -8
- data/vendor/assets/fonts/remixicon.symbol.svg +11 -0
- data/vendor/javascript/shoelace.min.js +333 -118
- data/vendor/javascript/sortable.min.js +1 -1
- data/vendor/javascript/tinymce.min.js +1 -1
- data/vendor/javascript/ungap-custom-elements.min.js +1 -1
- metadata +63 -55
- data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +0 -85
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +0 -107
- data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +0 -66
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +0 -45
- data/app/assets/javascripts/alchemy/alchemy.growler.js.coffee +0 -24
- data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +0 -49
- data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +0 -0
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +0 -230
- data/app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee +0 -49
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +0 -82
- data/app/assets/javascripts/alchemy/alchemy.string_extension.js.coffee +0 -11
- data/app/assets/javascripts/alchemy/templates/page.hbs +0 -19
- data/app/javascript/alchemy_admin/tags_autocomplete.js +0 -46
- data/app/models/alchemy/tree_node.rb +0 -7
- data/app/views/alchemy/admin/elements/destroy.js.erb +0 -8
- data/app/views/alchemy/admin/legacy_page_urls/_form.html.erb +0 -5
- data/app/views/alchemy/admin/legacy_page_urls/create.js.erb +0 -9
- data/app/views/alchemy/admin/legacy_page_urls/destroy.js.erb +0 -6
- data/app/views/alchemy/admin/legacy_page_urls/update.js.erb +0 -2
- data/app/views/alchemy/admin/pages/_anchor_link.html.erb +0 -22
- data/app/views/alchemy/admin/pages/_external_link.html.erb +0 -31
- data/app/views/alchemy/admin/pages/_file_link.html.erb +0 -31
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +0 -35
- data/app/views/alchemy/admin/pages/link.html.erb +0 -26
- data/app/views/alchemy/admin/partials/_flash.html.erb +0 -4
- data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +0 -29
- data/lib/alchemy/test_support/current_language_shared_examples.rb +0 -33
- data/vendor/assets/fonts/remixicon.eot +0 -0
- data/vendor/assets/fonts/remixicon.svg +0 -7816
- data/vendor/assets/fonts/remixicon.ttf +0 -0
- data/vendor/assets/fonts/remixicon.woff +0 -0
- data/vendor/assets/fonts/remixicon.woff2 +0 -0
- data/vendor/assets/stylesheets/remixicon.scss +0 -10480
@@ -1,7 +1,9 @@
|
|
1
1
|
import Sortable from "sortablejs"
|
2
|
+
import { growl } from "alchemy_admin/growler"
|
2
3
|
import { patch } from "alchemy_admin/utils/ajax"
|
4
|
+
import pleaseWaitOverlay from "alchemy_admin/please_wait_overlay"
|
3
5
|
|
4
|
-
function
|
6
|
+
function onSort(evt) {
|
5
7
|
const pageId = evt.item.dataset.pageId
|
6
8
|
const url = Alchemy.routes.move_admin_page_path(pageId)
|
7
9
|
const data = {
|
@@ -9,19 +11,26 @@ function onFinishDragging(evt) {
|
|
9
11
|
new_position: evt.newIndex
|
10
12
|
}
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
if (evt.target === evt.to) {
|
15
|
+
pleaseWaitOverlay(true)
|
16
|
+
patch(url, data)
|
17
|
+
.then(async (response) => {
|
18
|
+
const pageData = await response.data
|
19
|
+
const pageEl = document.getElementById(`page_${pageId}`)
|
20
|
+
const urlPathEl = pageEl.querySelector(".sitemap_url")
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
growl(Alchemy.t("Successfully moved page"))
|
23
|
+
urlPathEl.textContent = pageData.url_path
|
24
|
+
displayPageFolders()
|
25
|
+
})
|
26
|
+
.catch((error) => {
|
27
|
+
growl(error.message || error, "error")
|
28
|
+
Alchemy.currentSitemap.reload()
|
29
|
+
})
|
30
|
+
.finally(() => {
|
31
|
+
pleaseWaitOverlay(false)
|
32
|
+
})
|
33
|
+
}
|
25
34
|
}
|
26
35
|
|
27
36
|
export function displayPageFolders() {
|
@@ -50,7 +59,7 @@ export function createSortables(sortables) {
|
|
50
59
|
fallbackOnBody: true,
|
51
60
|
swapThreshold: 0.65,
|
52
61
|
handle: ".handle",
|
53
|
-
|
62
|
+
onSort
|
54
63
|
})
|
55
64
|
})
|
56
65
|
}
|
@@ -1,13 +1,14 @@
|
|
1
1
|
import debounce from "alchemy_admin/utils/debounce"
|
2
2
|
import max from "alchemy_admin/utils/max"
|
3
3
|
import { get } from "alchemy_admin/utils/ajax"
|
4
|
+
import { growl } from "alchemy_admin/growler"
|
4
5
|
import ImageLoader from "alchemy_admin/image_loader"
|
5
6
|
|
6
7
|
const UPDATE_DELAY = 125
|
7
|
-
const IMAGE_PLACEHOLDER = '<
|
8
|
+
const IMAGE_PLACEHOLDER = '<alchemy-icon name="image"></alchemy-icon>'
|
8
9
|
const THUMBNAIL_SIZE = "160x120"
|
9
10
|
|
10
|
-
|
11
|
+
class PictureEditor {
|
11
12
|
constructor(container) {
|
12
13
|
this.container = container
|
13
14
|
this.cropFromField = container.querySelector("[data-crop-from]")
|
@@ -77,7 +78,7 @@ export class PictureEditor {
|
|
77
78
|
})
|
78
79
|
.catch((error) => {
|
79
80
|
console.error(error.message || error)
|
80
|
-
|
81
|
+
growl(error.message || error, "error")
|
81
82
|
})
|
82
83
|
}
|
83
84
|
|
@@ -131,10 +132,10 @@ export class PictureEditor {
|
|
131
132
|
if (!this.imageCropperEnabled) return []
|
132
133
|
|
133
134
|
const mask = this.targetSize.split("x").map((n) => parseInt(n))
|
134
|
-
const zoom = max(
|
135
|
+
const zoom = max([
|
135
136
|
mask[0] / this.imageFileWidth,
|
136
137
|
mask[1] / this.imageFileHeight
|
137
|
-
)
|
138
|
+
])
|
138
139
|
|
139
140
|
return [Math.round(mask[0] / zoom), Math.round(mask[1] / zoom)]
|
140
141
|
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import { registerIconLibrary, setDefaultAnimation } from "shoelace"
|
2
|
+
|
3
|
+
// Change the default animation for all tooltips
|
4
|
+
setDefaultAnimation("tooltip.show", {
|
5
|
+
keyframes: [
|
6
|
+
{ transform: "translateY(10px)", opacity: "0" },
|
7
|
+
{ transform: "translateY(0)", opacity: "1" }
|
8
|
+
],
|
9
|
+
options: {
|
10
|
+
duration: 100
|
11
|
+
}
|
12
|
+
})
|
13
|
+
|
14
|
+
setDefaultAnimation("tooltip.hide", {
|
15
|
+
keyframes: [
|
16
|
+
{ transform: "translateY(0)", opacity: "1" },
|
17
|
+
{ transform: "translateY(10px)", opacity: "0" }
|
18
|
+
],
|
19
|
+
options: {
|
20
|
+
duration: 100
|
21
|
+
}
|
22
|
+
})
|
23
|
+
|
24
|
+
// Change the default animation for all dialogs
|
25
|
+
setDefaultAnimation("dialog.show", {
|
26
|
+
keyframes: [
|
27
|
+
{ transform: "scale(0.98)", opacity: "0" },
|
28
|
+
{ transform: "scale(1)", opacity: "1" }
|
29
|
+
],
|
30
|
+
options: {
|
31
|
+
duration: 150
|
32
|
+
}
|
33
|
+
})
|
34
|
+
|
35
|
+
setDefaultAnimation("dialog.hide", {
|
36
|
+
keyframes: [
|
37
|
+
{ transform: "scale(1)", opacity: "1" },
|
38
|
+
{ transform: "scale(0.98)", opacity: "0" }
|
39
|
+
],
|
40
|
+
options: {
|
41
|
+
duration: 150
|
42
|
+
}
|
43
|
+
})
|
44
|
+
|
45
|
+
const spriteUrl = document
|
46
|
+
.querySelector('meta[name="alchemy-icon-sprite"]')
|
47
|
+
.getAttribute("content")
|
48
|
+
|
49
|
+
const iconMap = {
|
50
|
+
"x-lg": "close"
|
51
|
+
}
|
52
|
+
|
53
|
+
const options = {
|
54
|
+
resolver: (name) => `${spriteUrl}#ri-${iconMap[name] || name}-line`,
|
55
|
+
mutator: (svg) => svg.setAttribute("fill", "currentColor"),
|
56
|
+
spriteSheet: true
|
57
|
+
}
|
58
|
+
|
59
|
+
registerIconLibrary("default", options)
|
60
|
+
registerIconLibrary("system", options)
|
@@ -2,6 +2,7 @@
|
|
2
2
|
import PageSorter from "alchemy_admin/page_sorter"
|
3
3
|
import { on } from "alchemy_admin/utils/events"
|
4
4
|
import { get, patch } from "alchemy_admin/utils/ajax"
|
5
|
+
import { growl } from "alchemy_admin/growler"
|
5
6
|
import { createSortables, displayPageFolders } from "alchemy_admin/page_sorter"
|
6
7
|
|
7
8
|
export default class Sitemap {
|
@@ -40,6 +41,11 @@ export default class Sitemap {
|
|
40
41
|
.catch(this.errorHandler)
|
41
42
|
}
|
42
43
|
|
44
|
+
// Reloads the sitemap
|
45
|
+
reload() {
|
46
|
+
this.load(this.options.page_root_id)
|
47
|
+
}
|
48
|
+
|
43
49
|
// Watch page folder clicks and re-render the page branch
|
44
50
|
handlePageFolders() {
|
45
51
|
on(
|
@@ -103,7 +109,6 @@ export default class Sitemap {
|
|
103
109
|
item.classList.remove("highlight")
|
104
110
|
}
|
105
111
|
})
|
106
|
-
this.filter_field_clear.style.display = "inline-block"
|
107
112
|
const { length } = results
|
108
113
|
|
109
114
|
if (length === 1) {
|
@@ -123,7 +128,6 @@ export default class Sitemap {
|
|
123
128
|
left: 0,
|
124
129
|
behavior: "smooth"
|
125
130
|
})
|
126
|
-
this.filter_field_clear.style.display = "none"
|
127
131
|
}
|
128
132
|
}
|
129
133
|
|
@@ -131,6 +135,8 @@ export default class Sitemap {
|
|
131
135
|
_observe() {
|
132
136
|
this.search_field.addEventListener("keyup", (evt) => {
|
133
137
|
const term = evt.target.value
|
138
|
+
this.filter_field_clear.style.visibility =
|
139
|
+
term == "" ? "hidden" : "visible"
|
134
140
|
this.filter(term.toLowerCase())
|
135
141
|
})
|
136
142
|
this.search_field.addEventListener("focus", () => key.setScope("search"))
|
@@ -142,7 +148,7 @@ export default class Sitemap {
|
|
142
148
|
}
|
143
149
|
|
144
150
|
errorHandler(error) {
|
145
|
-
|
151
|
+
growl(error.message || error, "error")
|
146
152
|
console.error(error)
|
147
153
|
}
|
148
154
|
}
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import Sortable from "sortablejs"
|
2
|
+
import { growl } from "alchemy_admin/growler"
|
2
3
|
import { post } from "alchemy_admin/utils/ajax"
|
4
|
+
import { reloadPreview } from "alchemy_admin/components/preview_window"
|
3
5
|
|
4
6
|
const SORTABLE_OPTIONS = {
|
5
7
|
draggable: ".element-editor",
|
@@ -35,8 +37,8 @@ function onSort(event) {
|
|
35
37
|
if (event.target === event.to) {
|
36
38
|
post(Alchemy.routes.order_admin_elements_path, params).then((response) => {
|
37
39
|
const data = response.data
|
38
|
-
|
39
|
-
|
40
|
+
growl(data.message)
|
41
|
+
reloadPreview()
|
40
42
|
item.updateTitle(data.preview_text)
|
41
43
|
})
|
42
44
|
}
|
@@ -76,8 +78,4 @@ export default function SortableElements(selector) {
|
|
76
78
|
})
|
77
79
|
|
78
80
|
sortable_areas.forEach((element) => createSortable(element))
|
79
|
-
|
80
|
-
document.querySelectorAll(".nested-elements").forEach((nestedElement) => {
|
81
|
-
createSortable(nestedElement)
|
82
|
-
})
|
83
81
|
}
|
@@ -1,62 +1,34 @@
|
|
1
1
|
import "@ungap/custom-elements"
|
2
2
|
import "@hotwired/turbo-rails"
|
3
|
-
import "keymaster"
|
4
3
|
|
5
4
|
import Rails from "@rails/ujs"
|
6
5
|
|
7
6
|
import GUI from "alchemy_admin/gui"
|
8
7
|
import { translate } from "alchemy_admin/i18n"
|
9
8
|
import Dirty from "alchemy_admin/dirty"
|
9
|
+
import * as FixedElements from "alchemy_admin/fixed_elements"
|
10
|
+
import { growl } from "alchemy_admin/growler"
|
10
11
|
import IngredientAnchorLink from "alchemy_admin/ingredient_anchor_link"
|
11
12
|
import ImageLoader from "alchemy_admin/image_loader"
|
12
13
|
import ImageCropper from "alchemy_admin/image_cropper"
|
13
14
|
import Initializer from "alchemy_admin/initializer"
|
15
|
+
import { LinkDialog } from "alchemy_admin/link_dialog"
|
14
16
|
import pictureSelector from "alchemy_admin/picture_selector"
|
15
17
|
import pleaseWaitOverlay from "alchemy_admin/please_wait_overlay"
|
16
18
|
import Sitemap from "alchemy_admin/sitemap"
|
17
|
-
import SortableElements from "alchemy_admin/sortable_elements"
|
18
19
|
import Spinner from "alchemy_admin/spinner"
|
19
20
|
import PagePublicationFields from "alchemy_admin/page_publication_fields"
|
21
|
+
import { reloadPreview } from "alchemy_admin/components/preview_window"
|
22
|
+
import {
|
23
|
+
openConfirmDialog,
|
24
|
+
confirmToDeleteDialog
|
25
|
+
} from "alchemy_admin/confirm_dialog"
|
20
26
|
|
21
27
|
// Web Components
|
22
|
-
import "alchemy_admin/components
|
23
|
-
import "alchemy_admin/components/char_counter"
|
24
|
-
import "alchemy_admin/components/clipboard_button"
|
25
|
-
import "alchemy_admin/components/datepicker"
|
26
|
-
import "alchemy_admin/components/dialog_link"
|
27
|
-
import "alchemy_admin/components/element_editor"
|
28
|
-
import "alchemy_admin/components/ingredient_group"
|
29
|
-
import "alchemy_admin/components/link_buttons"
|
30
|
-
import "alchemy_admin/components/node_select"
|
31
|
-
import "alchemy_admin/components/uploader"
|
32
|
-
import "alchemy_admin/components/overlay"
|
33
|
-
import "alchemy_admin/components/page_select"
|
34
|
-
import "alchemy_admin/components/select"
|
35
|
-
import "alchemy_admin/components/spinner"
|
36
|
-
import "alchemy_admin/components/tinymce"
|
28
|
+
import "alchemy_admin/components"
|
37
29
|
|
38
|
-
|
39
|
-
|
40
|
-
// Change the default animation for all dialogs
|
41
|
-
setDefaultAnimation("tooltip.show", {
|
42
|
-
keyframes: [
|
43
|
-
{ transform: "translateY(10px)", opacity: "0" },
|
44
|
-
{ transform: "translateY(0)", opacity: "1" }
|
45
|
-
],
|
46
|
-
options: {
|
47
|
-
duration: 100
|
48
|
-
}
|
49
|
-
})
|
50
|
-
|
51
|
-
setDefaultAnimation("tooltip.hide", {
|
52
|
-
keyframes: [
|
53
|
-
{ transform: "translateY(0)", opacity: "1" },
|
54
|
-
{ transform: "translateY(10px)", opacity: "0" }
|
55
|
-
],
|
56
|
-
options: {
|
57
|
-
duration: 100
|
58
|
-
}
|
59
|
-
})
|
30
|
+
// Shoelace Setup
|
31
|
+
import "alchemy_admin/shoelace_theme"
|
60
32
|
|
61
33
|
// Global Alchemy object
|
62
34
|
if (typeof window.Alchemy === "undefined") {
|
@@ -68,16 +40,20 @@ Object.assign(Alchemy, {
|
|
68
40
|
...Dirty,
|
69
41
|
GUI,
|
70
42
|
t: translate, // Global utility method for translating a given string
|
43
|
+
FixedElements,
|
44
|
+
growl,
|
71
45
|
ImageLoader: ImageLoader.init,
|
72
46
|
ImageCropper,
|
73
|
-
Initializer,
|
74
47
|
IngredientAnchorLink,
|
48
|
+
LinkDialog,
|
75
49
|
pictureSelector,
|
76
50
|
pleaseWaitOverlay,
|
77
51
|
Sitemap,
|
78
|
-
SortableElements,
|
79
52
|
Spinner,
|
80
|
-
PagePublicationFields
|
53
|
+
PagePublicationFields,
|
54
|
+
reloadPreview,
|
55
|
+
openConfirmDialog,
|
56
|
+
confirmToDeleteDialog
|
81
57
|
})
|
82
58
|
|
83
59
|
Rails.start()
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Alchemy
|
2
|
+
class Current < ActiveSupport::CurrentAttributes
|
3
|
+
attribute :preview_page, :page, :language, :site
|
4
|
+
|
5
|
+
def language
|
6
|
+
super || Language.default
|
7
|
+
end
|
8
|
+
|
9
|
+
def site
|
10
|
+
super || Site.first
|
11
|
+
end
|
12
|
+
|
13
|
+
def preview_page=(page)
|
14
|
+
super
|
15
|
+
|
16
|
+
self.page = page
|
17
|
+
self.language = page&.language
|
18
|
+
self.site = page&.site
|
19
|
+
end
|
20
|
+
|
21
|
+
def preview_page?(page = Current.page)
|
22
|
+
return false if preview_page.nil?
|
23
|
+
preview_page == page
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -101,7 +101,7 @@ module Alchemy
|
|
101
101
|
scope :excluded, ->(names) { where.not(name: names) }
|
102
102
|
scope :fixed, -> { where(fixed: true) }
|
103
103
|
scope :unfixed, -> { where(fixed: false) }
|
104
|
-
scope :from_current_site, -> { where(Language.table_name => {site_id:
|
104
|
+
scope :from_current_site, -> { where(Language.table_name => {site_id: Current.site}).joins(page: "language") }
|
105
105
|
scope :folded, -> { where(folded: true) }
|
106
106
|
scope :expanded, -> { where(folded: false) }
|
107
107
|
scope :not_nested, -> { where(parent_element_id: nil) }
|
@@ -26,17 +26,6 @@ module Alchemy
|
|
26
26
|
def preview_text(max_length = 30)
|
27
27
|
name.to_s[0..max_length - 1]
|
28
28
|
end
|
29
|
-
|
30
|
-
%i[
|
31
|
-
autoplay
|
32
|
-
controls
|
33
|
-
loop
|
34
|
-
muted
|
35
|
-
].each do |method|
|
36
|
-
define_method(:"#{method}=") do |value|
|
37
|
-
super(ActiveModel::Type::Boolean.new.cast(value))
|
38
|
-
end
|
39
|
-
end
|
40
29
|
end
|
41
30
|
end
|
42
31
|
end
|
@@ -38,6 +38,12 @@ module Alchemy
|
|
38
38
|
upsample
|
39
39
|
]
|
40
40
|
|
41
|
+
def alt_text(language: Alchemy::Current.language)
|
42
|
+
alt_tag.presence ||
|
43
|
+
picture&.description_for(language) ||
|
44
|
+
picture&.name&.humanize
|
45
|
+
end
|
46
|
+
|
41
47
|
# The first 30 characters of the pictures name
|
42
48
|
#
|
43
49
|
# Used by the Element#preview_text method.
|
@@ -31,18 +31,6 @@ module Alchemy
|
|
31
31
|
def preview_text(max_length = 30)
|
32
32
|
name.to_s[0..max_length - 1]
|
33
33
|
end
|
34
|
-
|
35
|
-
%i[
|
36
|
-
autoplay
|
37
|
-
controls
|
38
|
-
loop
|
39
|
-
muted
|
40
|
-
playsinline
|
41
|
-
].each do |method|
|
42
|
-
define_method(:"#{method}=") do |value|
|
43
|
-
super(ActiveModel::Type::Boolean.new.cast(value))
|
44
|
-
end
|
45
|
-
end
|
46
34
|
end
|
47
35
|
end
|
48
36
|
end
|
@@ -68,24 +68,26 @@ module Alchemy
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def on_current_site
|
71
|
-
on_site(
|
71
|
+
on_site(Current.site)
|
72
72
|
end
|
73
73
|
|
74
74
|
# Store the current language in the current thread.
|
75
|
+
# @deprecated Use {Alchemy::Current#language=} instead.
|
75
76
|
def current=(language)
|
76
|
-
|
77
|
+
Current.language = language
|
77
78
|
end
|
79
|
+
deprecate "current=": :"Alchemy::Current.language=", deprecator: Alchemy::Deprecation
|
78
80
|
|
79
81
|
# Current language from current thread or default.
|
82
|
+
# @deprecated Use {Alchemy::Current#language} instead.
|
80
83
|
def current
|
81
|
-
|
84
|
+
Current.language
|
82
85
|
end
|
86
|
+
deprecate current: :"Alchemy::Current.language", deprecator: Alchemy::Deprecation
|
83
87
|
|
84
88
|
# The root page of the current language.
|
85
89
|
def current_root_page
|
86
|
-
|
87
|
-
|
88
|
-
current.pages.language_roots.first
|
90
|
+
Current.language&.pages&.language_roots&.first
|
89
91
|
end
|
90
92
|
|
91
93
|
# Default language for current site
|
data/app/models/alchemy/node.rb
CHANGED
@@ -37,9 +37,9 @@ module Alchemy
|
|
37
37
|
class << self
|
38
38
|
# Returns all root nodes for current language
|
39
39
|
def language_root_nodes
|
40
|
-
raise "No language found" if
|
40
|
+
raise "No language found" if Current.language.nil?
|
41
41
|
|
42
|
-
roots.where(language_id:
|
42
|
+
roots.where(language_id: Current.language.id)
|
43
43
|
end
|
44
44
|
|
45
45
|
def available_menu_names
|
@@ -80,21 +80,21 @@ module Alchemy
|
|
80
80
|
# type: Richtext
|
81
81
|
#
|
82
82
|
def available_element_definitions(only_element_named = nil)
|
83
|
-
@
|
83
|
+
@_available_element_definitions ||= if only_element_named
|
84
84
|
definition = Element.definition_by_name(only_element_named)
|
85
85
|
element_definitions_by_name(definition["nestable_elements"])
|
86
86
|
else
|
87
|
-
element_definitions
|
87
|
+
element_definitions.dup
|
88
88
|
end
|
89
89
|
|
90
|
-
return [] if @
|
90
|
+
return [] if @_available_element_definitions.blank?
|
91
91
|
|
92
92
|
existing_elements = draft_version.elements.not_nested
|
93
93
|
@_existing_element_names = existing_elements.pluck(:name)
|
94
94
|
delete_unique_element_definitions!
|
95
95
|
delete_outnumbered_element_definitions!
|
96
96
|
|
97
|
-
@
|
97
|
+
@_available_element_definitions
|
98
98
|
end
|
99
99
|
|
100
100
|
# All names of elements that can actually be placed on current page.
|
@@ -186,18 +186,18 @@ module Alchemy
|
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
189
|
-
# Deletes unique and already present definitions from @
|
189
|
+
# Deletes unique and already present definitions from @_available_element_definitions.
|
190
190
|
#
|
191
191
|
def delete_unique_element_definitions!
|
192
|
-
@
|
192
|
+
@_available_element_definitions.delete_if do |element|
|
193
193
|
element["unique"] && @_existing_element_names.include?(element["name"])
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
-
# Deletes limited and outnumbered definitions from @
|
197
|
+
# Deletes limited and outnumbered definitions from @_available_element_definitions.
|
198
198
|
#
|
199
199
|
def delete_outnumbered_element_definitions!
|
200
|
-
@
|
200
|
+
@_available_element_definitions.delete_if do |element|
|
201
201
|
outnumbered = @_existing_element_names.select { |name| name == element["name"] }
|
202
202
|
element["amount"] && outnumbered.count >= element["amount"].to_i
|
203
203
|
end
|
@@ -103,10 +103,10 @@ module Alchemy
|
|
103
103
|
# page_layouts: [default_intro]
|
104
104
|
#
|
105
105
|
def available_on_site?(layout)
|
106
|
-
return false unless Alchemy::
|
106
|
+
return false unless Alchemy::Current.site
|
107
107
|
|
108
|
-
Alchemy::
|
109
|
-
Alchemy::
|
108
|
+
Alchemy::Current.site.definition.blank? ||
|
109
|
+
Alchemy::Current.site.definition.fetch("page_layouts", []).include?(layout["name"])
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
@@ -101,18 +101,22 @@ module Alchemy
|
|
101
101
|
page_layout.parameterize.underscore
|
102
102
|
end
|
103
103
|
|
104
|
-
# Returns the version that's taken for Rails' recycable cache key.
|
104
|
+
# Returns the version string that's taken for Rails' recycable cache key.
|
105
105
|
#
|
106
|
-
|
106
|
+
def cache_version
|
107
|
+
last_modified_at&.to_s
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns the timestamp that the page was last modified at, regardless of through
|
111
|
+
# publishing or editing page, or through a change of related objects through ingredients.
|
112
|
+
# Respects the public version not changing if editing a preview.
|
107
113
|
#
|
108
|
-
#
|
114
|
+
# In preview mode, it will take the draft version's updated_at timestamp.
|
115
|
+
# In public mode, it will take the public version's updated_at timestamp.
|
109
116
|
#
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
else
|
114
|
-
published_at.to_s
|
115
|
-
end
|
117
|
+
def last_modified_at
|
118
|
+
relevant_page_version = (Current.preview_page == self) ? draft_version : public_version
|
119
|
+
relevant_page_version&.updated_at
|
116
120
|
end
|
117
121
|
|
118
122
|
# Returns true if the page cache control headers should be set.
|
@@ -94,11 +94,11 @@ module Alchemy
|
|
94
94
|
#
|
95
95
|
scope :searchables, -> { not_restricted.published.contentpages }
|
96
96
|
|
97
|
-
# All pages from +Alchemy::
|
97
|
+
# All pages from +Alchemy::Current.site+
|
98
98
|
#
|
99
99
|
scope :from_current_site,
|
100
100
|
-> {
|
101
|
-
where(Language.table_name => {site_id:
|
101
|
+
where(Language.table_name => {site_id: Current.site}).joins(:language)
|
102
102
|
}
|
103
103
|
|
104
104
|
# All pages for xml sitemap
|