alchemy_cms 7.3.6 → 7.4.0

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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -6
  3. data/Gemfile +3 -3
  4. data/README.md +2 -2
  5. data/alchemy_cms.gemspec +1 -4
  6. data/app/assets/builds/alchemy/admin.css +9 -1
  7. data/app/assets/builds/alchemy/admin.css.map +1 -1
  8. data/app/assets/builds/alchemy/custom-properties.css +1 -1
  9. data/app/assets/builds/alchemy/custom-properties.css.map +1 -1
  10. data/app/assets/builds/alchemy/preview.min.js +1 -0
  11. data/app/assets/builds/alchemy/welcome.css +1 -1
  12. data/app/assets/builds/alchemy/welcome.css.map +1 -1
  13. data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css +1 -1
  14. data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css.map +1 -1
  15. data/app/assets/config/alchemy_manifest.js +0 -4
  16. data/app/assets/javascripts/alchemy/admin.js +8 -6
  17. data/app/assets/stylesheets/alchemy/admin/elements.scss +43 -7
  18. data/app/assets/stylesheets/alchemy/admin/forms.scss +4 -0
  19. data/app/assets/stylesheets/alchemy/admin/navigation.scss +8 -0
  20. data/app/assets/stylesheets/alchemy/admin/preview_window.scss +22 -17
  21. data/app/assets/stylesheets/alchemy/admin.scss +1 -1
  22. data/app/assets/stylesheets/alchemy/custom-properties.css +2 -1
  23. data/app/components/alchemy/admin/link_dialog/internal_tab.rb +1 -2
  24. data/app/controllers/alchemy/admin/base_controller.rb +8 -3
  25. data/app/controllers/alchemy/admin/elements_controller.rb +2 -2
  26. data/app/controllers/alchemy/admin/layoutpages_controller.rb +1 -0
  27. data/app/controllers/alchemy/admin/pages_controller.rb +5 -1
  28. data/app/controllers/alchemy/elements_controller.rb +3 -0
  29. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  30. data/app/helpers/alchemy/admin/navigation_helper.rb +22 -1
  31. data/app/javascript/alchemy_admin/components/action.js +2 -1
  32. data/app/javascript/alchemy_admin/components/dialog_link.js +3 -18
  33. data/app/javascript/alchemy_admin/components/element_editor.js +9 -0
  34. data/app/javascript/alchemy_admin/components/elements_window.js +34 -0
  35. data/app/javascript/alchemy_admin/components/elements_window_handle.js +65 -0
  36. data/app/javascript/alchemy_admin/components/icon.js +2 -2
  37. data/app/javascript/alchemy_admin/components/index.js +1 -0
  38. data/app/javascript/alchemy_admin/components/preview_window.js +5 -5
  39. data/app/javascript/alchemy_admin/components/uploader/file_upload.js +1 -1
  40. data/app/javascript/alchemy_admin/confirm_dialog.js +9 -11
  41. data/app/javascript/alchemy_admin/dialog.js +329 -0
  42. data/app/javascript/alchemy_admin/hotkeys.js +3 -2
  43. data/app/javascript/alchemy_admin/image_cropper.js +57 -40
  44. data/app/javascript/alchemy_admin/image_overlay.js +73 -0
  45. data/app/javascript/alchemy_admin/initializer.js +51 -2
  46. data/app/javascript/alchemy_admin/link_dialog.js +2 -1
  47. data/app/javascript/alchemy_admin/node_tree.js +3 -1
  48. data/app/javascript/alchemy_admin/page_sorter.js +1 -1
  49. data/app/javascript/alchemy_admin/picture_selector.js +2 -1
  50. data/app/javascript/alchemy_admin/shoelace_theme.js +2 -2
  51. data/app/javascript/alchemy_admin/templates/compiled.js +1 -0
  52. data/app/javascript/alchemy_admin.js +10 -6
  53. data/app/javascript/preview.js +117 -0
  54. data/app/models/alchemy/image_cropper_settings.rb +3 -4
  55. data/app/views/alchemy/_preview_mode_code.html.erb +1 -1
  56. data/app/views/alchemy/admin/crop.html.erb +19 -16
  57. data/app/views/alchemy/admin/dashboard/info.html.erb +1 -1
  58. data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +9 -8
  59. data/app/views/alchemy/admin/elements/_clipboard_button.html.erb +14 -0
  60. data/app/views/alchemy/admin/elements/_element.html.erb +2 -0
  61. data/app/views/alchemy/admin/elements/_form.html.erb +15 -13
  62. data/app/views/alchemy/admin/elements/create.turbo_stream.erb +34 -0
  63. data/app/views/alchemy/admin/elements/index.html.erb +3 -15
  64. data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +1 -1
  65. data/app/views/alchemy/admin/layoutpages/edit.html.erb +7 -5
  66. data/app/views/alchemy/admin/nodes/_form.html.erb +1 -1
  67. data/app/views/alchemy/admin/pages/_current_page.html.erb +1 -1
  68. data/app/views/alchemy/admin/pages/_form.html.erb +43 -40
  69. data/app/views/alchemy/admin/pages/_locked_page.html.erb +1 -1
  70. data/app/views/alchemy/admin/pages/_page_layout_filter.html.erb +1 -1
  71. data/app/views/alchemy/admin/pages/_sitemap.html.erb +1 -1
  72. data/app/views/alchemy/admin/pages/_table.html.erb +2 -2
  73. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  74. data/app/views/alchemy/admin/pages/update.turbo_stream.erb +39 -0
  75. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +3 -4
  76. data/app/views/alchemy/admin/pictures/_picture_description_field.html.erb +7 -5
  77. data/app/views/alchemy/admin/pictures/index.html.erb +13 -9
  78. data/app/views/alchemy/admin/resources/_filter_bar.html.erb +1 -1
  79. data/app/views/layouts/alchemy/admin.html.erb +8 -4
  80. data/bun.lockb +0 -0
  81. data/bundles/tinymce.js +2 -0
  82. data/config/alchemy/config.yml +3 -3
  83. data/config/alchemy/modules.yml +7 -6
  84. data/config/importmap.rb +4 -0
  85. data/config/routes.rb +1 -1
  86. data/lib/alchemy/engine.rb +6 -0
  87. data/lib/alchemy/modules.rb +0 -27
  88. data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +10 -10
  89. data/lib/alchemy/tinymce.rb +2 -1
  90. data/lib/alchemy/upgrader/seven_point_four.rb +26 -0
  91. data/lib/alchemy/version.rb +1 -1
  92. data/lib/alchemy.rb +14 -0
  93. data/lib/alchemy_cms.rb +0 -2
  94. data/lib/generators/alchemy/ingredient/ingredient_generator.rb +5 -0
  95. data/lib/generators/alchemy/ingredient/templates/view.html.erb +1 -1
  96. data/lib/generators/alchemy/ingredient/templates/view_component.rb.tt +10 -0
  97. data/lib/generators/alchemy/install/install_generator.rb +0 -1
  98. data/lib/generators/alchemy/install/templates/elements.yml.tt +1 -1
  99. data/lib/tasks/alchemy/upgrade.rake +19 -20
  100. data/rollup.config.mjs +44 -1
  101. data/vendor/javascript/cropperjs.min.js +10 -0
  102. data/vendor/javascript/handlebars.min.js +29 -0
  103. data/vendor/javascript/jquery.min.js +2 -0
  104. data/vendor/javascript/select2.min.js +23 -0
  105. data/vendor/javascript/tinymce.min.js +1 -1
  106. metadata +39 -92
  107. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +0 -271
  108. data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +0 -54
  109. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +0 -97
  110. data/app/assets/javascripts/alchemy/preview.js +0 -1
  111. data/app/assets/javascripts/alchemy/templates/index.js +0 -2
  112. data/app/javascript/alchemy_admin/gui.js +0 -12
  113. data/app/views/alchemy/admin/elements/create.js.erb +0 -35
  114. data/app/views/alchemy/admin/pages/update.js.erb +0 -43
  115. data/lib/alchemy/upgrader/seven_point_zero.rb +0 -36
  116. data/vendor/assets/images/Jcrop.gif +0 -0
  117. data/vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js +0 -7
  118. data/vendor/assets/javascripts/jquery_plugins/select2.js +0 -3729
  119. data/vendor/assets/stylesheets/jquery.Jcrop.min.css +0 -2
  120. data/vendor/assets/stylesheets/tinymce/skins/content/default/content.min.css +0 -1
  121. /data/app/{assets/javascripts/alchemy → javascript/alchemy_admin}/templates/node_folder.hbs +0 -0
  122. /data/app/{assets/javascripts/alchemy → javascript/alchemy_admin}/templates/page_folder.hbs +0 -0
  123. /data/app/{assets/javascripts/tinymce/icons/remixicons/icons.js → javascript/tinymce/icons/remixicons/index.js} +0 -0
  124. /data/app/{assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js → javascript/tinymce/plugins/alchemy_link/index.js} +0 -0
  125. /data/vendor/assets/{fonts → images}/remixicon.symbol.svg +0 -0
