alchemy_cms 7.3.4 → 7.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -1
- data/Gemfile +10 -3
- data/README.md +2 -2
- data/Rakefile +2 -0
- data/alchemy_cms.gemspec +1 -4
- data/app/assets/builds/alchemy/admin.css +9 -1
- data/app/assets/builds/alchemy/admin.css.map +1 -1
- data/app/assets/builds/alchemy/custom-properties.css +1 -1
- data/app/assets/builds/alchemy/custom-properties.css.map +1 -1
- data/app/assets/builds/alchemy/preview.min.js +1 -0
- data/app/assets/builds/alchemy/welcome.css +1 -1
- data/app/assets/builds/alchemy/welcome.css.map +1 -1
- data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css +1 -1
- data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css.map +1 -1
- data/app/assets/config/alchemy_manifest.js +0 -4
- data/app/assets/javascripts/alchemy/admin.js +8 -6
- data/app/assets/stylesheets/alchemy/admin/elements.scss +43 -7
- data/app/assets/stylesheets/alchemy/admin/forms.scss +4 -0
- data/app/assets/stylesheets/alchemy/admin/image_library.scss +40 -26
- data/app/assets/stylesheets/alchemy/admin/navigation.scss +9 -1
- data/app/assets/stylesheets/alchemy/admin/preview_window.scss +22 -17
- data/app/assets/stylesheets/alchemy/admin.scss +1 -1
- data/app/assets/stylesheets/alchemy/custom-properties.css +2 -1
- data/app/components/alchemy/ingredients/link_view.rb +7 -1
- data/app/components/alchemy/ingredients/picture_view.rb +5 -2
- data/app/components/alchemy/ingredients/text_view.rb +4 -1
- data/app/components/concerns/alchemy/ingredients/link_target.rb +18 -0
- data/app/controllers/alchemy/admin/base_controller.rb +34 -5
- data/app/controllers/alchemy/admin/elements_controller.rb +2 -2
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +1 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +6 -6
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
- data/app/controllers/alchemy/elements_controller.rb +3 -0
- data/app/helpers/alchemy/admin/form_helper.rb +1 -1
- data/app/helpers/alchemy/admin/navigation_helper.rb +22 -1
- data/app/javascript/alchemy_admin/components/action.js +2 -1
- data/app/javascript/alchemy_admin/components/dialog_link.js +3 -18
- data/app/javascript/alchemy_admin/components/element_editor.js +9 -0
- data/app/javascript/alchemy_admin/components/elements_window.js +34 -0
- data/app/javascript/alchemy_admin/components/elements_window_handle.js +65 -0
- data/app/javascript/alchemy_admin/components/icon.js +2 -2
- data/app/javascript/alchemy_admin/components/index.js +1 -0
- data/app/javascript/alchemy_admin/components/preview_window.js +5 -5
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +1 -1
- data/app/javascript/alchemy_admin/confirm_dialog.js +9 -11
- data/app/javascript/alchemy_admin/dialog.js +329 -0
- data/app/javascript/alchemy_admin/hotkeys.js +3 -2
- data/app/javascript/alchemy_admin/image_cropper.js +57 -40
- data/app/javascript/alchemy_admin/image_overlay.js +73 -0
- data/app/javascript/alchemy_admin/initializer.js +51 -2
- data/app/javascript/alchemy_admin/link_dialog.js +2 -1
- data/app/javascript/alchemy_admin/node_tree.js +3 -1
- data/app/javascript/alchemy_admin/page_sorter.js +1 -1
- data/app/javascript/alchemy_admin/picture_selector.js +2 -1
- data/app/javascript/alchemy_admin/shoelace_theme.js +2 -2
- data/app/javascript/alchemy_admin/templates/compiled.js +1 -0
- data/app/javascript/alchemy_admin.js +10 -6
- data/app/javascript/preview.js +117 -0
- data/app/models/alchemy/image_cropper_settings.rb +3 -4
- 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/crop.html.erb +19 -16
- data/app/views/alchemy/admin/dashboard/info.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +9 -8
- data/app/views/alchemy/admin/elements/_clipboard_button.html.erb +14 -0
- data/app/views/alchemy/admin/elements/_element.html.erb +2 -0
- data/app/views/alchemy/admin/elements/_form.html.erb +15 -13
- data/app/views/alchemy/admin/elements/create.turbo_stream.erb +34 -0
- data/app/views/alchemy/admin/elements/index.html.erb +3 -15
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +1 -1
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +7 -5
- data/app/views/alchemy/admin/nodes/_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_current_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_form.html.erb +43 -40
- data/app/views/alchemy/admin/pages/_locked_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_page_layout_filter.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_table.html.erb +2 -2
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/update.turbo_stream.erb +39 -0
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +3 -4
- data/app/views/alchemy/admin/pictures/_picture_description_field.html.erb +7 -5
- data/app/views/alchemy/admin/pictures/index.html.erb +13 -9
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +1 -1
- data/app/views/layouts/alchemy/admin.html.erb +8 -4
- data/bun.lockb +0 -0
- data/bundles/tinymce.js +2 -0
- data/config/alchemy/config.yml +3 -3
- data/config/alchemy/modules.yml +7 -6
- data/config/importmap.rb +4 -0
- data/config/routes.rb +1 -1
- data/lib/alchemy/engine.rb +6 -0
- data/lib/alchemy/modules.rb +0 -27
- data/lib/alchemy/resource.rb +14 -4
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +10 -10
- data/lib/alchemy/tinymce.rb +2 -1
- data/lib/alchemy/upgrader/seven_point_four.rb +26 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +14 -0
- data/lib/alchemy_cms.rb +0 -2
- data/lib/generators/alchemy/ingredient/ingredient_generator.rb +5 -0
- data/lib/generators/alchemy/ingredient/templates/view.html.erb +1 -1
- data/lib/generators/alchemy/ingredient/templates/view_component.rb.tt +10 -0
- data/lib/generators/alchemy/install/install_generator.rb +0 -1
- data/lib/generators/alchemy/install/templates/elements.yml.tt +1 -1
- data/lib/tasks/alchemy/upgrade.rake +19 -20
- data/rollup.config.mjs +44 -1
- data/vendor/javascript/cropperjs.min.js +10 -0
- data/vendor/javascript/handlebars.min.js +29 -0
- data/vendor/javascript/jquery.min.js +2 -0
- data/vendor/javascript/select2.min.js +23 -0
- data/vendor/javascript/tinymce.min.js +1 -1
- metadata +40 -94
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +0 -271
- data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +0 -54
- data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +0 -97
- data/app/assets/javascripts/alchemy/preview.js +0 -1
- data/app/assets/javascripts/alchemy/templates/index.js +0 -2
- data/app/javascript/alchemy_admin/gui.js +0 -12
- data/app/views/alchemy/admin/elements/create.js.erb +0 -35
- data/app/views/alchemy/admin/pages/update.js.erb +0 -43
- data/lib/alchemy/upgrader/seven_point_zero.rb +0 -36
- data/vendor/assets/images/Jcrop.gif +0 -0
- data/vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js +0 -7
- data/vendor/assets/javascripts/jquery_plugins/select2.js +0 -3729
- data/vendor/assets/stylesheets/jquery.Jcrop.min.css +0 -2
- data/vendor/assets/stylesheets/tinymce/skins/content/default/content.min.css +0 -1
- /data/app/{assets/javascripts/alchemy → javascript/alchemy_admin}/templates/node_folder.hbs +0 -0
- /data/app/{assets/javascripts/alchemy → javascript/alchemy_admin}/templates/page_folder.hbs +0 -0
- /data/app/{assets/javascripts/tinymce/icons/remixicons/icons.js → javascript/tinymce/icons/remixicons/index.js} +0 -0
- /data/app/{assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js → javascript/tinymce/plugins/alchemy_link/index.js} +0 -0
- /data/vendor/assets/{fonts → images}/remixicon.symbol.svg +0 -0
@@ -4,6 +4,7 @@
|
|
4
4
|
data-element-name="<%= element.name %>"
|
5
5
|
class="<%= element.css_classes.join(" ") %>"
|
6
6
|
<%= element.compact? ? "compact" : nil %>
|
7
|
+
<%= local_assigns[:created] ? "created" : nil %>
|
7
8
|
<%= element.fixed? ? "fixed" : nil %>
|
8
9
|
>
|
9
10
|
<% unless element.fixed? %>
|
@@ -68,6 +69,7 @@
|
|
68
69
|
<% if element.nestable_elements.any? %>
|
69
70
|
<div class="nestable-elements">
|
70
71
|
<%= content_tag :div,
|
72
|
+
id: "element_#{element.id}_nested_elements",
|
71
73
|
class: "nested-elements", data: {
|
72
74
|
'droppable-elements' => element.nestable_elements.join(' '),
|
73
75
|
'element-name' => element.name
|
@@ -3,18 +3,20 @@
|
|
3
3
|
<%= Alchemy.t(:no_more_elements_to_add) %>
|
4
4
|
<% end %>
|
5
5
|
<%- else -%>
|
6
|
-
<%=
|
7
|
-
<%=
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
6
|
+
<%= turbo_frame_tag @element do %>
|
7
|
+
<%= alchemy_form_for [:admin, @element], remote: false do |form| %>
|
8
|
+
<%= form.hidden_field :page_version_id %>
|
9
|
+
<%= form.input :name,
|
10
|
+
label: Alchemy.t(:element_of_type),
|
11
|
+
collection: elements_for_select(@elements),
|
12
|
+
prompt: Alchemy.t(:select_element),
|
13
|
+
selected: (@elements.first if @elements.count == 1),
|
14
|
+
input_html: {is: 'alchemy-select', autofocus: true} %>
|
15
|
+
<% if @elements.count == 1 %>
|
16
|
+
<%= form.hidden_field :name, value: @elements.first[:name] %>
|
17
|
+
<% end %>
|
18
|
+
<%= form.hidden_field :parent_element_id, value: @parent_element.try(:id) %>
|
19
|
+
<%= form.submit Alchemy.t(:add) %>
|
20
|
+
<%- end -%>
|
19
21
|
<%- end -%>
|
20
22
|
<%- end -%>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% opts = {
|
2
|
+
partial: "alchemy/admin/elements/element",
|
3
|
+
locals: {
|
4
|
+
element: Alchemy::ElementEditor.new(@element),
|
5
|
+
created: true
|
6
|
+
}
|
7
|
+
} %>
|
8
|
+
|
9
|
+
<% if @element.fixed? %>
|
10
|
+
<% target = "fixed_element_#{@element.id}" %>
|
11
|
+
<% elsif @element.parent_element %>
|
12
|
+
<% target = "element_#{@element.parent_element_id}_nested_elements" %>
|
13
|
+
<% else %>
|
14
|
+
<% target = "main-content-elements" %>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<%- if @cut_element_id -%>
|
18
|
+
<%= turbo_stream.remove "element_#{@cut_element_id}" %>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<% if @insert_at_top %>
|
22
|
+
<%= turbo_stream.prepend target, **opts %>
|
23
|
+
<% else %>
|
24
|
+
<%= turbo_stream.append target, **opts %>
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
<%= turbo_stream.replace "clipboard_button",
|
28
|
+
partial: "alchemy/admin/elements/clipboard_button" %>
|
29
|
+
|
30
|
+
<alchemy-growl>
|
31
|
+
<%= Alchemy.t(:successfully_added_element) %>
|
32
|
+
</alchemy-growl>
|
33
|
+
|
34
|
+
<alchemy-action name="closeCurrentDialog"></alchemy-action>
|
@@ -1,4 +1,5 @@
|
|
1
1
|
<%= turbo_frame_tag "alchemy_elements_window" do %>
|
2
|
+
<alchemy-elements-window-handle></alchemy-elements-window-handle>
|
2
3
|
<alchemy-elements-window>
|
3
4
|
<div class="elements-window-toolbar">
|
4
5
|
<%= render Alchemy::Admin::ToolbarButton.new(
|
@@ -12,20 +13,7 @@
|
|
12
13
|
},
|
13
14
|
if_permitted_to: [:create, Alchemy::Element]
|
14
15
|
) %>
|
15
|
-
<%= render
|
16
|
-
url: alchemy.admin_clipboard_path(remarkable_type: "elements"),
|
17
|
-
label: Alchemy.t("Show clipboard"),
|
18
|
-
icon: :clipboard,
|
19
|
-
icon_style: clipboard_empty?("elements") ? "line" : "fill",
|
20
|
-
dialog_options: {
|
21
|
-
title: Alchemy.t("Clipboard"),
|
22
|
-
size: "400x305"
|
23
|
-
},
|
24
|
-
link_options: {
|
25
|
-
id: "clipboard_button"
|
26
|
-
},
|
27
|
-
if_permitted_to: [:index, :alchemy_admin_clipboard]
|
28
|
-
) %>
|
16
|
+
<%= render "alchemy/admin/elements/clipboard_button" %>
|
29
17
|
<sl-tooltip content="<%= Alchemy.t("Collapse all elements") %>" placement="top-end" class="right">
|
30
18
|
<button id="collapse-all-elements-button" class="icon_button">
|
31
19
|
<alchemy-icon name="contract-up-down"></alchemy-icon>
|
@@ -53,7 +41,7 @@
|
|
53
41
|
<%= render @elements.map { |element| Alchemy::ElementEditor.new(element) } %>
|
54
42
|
</sl-tab-panel>
|
55
43
|
<% @fixed_elements.each do |element| %>
|
56
|
-
<sl-tab-panel name="fixed-element-<%= element.id %>" style="--padding: 0" class="scrollable-elements">
|
44
|
+
<sl-tab-panel id="fixed_element_<%= element.id %>" name="fixed-element-<%= element.id %>" style="--padding: 0" class="scrollable-elements">
|
57
45
|
<%= render Alchemy::ElementEditor.new(element) %>
|
58
46
|
</sl-tab-panel>
|
59
47
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%= f.input :caption, as: ingredient.settings[:caption_as_textarea] ? 'text' : 'string' %>
|
2
2
|
<%= f.input :title %>
|
3
|
-
<%= f.input :alt_tag, as: :text, placeholder: ingredient.alt_text(language: @language) %>
|
3
|
+
<%= f.input :alt_tag, as: :text, placeholder: ingredient.alt_text(language: @language), input_html: {rows: 4} %>
|
4
4
|
<%- if ingredient.settings[:sizes].present? && ingredient.settings[:srcset].blank? -%>
|
5
5
|
<%= f.input :render_size,
|
6
6
|
collection: [
|
@@ -1,7 +1,9 @@
|
|
1
|
-
<%=
|
2
|
-
<%=
|
3
|
-
|
4
|
-
<%=
|
1
|
+
<%= turbo_frame_tag @page do %>
|
2
|
+
<%= alchemy_form_for [:admin, @page], url: alchemy.admin_layoutpage_path(@page), class: 'edit_page', remote: false do |f| %>
|
3
|
+
<%= f.input :name, autofocus: true %>
|
4
|
+
<%= render Alchemy::Admin::TagsAutocomplete.new do %>
|
5
|
+
<%= f.input :tag_list, input_html: { value: f.object.tag_list.join(",") } %>
|
6
|
+
<% end %>
|
7
|
+
<%= f.submit Alchemy.t(:save) %>
|
5
8
|
<% end %>
|
6
|
-
<%= f.submit Alchemy.t(:save) %>
|
7
9
|
<% end %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="page_status_and_name" id="
|
1
|
+
<div class="page_status_and_name" id="locked_page_<%= current_page.id %>">
|
2
2
|
<%= render 'alchemy/admin/pages/page_infos', page: current_page %>
|
3
3
|
<%= render 'alchemy/admin/pages/page_status', page: current_page %>
|
4
4
|
</div>
|
@@ -1,55 +1,58 @@
|
|
1
|
-
<%=
|
2
|
-
|
3
|
-
|
4
|
-
<%=
|
1
|
+
<%= turbo_frame_tag @page do %>
|
2
|
+
<%= alchemy_form_for [:admin, @page], class: 'edit_page', remote: false do |f| %>
|
3
|
+
<% unless @page.language_root? || @page.layoutpage %>
|
4
|
+
<%= render Alchemy::Admin::PageSelect.new(@page.parent) do %>
|
5
|
+
<%= f.input :parent_id, required: true %>
|
6
|
+
<% end %>
|
5
7
|
<% end %>
|
6
|
-
<% end %>
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
<div class="input check_boxes">
|
10
|
+
<label class="control-label"><%= Alchemy.t(:page_status) %></label>
|
11
|
+
<div class="control_group">
|
12
|
+
<%= render 'alchemy/admin/pages/publication_fields' %>
|
13
|
+
<%= page_status_checkbox(@page, :restricted) %>
|
14
|
+
<% if configuration(:sitemap)['show_flag'] %>
|
15
|
+
<%= page_status_checkbox(@page, :sitemap) %>
|
16
|
+
<% end %>
|
17
|
+
</div>
|
16
18
|
</div>
|
17
|
-
</div>
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
<%= f.input :name, autofocus: true %>
|
21
|
+
<%= f.input :urlname, as: 'string', input_html: {value: @page.slug}, label: Alchemy::Page.human_attribute_name(:slug) %>
|
22
|
+
<alchemy-char-counter max-chars="60">
|
23
|
+
<%= f.input :title %>
|
24
|
+
</alchemy-char-counter>
|
25
|
+
|
26
|
+
<% if Alchemy.enable_searchable %>
|
27
|
+
<div class="input check_boxes">
|
28
|
+
<label class="control-label"><%= Alchemy.t(:fulltext_search) %></label>
|
29
|
+
<div class="control_group">
|
30
|
+
<%= page_status_checkbox(@page, :searchable) %>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
24
34
|
|
25
|
-
<% if Alchemy.enable_searchable %>
|
26
35
|
<div class="input check_boxes">
|
27
|
-
<label class="control-label"><%= Alchemy.t(:
|
36
|
+
<label class="control-label"><%= Alchemy.t(:search_engines) %></label>
|
28
37
|
<div class="control_group">
|
29
|
-
<%= page_status_checkbox(@page, :
|
38
|
+
<%= page_status_checkbox(@page, :robot_index) %>
|
39
|
+
<%= page_status_checkbox(@page, :robot_follow) %>
|
30
40
|
</div>
|
31
41
|
</div>
|
32
|
-
<% end %>
|
33
42
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
<%= page_status_checkbox(@page, :robot_index) %>
|
38
|
-
<%= page_status_checkbox(@page, :robot_follow) %>
|
39
|
-
</div>
|
40
|
-
</div>
|
43
|
+
<alchemy-char-counter max-chars="160">
|
44
|
+
<%= f.input :meta_description, as: 'text' %>
|
45
|
+
</alchemy-char-counter>
|
41
46
|
|
42
|
-
|
43
|
-
|
44
|
-
|
47
|
+
<%= f.input :meta_keywords,
|
48
|
+
as: 'text',
|
49
|
+
hint: Alchemy.t('pages.update.comma_seperated') %>
|
45
50
|
|
46
|
-
|
47
|
-
|
48
|
-
|
51
|
+
<%= render Alchemy::Admin::TagsAutocomplete.new do %>
|
52
|
+
<%= f.input :tag_list, input_html: { value: f.object.tag_list.join(",") } %>
|
53
|
+
<% end %>
|
49
54
|
|
50
|
-
|
51
|
-
<%= f.
|
55
|
+
<%= hidden_field_tag :view, params[:view] %>
|
56
|
+
<%= f.submit Alchemy.t(:save) %>
|
52
57
|
<% end %>
|
53
|
-
|
54
|
-
<%= f.submit Alchemy.t(:save) %>
|
55
58
|
<% end %>
|
@@ -19,7 +19,7 @@
|
|
19
19
|
</label>
|
20
20
|
</div>
|
21
21
|
|
22
|
-
<script type="
|
22
|
+
<script type="module">
|
23
23
|
$(function() {
|
24
24
|
$("#page_layout").on("change", function(e) {
|
25
25
|
var url = "<%= alchemy.admin_pages_path(search_filter_params.except(:page_layout, :page).merge(view: "list")) %>";
|
@@ -67,7 +67,7 @@
|
|
67
67
|
<% table.with_action :configure, Alchemy.t(:edit_page_properties) do |page| %>
|
68
68
|
<%= link_to_dialog(
|
69
69
|
render_icon(:cog),
|
70
|
-
alchemy.configure_admin_page_path(page),
|
70
|
+
alchemy.configure_admin_page_path(page, view: "list"),
|
71
71
|
{
|
72
72
|
title: Alchemy.t(:edit_page_properties),
|
73
73
|
size: '450x680'
|
@@ -91,7 +91,7 @@
|
|
91
91
|
<% end %>
|
92
92
|
|
93
93
|
|
94
|
-
<script type="
|
94
|
+
<script type="module">
|
95
95
|
$(function() {
|
96
96
|
Alchemy.PagePublicationFields();
|
97
97
|
});
|
@@ -144,7 +144,7 @@
|
|
144
144
|
<% end %>
|
145
145
|
|
146
146
|
<% content_for :javascripts do %>
|
147
|
-
<script type="
|
147
|
+
<script type="module">
|
148
148
|
$(document).one('turbo:load', function() {
|
149
149
|
$('#unlock_page_form, #publish_page_form').on('submit', function(event) {
|
150
150
|
var not_dirty = Alchemy.checkPageDirtyness(this);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<alchemy-growl><%= @notice %></alchemy-action>
|
2
|
+
<alchemy-action name="closeCurrentDialog"></alchemy-action>
|
3
|
+
|
4
|
+
<% if @while_page_edit -%>
|
5
|
+
<%= turbo_stream.replace "locked_page_#{@page.id}" do %>
|
6
|
+
<%= render("alchemy/admin/pages/current_page", current_page: @page) %>
|
7
|
+
<% end %>
|
8
|
+
<alchemy-action name="reloadPreview"></alchemy-action>
|
9
|
+
<% else %>
|
10
|
+
<%= turbo_stream.replace "locked_page_#{@page.id}" do %>
|
11
|
+
<%= render("alchemy/admin/pages/locked_page", locked_page: @page) %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% if @view == "list" %>
|
15
|
+
<turbo-stream action="refresh"></turbo-stream>
|
16
|
+
<% elsif @page.parent_id != @old_parent_id -%>
|
17
|
+
<%= turbo_stream.append "sitemap" do %>
|
18
|
+
<script type="module">
|
19
|
+
Alchemy.currentSitemap.load(<%= @page.get_language_root.id %>);
|
20
|
+
</script>
|
21
|
+
<% end %>
|
22
|
+
<% else -%>
|
23
|
+
<% if @page.layoutpage %>
|
24
|
+
<%= turbo_stream.replace "page_#{@page.id}" do %>
|
25
|
+
<%= render("alchemy/admin/layoutpages/layoutpage", layoutpage: @page) %>
|
26
|
+
<% end %>
|
27
|
+
<% else %>
|
28
|
+
<%= turbo_stream.append "sitemap" do %>
|
29
|
+
<script type="module">
|
30
|
+
const page = document.getElementById('page_<%= @page.id %>');
|
31
|
+
const page_html = "<%= j render('page', page: @page) %>".replace(/__ID__/g, "<%= @page.id %>");
|
32
|
+
const compiler = Handlebars.compile(page_html);
|
33
|
+
const tree = <%== @tree.to_json %>;
|
34
|
+
page.outerHTML = compiler(tree.pages[0]);
|
35
|
+
</script>
|
36
|
+
<% end %>
|
37
|
+
<% end %>
|
38
|
+
<% end -%>
|
39
|
+
<% end %>
|
@@ -6,10 +6,9 @@
|
|
6
6
|
<% elsif navigation["inline_image"] %>
|
7
7
|
<%== navigation["inline_image"] %>
|
8
8
|
<% elsif navigation["icon"] %>
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
</svg>
|
9
|
+
<%= content_tag :"alchemy-icon", nil,
|
10
|
+
name: navigation["icon"],
|
11
|
+
"icon-style": navigation["icon-style"] %>
|
13
12
|
<% else %>
|
14
13
|
<%= render_icon :table %>
|
15
14
|
<% end %>
|
@@ -21,9 +21,11 @@
|
|
21
21
|
<script type="module">
|
22
22
|
const select = document.querySelector("#language_id")
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
if (select) {
|
25
|
+
select.addEventListener("change", () => {
|
26
|
+
const url = new URL(select.dataset.url)
|
27
|
+
url.searchParams.set("language_id", select.value)
|
28
|
+
Turbo.visit(url, { frame: "picture_descriptions" })
|
29
|
+
})
|
30
|
+
}
|
29
31
|
</script>
|
@@ -86,16 +86,20 @@
|
|
86
86
|
</div>
|
87
87
|
|
88
88
|
<% content_for :javascripts do %>
|
89
|
-
<script type="
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
89
|
+
<script type="module">
|
90
|
+
import ImageOverlay from "alchemy_admin/image_overlay";
|
91
|
+
import pictureSelector from "alchemy_admin/picture_selector";
|
92
|
+
import { on } from "alchemy_admin/utils/events";
|
93
|
+
|
94
|
+
pictureSelector();
|
95
|
+
on("click", "#picture_archive", ".thumbnail_background", (event) => {
|
96
|
+
const url = event.target.closest("a")?.href;
|
97
|
+
const overlay = new ImageOverlay(url, {
|
98
|
+
size: `${window.innerWidth}x${window.innerHeight}`,
|
99
|
+
padding: false
|
98
100
|
});
|
101
|
+
overlay.open();
|
102
|
+
event.preventDefault();
|
99
103
|
});
|
100
104
|
</script>
|
101
105
|
<% end %>
|
@@ -5,15 +5,17 @@
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
6
|
<title><%= render_alchemy_title %></title>
|
7
7
|
<link rel="shortcut icon" href="<%= asset_path('alchemy/favicon.ico') %>">
|
8
|
+
<link rel="preload" href="<%= asset_path("remixicon.symbol.svg") %>" as="image" type="<%= Mime::Type.lookup_by_extension(:svg) %>" crossorigin>
|
8
9
|
<%= csrf_meta_tag %>
|
9
10
|
<meta name="robots" content="noindex">
|
10
|
-
<meta name="alchemy-icon-sprite" content="<%= asset_path("remixicon.symbol.svg") %>">
|
11
11
|
<meta name="turbo-prefetch" content="false">
|
12
12
|
<meta name="turbo-cache-control" content="no-cache">
|
13
13
|
<%= stylesheet_link_tag('alchemy/custom-properties', media: 'screen', 'data-turbo-track' => true) %>
|
14
14
|
<%= stylesheet_link_tag('alchemy/admin', media: 'screen', 'data-turbo-track' => true) %>
|
15
15
|
<%= stylesheet_link_tag('alchemy/admin/print', media: 'print', 'data-turbo-track' => true) %>
|
16
|
-
|
16
|
+
<% Alchemy.admin_stylesheets.each do |stylesheet| %>
|
17
|
+
<%= stylesheet_link_tag(stylesheet, 'data-turbo-track' => true) %>
|
18
|
+
<% end %>
|
17
19
|
<%= yield :stylesheets %>
|
18
20
|
<script>
|
19
21
|
// Global Alchemy JavaScript object.
|
@@ -32,7 +34,9 @@
|
|
32
34
|
<% end %>
|
33
35
|
<%= yield :javascript_includes %>
|
34
36
|
</head>
|
35
|
-
<%= content_tag :body, id: 'alchemy',
|
37
|
+
<%= content_tag :body, id: 'alchemy',
|
38
|
+
class: alchemy_body_class + ["alchemy-light"],
|
39
|
+
style: cookies["alchemy-elements-window-width"] && "--elements-window-width: #{cookies["alchemy-elements-window-width"]}px" do %>
|
36
40
|
<noscript>
|
37
41
|
<h1><%= Alchemy.t(:javascript_disabled_headline) %></h1>
|
38
42
|
<p><%= Alchemy.t(:javascript_disabled_text) %></p>
|
@@ -89,7 +93,7 @@
|
|
89
93
|
<div id="main_content">
|
90
94
|
<%= yield %>
|
91
95
|
</div>
|
92
|
-
<script>
|
96
|
+
<script type="module">
|
93
97
|
// Setting the correct locale for select2 dropdown replacement.
|
94
98
|
$.extend($.fn.select2.defaults, $.fn.select2.locales['<%= ::I18n.locale %>']);
|
95
99
|
</script>
|
data/bun.lockb
CHANGED
Binary file
|
data/bundles/tinymce.js
CHANGED
@@ -3,6 +3,7 @@ import tinymce from "tinymce"
|
|
3
3
|
|
4
4
|
/* Default icons are required. After that, import custom icons if applicable */
|
5
5
|
import "tinymce/icons/default"
|
6
|
+
import "tinymce/icons/remixicons"
|
6
7
|
|
7
8
|
/* Required TinyMCE components */
|
8
9
|
import "tinymce/themes/silver"
|
@@ -16,5 +17,6 @@ import "tinymce/plugins/directionality"
|
|
16
17
|
import "tinymce/plugins/fullscreen"
|
17
18
|
import "tinymce/plugins/link"
|
18
19
|
import "tinymce/plugins/lists"
|
20
|
+
import "tinymce/plugins/alchemy_link"
|
19
21
|
|
20
22
|
export default tinymce
|
data/config/alchemy/config.yml
CHANGED
@@ -199,9 +199,9 @@ link_target_options: [blank]
|
|
199
199
|
# validates_format_of :url, with: Alchemy::Config.get('format_matchers')['url']
|
200
200
|
#
|
201
201
|
format_matchers:
|
202
|
-
email: !ruby/regexp
|
203
|
-
url: !ruby/regexp
|
204
|
-
link_url: !ruby/regexp
|
202
|
+
email: !ruby/regexp /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
|
203
|
+
url: !ruby/regexp /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?\z/ix
|
204
|
+
link_url: !ruby/regexp /^(tel:|mailto:|\/|[a-z]+:\/\/)/
|
205
205
|
|
206
206
|
# The layout used for rendering the +alchemy/admin/pages#show+ action.
|
207
207
|
admin_page_preview_layout: application
|
data/config/alchemy/modules.yml
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
name: Home
|
8
8
|
controller: "/alchemy/admin/dashboard"
|
9
9
|
action: index
|
10
|
-
icon: home-2
|
10
|
+
icon: home-2
|
11
11
|
|
12
12
|
- name: pages
|
13
13
|
engine_name: alchemy
|
@@ -16,7 +16,7 @@
|
|
16
16
|
name: "modules.pages"
|
17
17
|
controller: "/alchemy/admin/pages"
|
18
18
|
action: index
|
19
|
-
icon: pages
|
19
|
+
icon: pages
|
20
20
|
sub_navigation:
|
21
21
|
- name: "modules.pages"
|
22
22
|
controller: "/alchemy/admin/pages"
|
@@ -35,7 +35,7 @@
|
|
35
35
|
name: "modules.menus"
|
36
36
|
controller: "/alchemy/admin/nodes"
|
37
37
|
action: index
|
38
|
-
icon: menu-2
|
38
|
+
icon: menu-2
|
39
39
|
|
40
40
|
- name: languages
|
41
41
|
engine_name: alchemy
|
@@ -45,6 +45,7 @@
|
|
45
45
|
controller: "/alchemy/admin/languages"
|
46
46
|
action: index
|
47
47
|
icon: translate-2
|
48
|
+
icon-style: none
|
48
49
|
|
49
50
|
- name: sites
|
50
51
|
engine_name: alchemy
|
@@ -53,7 +54,7 @@
|
|
53
54
|
name: "modules.sites"
|
54
55
|
controller: "/alchemy/admin/sites"
|
55
56
|
action: index
|
56
|
-
icon: global
|
57
|
+
icon: global
|
57
58
|
|
58
59
|
- name: tags
|
59
60
|
engine_name: alchemy
|
@@ -62,7 +63,7 @@
|
|
62
63
|
name: "modules.tags"
|
63
64
|
controller: "/alchemy/admin/tags"
|
64
65
|
action: index
|
65
|
-
icon: price-tag-3
|
66
|
+
icon: price-tag-3
|
66
67
|
|
67
68
|
- name: archive
|
68
69
|
engine_name: alchemy
|
@@ -71,7 +72,7 @@
|
|
71
72
|
controller: "/alchemy/admin/pictures"
|
72
73
|
action: index
|
73
74
|
name: "modules.library"
|
74
|
-
icon: archive-drawer
|
75
|
+
icon: archive-drawer
|
75
76
|
sub_navigation:
|
76
77
|
- name: "modules.pictures"
|
77
78
|
controller: "/alchemy/admin/pictures"
|
data/config/importmap.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
pin "@ungap/custom-elements", to: "ungap-custom-elements.min.js", preload: true # @1.3.0
|
2
2
|
pin "clipboard", to: "clipboard.min.js", preload: true
|
3
|
+
pin "cropperjs", to: "cropperjs.min.js", preload: true
|
3
4
|
pin "flatpickr", to: "flatpickr.min.js", preload: true # @4.6.13
|
5
|
+
pin "handlebars", to: "handlebars.min.js", preload: true # @4.7.8
|
6
|
+
pin "jquery", to: "jquery.min.js", preload: true
|
4
7
|
pin "keymaster", to: "keymaster.min.js", preload: true
|
8
|
+
pin "select2", to: "select2.min.js", preload: true
|
5
9
|
pin "sortablejs", to: "sortable.min.js", preload: true # @1.15.1
|
6
10
|
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
|
7
11
|
pin "shoelace", to: "shoelace.min.js", preload: true
|
data/config/routes.rb
CHANGED
data/lib/alchemy/engine.rb
CHANGED
@@ -20,6 +20,12 @@ module Alchemy
|
|
20
20
|
NonStupidDigestAssets.whitelist += [/^tinymce\//]
|
21
21
|
end
|
22
22
|
|
23
|
+
initializer "alchemy.admin_stylesheets" do |app|
|
24
|
+
Alchemy.admin_stylesheets.each do |stylesheet|
|
25
|
+
app.config.assets.precompile << stylesheet
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
23
29
|
initializer "alchemy.importmap" do |app|
|
24
30
|
watch_paths = []
|
25
31
|
|