@@ -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="text/javascript">
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="text/javascript" charset="utf-8">
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
- <%# Cannot use the render_icon helper, because the navigation["icon"] includes the style %>
10
- <svg class="icon">
11
- <use href="<%= asset_path("remixicon.symbol.svg") %>#ri-<%= navigation["icon"] %>" />
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
- select.addEventListener("change", () => {
25
- const url = new URL(select.dataset.url)
26
- url.searchParams.set("language_id", select.value)
27
- Turbo.visit(url, { frame: "picture_descriptions" })
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="text/javascript" charset="utf-8">
90
- $(function() {
91
- Alchemy.pictureSelector();
92
- $('#picture_archive').on("click", ".thumbnail_background", function(event) {
93
- var url = $(this).attr('href');
94
- var overlay = new Alchemy.ImageOverlay(url);
95
- overlay.open();
96
- event.preventDefault();
97
- return false;
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 %>
@@ -2,7 +2,7 @@
2
2
  <%= render partial: "filter", collection: resource_filters_for_select %>
3
3
  </div>
4
4
 
5
- <script type="text/javascript">
5
+ <script type="module">
6
6
  $(function() {
7
7
  $('select', '#filter_bar').on('change', function(e) {
8
8
  var $this = $(this);
@@ -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
- <%= stylesheet_link_tag('alchemy/admin/custom', 'data-turbo-track' => true) %>
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', class: alchemy_body_class + ["alchemy-light"] do %>
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
@@ -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 '/\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]+:\/\/)/'
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
@@ -7,7 +7,7 @@
7
7
  name: Home
8
8
  controller: "/alchemy/admin/dashboard"
9
9
  action: index
10
- icon: home-2-line
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-line
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-line
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-line
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-line
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-line
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
@@ -88,7 +88,7 @@ Alchemy::Engine.routes.draw do
88
88
  end
89
89
  end
90
90
 
91
- resource :clipboard, only: :index, controller: "clipboard" do
91
+ resource :clipboard, only: [], controller: "clipboard" do
92
92
  collection do
93
93
  get :index
94
94
  delete :clear
@@ -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
 
@@ -27,35 +27,8 @@ module Alchemy
27
27
  def register_module(module_definition)
28
28
  definition_hash = module_definition.deep_stringify_keys
29
29
 
30
- ### Validate controller(s) existence
31
- if definition_hash["navigation"].is_a?(Hash)
32
- defined_controllers = [definition_hash["navigation"]["controller"]]
33
-
34
- if definition_hash["navigation"]["sub_navigation"].is_a?(Array)
35
- defined_controllers.concat(definition_hash["navigation"]["sub_navigation"].map { |x| x["controller"] })
36
- end
37
-
38
- validate_controllers_existence(defined_controllers, definition_hash)
39
- end
40
-
41
30
  @@alchemy_modules |= [definition_hash]
42
31
  end
43
-
44
- private
45
-
46
- def validate_controllers_existence(controllers, definition_hash)
47
- controllers.each do |controller_val|
48
- next if controller_val.blank?
49
-
50
- controller_name = "#{controller_val.camelize}Controller"
51
-
52
- begin
53
- controller_name.constantize
54
- rescue NameError
55
- raise "Error in AlchemyCMS module definition: '#{definition_hash["name"]}'. Could not find the matching controller class #{controller_name.sub(/^::/, "")} for the specified controller: '#{controller_val}'"
56
- end
57
- end
58
- end
59
32
  end
60
33
 
61
34
  # Get the module definition for given module name
@@ -562,8 +562,8 @@ RSpec.shared_examples_for "having picture thumbnails" do
562
562
  context "size 200x50" do
563
563
  let(:size) { "200x50" }
564
564
 
565
- it "default box should be [0, 25, 200, 75]" do
566
- expect(subject[:default_box]).to eq([0, 25, 200, 75])
565
+ it "default box should be [0, 25, 200, 50]" do
566
+ expect(subject[:default_box]).to eq([0, 25, 200, 50])
567
567
  end
568
568
  end
569
569
 
@@ -578,16 +578,16 @@ RSpec.shared_examples_for "having picture thumbnails" do
578
578
  context "size 50x100" do
579
579
  let(:size) { "50x100" }
580
580
 
581
- it "the hash should be {x1: 75, y1: 0, x2: 125, y2: 100}" do
582
- expect(subject[:default_box]).to eq([75, 0, 125, 100])
581
+ it "the hash should be {x1: 75, y1: 0, x2: 50, y2: 100}" do
582
+ expect(subject[:default_box]).to eq([75, 0, 50, 100])
583
583
  end
584
584
  end
585
585
 
586
586
  context "size 50x50" do
587
587
  let(:size) { "50x50" }
588
588
 
589
- it "the hash should be {x1: 50, y1: 0, x2: 150, y2: 100}" do
590
- expect(subject[:default_box]).to eq([50, 0, 150, 100])
589
+ it "the hash should be {x1: 50, y1: 0, x2: 100, y2: 100}" do
590
+ expect(subject[:default_box]).to eq([50, 0, 100, 100])
591
591
  end
592
592
  end
593
593
 
@@ -602,16 +602,16 @@ RSpec.shared_examples_for "having picture thumbnails" do
602
602
  context "size 400x100" do
603
603
  let(:size) { "400x100" }
604
604
 
605
- it "the hash should be {x1: 0, y1: 25, x2: 200, y2: 75}" do
606
- expect(subject[:default_box]).to eq([0, 25, 200, 75])
605
+ it "the hash should be {x1: 0, y1: 25, x2: 200, y2: 50}" do
606
+ expect(subject[:default_box]).to eq([0, 25, 200, 50])
607
607
  end
608
608
  end
609
609
 
610
610
  context "size 200x200" do
611
611
  let(:size) { "200x200" }
612
612
 
613
- it "the hash should be {x1: 50, y1: 0, x2: 150, y2: 100}" do
614
- expect(subject[:default_box]).to eq([50, 0, 150, 100])
613
+ it "the hash should be {x1: 50, y1: 0, x2: 100, y2: 100}" do
614
+ expect(subject[:default_box]).to eq([50, 0, 100, 100])
615
615
  end
616
616
  end
617
617
  end
@@ -5,6 +5,7 @@ module Alchemy
5
5
  mattr_accessor :languages, :plugins
6
6
 
7
7
  DEFAULT_PLUGINS = %w[
8
+ alchemy_link
8
9
  anchor
9
10
  charmap
10
11
  code
@@ -14,7 +15,7 @@ module Alchemy
14
15
  lists
15
16
  ]
16
17
 
17
- @@plugins = DEFAULT_PLUGINS + %w[alchemy_link]
18
+ @@plugins = DEFAULT_PLUGINS
18
19
  @@init = {
19
20
  skin: "alchemy",
20
21
  content_css: "/assets/tinymce/skins/content/alchemy/content.min.css",
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "thor"
5
+
6
+ module Alchemy
7
+ class Upgrader::SevenPointFour < Upgrader
8
+ include Thor::Base
9
+ include Thor::Actions
10
+
11
+ class << self
12
+ def update_custom_css_config
13
+ if File.exist? "app/assets/config/manifest.js"
14
+ log "Removing alchemy/admin/custom.css from assets config file."
15
+ task.gsub_file "app/assets/config/manifest.js", %r{//= link alchemy/admin/custom.css\n}, ""
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def task
22
+ @_task || new
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "7.3.6"
4
+ VERSION = "7.4.0"
5
5
 
6
6
  def self.version
7
7
  VERSION
data/lib/alchemy.rb CHANGED
@@ -98,6 +98,20 @@ module Alchemy
98
98
  }])
99
99
  end
100
100
 
101
+ # Additional stylesheets to be included in the Alchemy admin UI
102
+ #
103
+ # == Example
104
+ #
105
+ # # lib/alchemy/devise/engine.rb
106
+ # initializer "alchemy.devise.stylesheets", before: "alchemy.admin_stylesheets" do
107
+ # Alchemy.admin_stylesheets << "alchemy/devise/admin.css"
108
+ # end
109
+ #
110
+ # @return [Set<String>]
111
+ def self.admin_stylesheets
112
+ @_admin_stylesheets ||= Set.new(["alchemy/admin/custom.css"])
113
+ end
114
+
101
115
  # Define page publish targets
102
116
  #
103
117
  # A publish target is a ActiveJob that gets performed
data/lib/alchemy_cms.rb CHANGED
@@ -11,9 +11,7 @@ require "awesome_nested_set"
11
11
  require "cancan"
12
12
  require "dragonfly"
13
13
  require "gutentag"
14
- require "handlebars_assets"
15
14
  require "importmap-rails"
16
- require "jquery-rails"
17
15
  require "kaminari"
18
16
  require "non_stupid_digest_assets"
19
17
  require "ransack"
@@ -14,6 +14,10 @@ module Alchemy
14
14
  @ingredients_view_path = "app/views/alchemy/ingredients"
15
15
  end
16
16
 
17
+ def create_view_component
18
+ template "view_component.rb.tt", "app/components/alchemy/ingredients/#{file_name}_view.rb"
19
+ end
20
+
17
21
  def create_model
18
22
  template "model.rb.tt", "app/models/alchemy/ingredients/#{file_name}.rb"
19
23
  end
@@ -21,6 +25,7 @@ module Alchemy
21
25
  def copy_templates
22
26
  @ingredient_editor_local = "#{file_name}_editor"
23
27
  @ingredient_view_local = "#{file_name}_view"
28
+ @ingredient_view_component_class = "#{@class_name}View"
24
29
  template "view.html.erb", "#{@ingredients_view_path}/_#{file_name}_view.html.erb"
25
30
  template "editor.html.erb", "#{@ingredients_view_path}/_#{file_name}_editor.html.erb"
26
31
  end
@@ -1 +1 @@
1
- <%%= <%= @ingredient_view_local %>.value %>
1
+ <%%= render Alchemy::Ingredients::<%= @ingredient_view_component_class %>.new(<%= @ingredient_view_local %>) %>
@@ -0,0 +1,10 @@
1
+ module Alchemy
2
+ module Ingredients
3
+ class <%= @class_name %>View < BaseView
4
+
5
+ def call
6
+ content_tag(:div, ingredient.value)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -66,7 +66,6 @@ module Alchemy
66
66
  def install_assets
67
67
  copy_file "all.js", app_vendor_assets_path.join("javascripts", "alchemy", "admin", "all.js")
68
68
  copy_file "custom.css", app_assets_path.join("stylesheets/alchemy/admin/custom.css")
69
- append_to_file Rails.root.join("app/assets/config/manifest.js"), "//= link alchemy/admin/custom.css\n"
70
69
  end
71
70
 
72
71
  def copy_demo_views
@@ -1,6 +1,6 @@
1
1
  # == In this configuration, you set up Alchemy's element layouts.
2
2
  #
3
- # For further information please see http://guides.alchemy-cms.com/stable/elements.html
3
+ # For further information please see http://guides.alchemy-cms.com/elements.html
4
4
 
5
5
  <%- unless @options[:skip_demo_files] -%>
6
6
  - name: article
@@ -7,8 +7,8 @@ namespace :alchemy do
7
7
  desc "Upgrades your app to AlchemyCMS v#{Alchemy::VERSION}."
8
8
  task upgrade: [
9
9
  "alchemy:upgrade:prepare",
10
- "alchemy:upgrade:7.0:run",
11
- "alchemy:upgrade:7.3:run"
10
+ "alchemy:upgrade:7.3:run",
11
+ "alchemy:upgrade:7.4:run"
12
12
  ] do
13
13
  Alchemy::Upgrader.display_todos
14
14
  end
@@ -31,14 +31,6 @@ namespace :alchemy do
31
31
  Alchemy::Upgrader.copy_new_config_file
32
32
  end
33
33
 
34
- desc "Upgrade Alchemy to v7.0"
35
- task "7.0" => [
36
- "alchemy:upgrade:prepare",
37
- "alchemy:upgrade:7.0:run"
38
- ] do
39
- Alchemy::Upgrader.display_todos
40
- end
41
-
42
34
  desc "Upgrade Alchemy to v7.3"
43
35
  task "7.3" => [
44
36
  "alchemy:upgrade:prepare",
@@ -47,16 +39,12 @@ namespace :alchemy do
47
39
  Alchemy::Upgrader.display_todos
48
40
  end
49
41
 
50
- namespace "7.0" do
51
- task "run" => [
52
- "alchemy:upgrade:7.0:remove_admin_entrypoint"
53
- ]
54
-
55
- desc "Remove alchemy admin entrypoint"
56
- task remove_admin_entrypoint: [:environment] do
57
- puts "removing npm_package..."
58
- Alchemy::Upgrader::SevenPointZero.remove_admin_entrypoint
59
- end
42
+ desc "Upgrade Alchemy to v7.4"
43
+ task "7.4" => [
44
+ "alchemy:upgrade:prepare",
45
+ "alchemy:upgrade:7.4:run"
46
+ ] do
47
+ Alchemy::Upgrader.display_todos
60
48
  end
61
49
 
62
50
  namespace "7.3" do
@@ -77,5 +65,16 @@ namespace :alchemy do
77
65
  Alchemy::Upgrader::SevenPointThree.generate_custom_css_entrypoint
78
66
  end
79
67
  end
68
+
69
+ namespace "7.4" do
70
+ task "run" => [
71
+ "alchemy:upgrade:7.4:update_custom_css_config"
72
+ ]
73
+
74
+ desc "Update custom alchemy admin stylesheet config"
75
+ task update_custom_css_config: [:environment] do
76
+ Alchemy::Upgrader::SevenPointFour.update_custom_css_config
77
+ end
78
+ end
80
79
  end
81
80
  end