alchemy_cms 4.4.0 → 4.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +22 -14
- data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +27 -15
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +4 -0
- data/app/assets/stylesheets/alchemy/elements.scss +21 -31
- data/app/helpers/alchemy/admin/elements_helper.rb +3 -7
- data/app/models/alchemy/page.rb +3 -3
- data/app/views/alchemy/admin/elements/_element.html.erb +31 -32
- data/app/views/alchemy/admin/elements/create.js.erb +1 -1
- data/app/views/alchemy/admin/elements/update.js.erb +1 -1
- data/lib/alchemy/auth_accessors.rb +10 -5
- data/lib/alchemy/upgrader/four_point_four.rb +52 -0
- data/lib/alchemy/upgrader/tasks/element_views_updater.rb +34 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/tasks/alchemy/tidy.rake +27 -0
- data/lib/tasks/alchemy/upgrade.rake +32 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfa2cfba392b4282fab17dcd0baf419c2ad6204a4a62eb542fa589a5047cc518
|
4
|
+
data.tar.gz: bc7456380f3bb098ea641066c58afaf2d7d38afea8d7278dcbbdee7c66d10cdb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67f12a17d5b5a483d2054934f2dbc4808748dfa0a437ebb93048fcbecd6af35dc76c657198d0072728afeb7b5c87df84cdec2c1ba1dc48b2056c999251003741
|
7
|
+
data.tar.gz: 77760e2ffc8287532502ad93e55e738fcaddf67e09d4f7ffbf7405648e0d265be8f6dc1ad29a90ec40361a8cdceec17033a436e405f14b923422cf5d3a5f3066
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 5.0.0 (unreleased)
|
2
|
+
|
3
|
+
## 4.4.1 (2020-01-08)
|
4
|
+
|
5
|
+
- Fix updating page preview after element create/save [#1710](https://github.com/AlchemyCMS/alchemy_cms/pull/1710) ([tvdeyen](https://github.com/tvdeyen))
|
6
|
+
- Element editor layout changes [#1709](https://github.com/AlchemyCMS/alchemy_cms/pull/1709) ([tvdeyen](https://github.com/tvdeyen))
|
7
|
+
- Add Alchemy.user_class_primary_key setting [#1708](https://github.com/AlchemyCMS/alchemy_cms/pull/1708) ([tvdeyen](https://github.com/tvdeyen))
|
8
|
+
- Add Element views upgrade tasks [#1707](https://github.com/AlchemyCMS/alchemy_cms/pull/1707) ([tvdeyen](https://github.com/tvdeyen))
|
9
|
+
- Use postMessage to send messages between preview and element windows [#1704](https://github.com/AlchemyCMS/alchemy_cms/pull/1704) ([tvdeyen](https://github.com/tvdeyen))
|
10
|
+
|
1
11
|
## 4.4.0 (2020-01-06)
|
2
12
|
|
3
13
|
- Use contents settings for size in EssencePicture#picture_url [#1703](https://github.com/AlchemyCMS/alchemy_cms/pull/1703) ([tvdeyen](https://github.com/tvdeyen))
|
@@ -36,20 +36,21 @@ Alchemy.ElementEditors =
|
|
36
36
|
# Binds the custom SaveElement event
|
37
37
|
@element_area.on "SaveElement.Alchemy", '.element-editor', (e, data) =>
|
38
38
|
@onSaveElement(e, data)
|
39
|
+
# Listen to postMessage messages from the preview frame
|
40
|
+
window.addEventListener 'message', (e) =>
|
41
|
+
if e.origin == window.location.origin
|
42
|
+
@onMessage(e.data)
|
43
|
+
else
|
44
|
+
console.warn 'Unsafe message origin!', e.origin
|
45
|
+
true
|
39
46
|
return
|
40
47
|
|
41
48
|
# Selects and scrolls to element with given id in the preview window.
|
42
49
|
#
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
.querySelectorAll('[data-alchemy-element]')
|
48
|
-
previewElement = Array.from(previewElements).find (element) ->
|
49
|
-
element.getAttribute('data-alchemy-element') == element_id
|
50
|
-
if previewElement
|
51
|
-
event = new Event('SelectPreviewElement.Alchemy')
|
52
|
-
previewElement.dispatchEvent(event)
|
50
|
+
focusElementPreview: (element_id) ->
|
51
|
+
Alchemy.PreviewWindow.postMessage
|
52
|
+
message: 'Alchemy.focusElement'
|
53
|
+
element_id: element_id
|
53
54
|
return
|
54
55
|
|
55
56
|
# Selects element
|
@@ -60,6 +61,7 @@ Alchemy.ElementEditors =
|
|
60
61
|
# Used by the elements on click events in the preview frame.
|
61
62
|
focusElement: ($element) ->
|
62
63
|
element_id = $element.attr('id').replace(/\D/g, "")
|
64
|
+
Alchemy.ElementsWindow.show()
|
63
65
|
@selectTabForElement($element)
|
64
66
|
# If we have folded parents we need to unfold each of them
|
65
67
|
# and then finally scroll to or unfold ourself
|
@@ -173,25 +175,31 @@ Alchemy.ElementEditors =
|
|
173
175
|
|
174
176
|
# Event handlers
|
175
177
|
|
178
|
+
onMessage: (data) ->
|
179
|
+
if data.message == 'Alchemy.focusElementEditor'
|
180
|
+
$element = $("#element_#{data.element_id}")
|
181
|
+
Alchemy.ElementEditors.focusElement($element)
|
182
|
+
else
|
183
|
+
console.warn 'Unknown message received!', data
|
184
|
+
|
176
185
|
onClickBody: (e) ->
|
177
|
-
frameWindow = $('#alchemy_preview_window')[0].contentWindow
|
178
186
|
element = $(e.target).parents('.element-editor')[0]
|
179
187
|
$('#element_area .element-editor').not(element).removeClass('selected')
|
180
188
|
unless element
|
181
|
-
|
189
|
+
Alchemy.PreviewWindow.postMessage(message: 'Alchemy.blurElements')
|
182
190
|
return
|
183
191
|
|
184
192
|
# Click event handler for element body.
|
185
193
|
#
|
186
194
|
# - Focuses the element
|
187
|
-
# -
|
195
|
+
# - Sends 'Alchemy.focusElement' message to preview frame.
|
188
196
|
#
|
189
197
|
onClickElement: (e) ->
|
190
198
|
$target = $(e.target)
|
191
199
|
$element = $target.closest(".element-editor")
|
192
200
|
element_id = $element.attr("id").replace(/\D/g, "")
|
193
201
|
@selectElement($element)
|
194
|
-
@
|
202
|
+
@focusElementPreview(element_id)
|
195
203
|
return
|
196
204
|
|
197
205
|
# Double click event handler for element head.
|
@@ -21,11 +21,16 @@ Alchemy.initAlchemyPreviewMode = ->
|
|
21
21
|
"outline-offset": "4px"
|
22
22
|
|
23
23
|
init: ->
|
24
|
-
window.addEventListener "message", (
|
25
|
-
if
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
window.addEventListener "message", (event) =>
|
25
|
+
if event.origin != window.location.origin
|
26
|
+
console.warn 'Unsafe message origin!', event.origin
|
27
|
+
return
|
28
|
+
switch event.data.message
|
29
|
+
when "Alchemy.blurElements" then @blurElements()
|
30
|
+
when "Alchemy.focusElement" then @focusElement(event.data)
|
31
|
+
else console.info("Received unknown message!", event.data)
|
32
|
+
return
|
33
|
+
@elements = Array.from document.querySelectorAll("[data-alchemy-element]")
|
29
34
|
@elements.forEach (element) =>
|
30
35
|
element.addEventListener 'mouseover', =>
|
31
36
|
unless element.classList.contains('selected')
|
@@ -35,10 +40,6 @@ Alchemy.initAlchemyPreviewMode = ->
|
|
35
40
|
unless element.classList.contains('selected')
|
36
41
|
Object.assign element.style, @getStyle('reset')
|
37
42
|
return
|
38
|
-
element.addEventListener 'SelectPreviewElement.Alchemy', =>
|
39
|
-
@selectElement(element)
|
40
|
-
return
|
41
|
-
, false
|
42
43
|
element.addEventListener 'click', (e) =>
|
43
44
|
e.stopPropagation()
|
44
45
|
e.preventDefault()
|
@@ -66,14 +67,25 @@ Alchemy.initAlchemyPreviewMode = ->
|
|
66
67
|
return
|
67
68
|
return
|
68
69
|
|
70
|
+
# Focus the element in the Alchemy preview window.
|
71
|
+
focusElement: (data) ->
|
72
|
+
element = @getElement(data.element_id)
|
73
|
+
if element
|
74
|
+
@selectElement(element)
|
75
|
+
else
|
76
|
+
console.warn('Could not focus element with id', data.element_id)
|
77
|
+
|
78
|
+
getElement: (element_id) ->
|
79
|
+
@elements.find (element) ->
|
80
|
+
element.dataset.alchemyElement == element_id.toString()
|
81
|
+
|
69
82
|
# Focus the element editor in the Alchemy element window.
|
70
83
|
focusElementEditor: (element) ->
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
elements_window.show() if elements_window.hidden
|
84
|
+
element_id = element.getAttribute('data-alchemy-element')
|
85
|
+
window.parent.postMessage
|
86
|
+
message: 'Alchemy.focusElementEditor'
|
87
|
+
element_id: element_id
|
88
|
+
, window.location.origin
|
77
89
|
return
|
78
90
|
|
79
91
|
getStyle: (state) ->
|
@@ -32,6 +32,10 @@ Alchemy.PreviewWindow =
|
|
32
32
|
$iframe.attr 'src', $iframe.attr('src')
|
33
33
|
true
|
34
34
|
|
35
|
+
postMessage: (data) ->
|
36
|
+
frameWindow = @currentWindow[0].contentWindow
|
37
|
+
frameWindow.postMessage(data, window.location.origin)
|
38
|
+
|
35
39
|
_showSpinner: ->
|
36
40
|
@reload = $('#reload_preview_button')
|
37
41
|
@spinner = new Alchemy.Spinner('small')
|
@@ -155,6 +155,22 @@
|
|
155
155
|
}
|
156
156
|
}
|
157
157
|
|
158
|
+
&.expanded {
|
159
|
+
&.not-fixed {
|
160
|
+
.nestable-elements {
|
161
|
+
box-shadow: inset 0 4px 8px -2px darken($medium-gray, 15%);
|
162
|
+
background-color: $medium-gray;
|
163
|
+
padding: 8px 4px 4px;
|
164
|
+
|
165
|
+
.add-nestable-element-button {
|
166
|
+
width: calc(50% - 8px);
|
167
|
+
margin: 4px;
|
168
|
+
text-align: center;
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
158
174
|
&.dragged {
|
159
175
|
border-style: dotted;
|
160
176
|
overflow: hidden;
|
@@ -165,15 +181,6 @@
|
|
165
181
|
}
|
166
182
|
}
|
167
183
|
|
168
|
-
&.with-contents,
|
169
|
-
&.without-contents.not-nestable {
|
170
|
-
|
171
|
-
.element-content {
|
172
|
-
padding: 2*$default-padding 2*$default-padding 0;
|
173
|
-
border-top: 1px solid $medium-gray;
|
174
|
-
}
|
175
|
-
}
|
176
|
-
|
177
184
|
&.compact {
|
178
185
|
.element-toolbar {
|
179
186
|
visibility: hidden;
|
@@ -194,7 +201,6 @@
|
|
194
201
|
}
|
195
202
|
|
196
203
|
.element-footer {
|
197
|
-
margin-top: 0;
|
198
204
|
padding-top: 0;
|
199
205
|
border-top: 0;
|
200
206
|
|
@@ -223,7 +229,7 @@
|
|
223
229
|
}
|
224
230
|
|
225
231
|
.element-content {
|
226
|
-
|
232
|
+
margin: 4px 8px;
|
227
233
|
}
|
228
234
|
|
229
235
|
.button_with_label {
|
@@ -253,8 +259,8 @@
|
|
253
259
|
}
|
254
260
|
}
|
255
261
|
|
256
|
-
|
257
|
-
margin:
|
262
|
+
.element-content {
|
263
|
+
margin: 2*$default-padding;
|
258
264
|
}
|
259
265
|
|
260
266
|
.validation_notice {
|
@@ -266,8 +272,7 @@
|
|
266
272
|
}
|
267
273
|
|
268
274
|
.message {
|
269
|
-
|
270
|
-
margin: 2*$default-margin 0;
|
275
|
+
margin: 2*$default-margin;
|
271
276
|
}
|
272
277
|
|
273
278
|
.foot_note {
|
@@ -332,6 +337,7 @@
|
|
332
337
|
.element-toolbar {
|
333
338
|
padding: $default-padding 0;
|
334
339
|
height: $element-toolbar-height;
|
340
|
+
border-bottom: 1px solid $medium-gray;
|
335
341
|
|
336
342
|
.element_tools {
|
337
343
|
float: left;
|
@@ -341,7 +347,6 @@
|
|
341
347
|
|
342
348
|
.element-footer {
|
343
349
|
border-top: 1px solid $medium-gray;
|
344
|
-
margin: 8px 0 0 0;
|
345
350
|
padding: 2*$default-padding;
|
346
351
|
text-align: right;
|
347
352
|
|
@@ -762,21 +767,6 @@ textarea.has_tinymce {
|
|
762
767
|
top: -1px;
|
763
768
|
}
|
764
769
|
|
765
|
-
.not-fixed .nestable-elements {
|
766
|
-
box-shadow: inset 0 4px 8px -2px darken($medium-gray, 15%);
|
767
|
-
background-color: $medium-gray;
|
768
|
-
|
769
|
-
.expanded.element-editor>& {
|
770
|
-
padding: 8px 4px 4px;
|
771
|
-
}
|
772
|
-
|
773
|
-
.add-nestable-element-button {
|
774
|
-
width: calc(50% - 8px);
|
775
|
-
margin: 4px;
|
776
|
-
text-align: center;
|
777
|
-
}
|
778
|
-
}
|
779
|
-
|
780
770
|
.is-fixed {
|
781
771
|
&.with-contents {
|
782
772
|
>.element-footer {
|
@@ -101,14 +101,10 @@ module Alchemy
|
|
101
101
|
].join(' ')
|
102
102
|
end
|
103
103
|
|
104
|
-
# Tells us, if we should show the element footer.
|
105
|
-
def
|
104
|
+
# Tells us, if we should show the element footer and form inputs.
|
105
|
+
def element_editable?(element)
|
106
106
|
return false if element.folded?
|
107
|
-
|
108
|
-
element.content_definitions.present? || element.taggable?
|
109
|
-
else
|
110
|
-
element.nestable_elements.empty?
|
111
|
-
end
|
107
|
+
element.content_definitions.present? || element.taggable?
|
112
108
|
end
|
113
109
|
end
|
114
110
|
end
|
data/app/models/alchemy/page.rb
CHANGED
@@ -90,19 +90,19 @@ module Alchemy
|
|
90
90
|
belongs_to :language, optional: true
|
91
91
|
|
92
92
|
belongs_to :creator,
|
93
|
-
primary_key: Alchemy.
|
93
|
+
primary_key: Alchemy.user_class_primary_key,
|
94
94
|
class_name: Alchemy.user_class_name,
|
95
95
|
foreign_key: :creator_id,
|
96
96
|
optional: true
|
97
97
|
|
98
98
|
belongs_to :updater,
|
99
|
-
primary_key: Alchemy.
|
99
|
+
primary_key: Alchemy.user_class_primary_key,
|
100
100
|
class_name: Alchemy.user_class_name,
|
101
101
|
foreign_key: :updater_id,
|
102
102
|
optional: true
|
103
103
|
|
104
104
|
belongs_to :locker,
|
105
|
-
primary_key: Alchemy.
|
105
|
+
primary_key: Alchemy.user_class_primary_key,
|
106
106
|
class_name: Alchemy.user_class_name,
|
107
107
|
foreign_key: :locked_by,
|
108
108
|
optional: true
|
@@ -10,44 +10,47 @@
|
|
10
10
|
<% if element.expanded? || element.fixed? %>
|
11
11
|
<%= render 'alchemy/admin/elements/element_toolbar', element: element %>
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
<% element.definition[:message].tap do |message| %>
|
14
|
+
<%= render_message(:info, sanitize(message)) if message %>
|
15
|
+
<% end %>
|
15
16
|
|
16
|
-
|
17
|
+
<% element.definition[:warning].tap do |warning| %>
|
18
|
+
<%= render_message(:warning, sanitize(warning)) if warning %>
|
19
|
+
<% end %>
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
<% if element_editable?(element) %>
|
22
|
+
<%= form_for [alchemy, :admin, element], remote: true,
|
23
|
+
html: {id: "element_#{element.id}_form".html_safe, class: 'element-content'} do |f| %>
|
24
|
+
|
25
|
+
<div id="element_<%= element.id %>_errors" class="element_errors"></div>
|
26
|
+
|
27
|
+
<div id="element_<%= element.id %>_content" class="element-content-editors">
|
28
|
+
<% if lookup_context.exists?("#{element.name}_editor", ["alchemy/elements"], true) %>
|
29
|
+
<%= render_editor(element) %>
|
30
|
+
<% else %>
|
31
|
+
<%= element_editor_for(element) do %>
|
32
|
+
<% element.contents.each do |content| %>
|
33
|
+
<%= render "alchemy/essences/#{content.essence_partial_name}_editor", {
|
34
|
+
content: content
|
35
|
+
} %>
|
36
|
+
<% end %>
|
33
37
|
<% end %>
|
34
38
|
<% end %>
|
35
|
-
<% end %>
|
36
|
-
</div>
|
37
|
-
|
38
|
-
<% if element.taggable? %>
|
39
|
-
<div class="autocomplete_tag_list">
|
40
|
-
<%= f.label :tag_list %>
|
41
|
-
<%= render 'alchemy/admin/partials/autocomplete_tag_list', f: f %>
|
42
39
|
</div>
|
40
|
+
|
41
|
+
<% if element.taggable? %>
|
42
|
+
<div class="autocomplete_tag_list">
|
43
|
+
<%= f.label :tag_list %>
|
44
|
+
<%= render 'alchemy/admin/partials/autocomplete_tag_list', f: f %>
|
45
|
+
</div>
|
46
|
+
<% end %>
|
43
47
|
<% end %>
|
48
|
+
|
49
|
+
<%= render 'alchemy/admin/elements/element_footer', element: element %>
|
44
50
|
<% end %>
|
45
51
|
<% end %>
|
46
52
|
|
47
53
|
<% if element.nestable_elements.any? %>
|
48
|
-
<% if show_element_footer?(element, :with_nestable_elements) %>
|
49
|
-
<%= render 'alchemy/admin/elements/element_footer', element: element %>
|
50
|
-
<% end %>
|
51
54
|
<div class="nestable-elements">
|
52
55
|
<%= content_tag :div,
|
53
56
|
class: "nested-elements", data: {
|
@@ -82,8 +85,4 @@
|
|
82
85
|
<% end %>
|
83
86
|
</div>
|
84
87
|
<% end %>
|
85
|
-
|
86
|
-
<% if show_element_footer?(element) %>
|
87
|
-
<%= render 'alchemy/admin/elements/element_footer', element: element %>
|
88
|
-
<% end %>
|
89
88
|
<% end %>
|
@@ -36,7 +36,7 @@
|
|
36
36
|
Alchemy.closeCurrentDialog();
|
37
37
|
Alchemy.Tinymce.init(<%= @element.richtext_contents_ids.to_json %>);
|
38
38
|
Alchemy.PreviewWindow.refresh(function() {
|
39
|
-
Alchemy.ElementEditors.
|
39
|
+
Alchemy.ElementEditors.focusElementPreview(<%= @element.id %>);
|
40
40
|
});
|
41
41
|
|
42
42
|
$el = $('#element_<%= @element.id %>');
|
@@ -9,7 +9,7 @@
|
|
9
9
|
$el.trigger('SaveElement.Alchemy', {previewText: '<%= j sanitize(@element.preview_text) %>'});
|
10
10
|
Alchemy.growl('<%= Alchemy.t(:element_saved) %>');
|
11
11
|
Alchemy.PreviewWindow.refresh(function() {
|
12
|
-
Alchemy.ElementEditors.
|
12
|
+
Alchemy.ElementEditors.focusElementPreview(<%= @element.id %>);
|
13
13
|
});
|
14
14
|
|
15
15
|
<%- else -%>
|
@@ -5,6 +5,7 @@
|
|
5
5
|
# Alchemy has some defaults for user model name and login logout path names:
|
6
6
|
#
|
7
7
|
# +Alchemy.user_class_name+ defaults to +'User'+
|
8
|
+
# +Alchemy.user_class_primary_key+ defaults to +:id+
|
8
9
|
# +Alchemy.current_user_method defaults to +'current_user'+
|
9
10
|
# +Alchemy.signup_path defaults to +'/signup'+
|
10
11
|
# +Alchemy.login_path defaults to +'/login'+
|
@@ -14,17 +15,19 @@
|
|
14
15
|
# Anyway, you can tell Alchemy about your authentication model configuration:
|
15
16
|
#
|
16
17
|
# 1. Your user class name - @see: Alchemy.user_class
|
17
|
-
# 2.
|
18
|
+
# 2. Your users table primary key - @see: Alchemy.user_class_primary_key
|
19
|
+
# 3. A method on your ApplicationController to get current user -
|
18
20
|
# @see: Alchemy.current_user_method
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# 4. The path to the signup form - @see: Alchemy.signup_path
|
22
|
+
# 5. The path to the login form - @see: Alchemy.login_path
|
23
|
+
# 6. The path to the logout method - @see: Alchemy.logout_path
|
24
|
+
# 7. The http verb for the logout method - @see: Alchemy.logout_method
|
23
25
|
#
|
24
26
|
# == Example
|
25
27
|
#
|
26
28
|
# # config/initializers/alchemy.rb
|
27
29
|
# Alchemy.user_class_name = 'Admin'
|
30
|
+
# Alchemy.user_class_primary_key = :user_id
|
28
31
|
# Alchemy.current_user_method = 'current_admin'
|
29
32
|
# Alchemy.signup_path = '/auth/signup'
|
30
33
|
# Alchemy.login_path = '/auth/login'
|
@@ -42,6 +45,7 @@
|
|
42
45
|
#
|
43
46
|
module Alchemy
|
44
47
|
mattr_accessor :user_class_name,
|
48
|
+
:user_class_primary_key,
|
45
49
|
:current_user_method,
|
46
50
|
:signup_path,
|
47
51
|
:login_path,
|
@@ -51,6 +55,7 @@ module Alchemy
|
|
51
55
|
# Defaults
|
52
56
|
#
|
53
57
|
@@user_class_name = 'User'
|
58
|
+
@@user_class_primary_key = :id
|
54
59
|
@@current_user_method = 'current_user'
|
55
60
|
@@signup_path = '/signup'
|
56
61
|
@@login_path = '/login'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'tasks/element_views_updater'
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
class Upgrader::FourPointFour < Upgrader
|
7
|
+
class << self
|
8
|
+
def rename_element_views
|
9
|
+
desc "Remove '_view' suffix from element views."
|
10
|
+
Alchemy::Upgrader::Tasks::ElementViewsUpdater.new.rename_element_views
|
11
|
+
end
|
12
|
+
|
13
|
+
def update_local_variable
|
14
|
+
desc 'Update element views local variable to element name.'
|
15
|
+
Alchemy::Upgrader::Tasks::ElementViewsUpdater.new.update_local_variable
|
16
|
+
end
|
17
|
+
|
18
|
+
def alchemy_4_4_todos
|
19
|
+
notice = <<-NOTE.strip_heredoc
|
20
|
+
|
21
|
+
ℹ️ Element editor partials are deprecated
|
22
|
+
-----------------------------------------
|
23
|
+
|
24
|
+
The element editor partials are not needed anymore. They still work, but in order to
|
25
|
+
prepare the Alchemy 5 upgrade your should consider removing them now.
|
26
|
+
|
27
|
+
In order to update check if you have any messages in your editor partials and move them
|
28
|
+
to either a `warning` or `message` in your element definition.
|
29
|
+
|
30
|
+
Also check if you pass any values to EssenceSelects `select_values`. Move static values
|
31
|
+
to the `settings` of your content definition and either use EssencePage for referencing
|
32
|
+
pages or create a custom essence for other dynamic values.
|
33
|
+
|
34
|
+
|
35
|
+
ℹ️ The `_view` suffix of Element view partials is deprecated
|
36
|
+
-----------------------------------------------------------
|
37
|
+
|
38
|
+
The element view partials do not need the `_view` suffix anymore. Your files have been
|
39
|
+
renamed.
|
40
|
+
|
41
|
+
The local variable in your element views has been replaced by a variable named after the
|
42
|
+
element itself. A "article" element has a "_article.html.erb" partial and therefore
|
43
|
+
a `article` local variable now.
|
44
|
+
|
45
|
+
The former `element` variable is still present, though.
|
46
|
+
|
47
|
+
NOTE
|
48
|
+
todo notice, 'Alchemy v4.4 TODO'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'alchemy/upgrader'
|
4
|
+
|
5
|
+
module Alchemy::Upgrader::Tasks
|
6
|
+
class ElementViewsUpdater < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
no_tasks do
|
10
|
+
def rename_element_views
|
11
|
+
puts "-- Removing '_view' suffix from element views"
|
12
|
+
|
13
|
+
Dir.glob("#{elements_view_folder}/*_view.*").each do |file|
|
14
|
+
FileUtils.mv(file, file.to_s.sub(/_view/, ''))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def update_local_variable
|
19
|
+
puts "-- Updating element views local variable to element name"
|
20
|
+
|
21
|
+
Alchemy::Element.definitions.map { |e| e['name'] }.each do |name|
|
22
|
+
view = Dir.glob("#{elements_view_folder}/_#{name}.*").last
|
23
|
+
gsub_file(view, /\b#{name}_view\b/, name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def elements_view_folder
|
31
|
+
Rails.root.join('app', 'views', 'alchemy', 'elements')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/alchemy/version.rb
CHANGED
data/lib/tasks/alchemy/tidy.rake
CHANGED
@@ -34,5 +34,32 @@ namespace :alchemy do
|
|
34
34
|
task remove_orphaned_contents: [:environment] do
|
35
35
|
Alchemy::Tidy.remove_orphaned_contents
|
36
36
|
end
|
37
|
+
|
38
|
+
desc "List Alchemy elements usage"
|
39
|
+
task elements_usage: :environment do
|
40
|
+
puts "\n"
|
41
|
+
removable_elements = []
|
42
|
+
names = Alchemy::Element.definitions.map { |e| e['name'] }
|
43
|
+
longest_name = names.max_by { |name| name.to_s.length }.length + 1
|
44
|
+
names.sort.each do |name|
|
45
|
+
names = Alchemy::Element.where(name: name)
|
46
|
+
count = names.count
|
47
|
+
page_count = Alchemy::Page.where(id: names.pluck(:page_id)).published.count
|
48
|
+
if count.zero?
|
49
|
+
removable_elements.push(name)
|
50
|
+
else
|
51
|
+
spacer = ' ' * (longest_name - name.length)
|
52
|
+
puts "#{name}#{spacer}is used\t#{count}\ttime(s) on\t#{page_count}\tpublic page(s)"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
if removable_elements.many?
|
56
|
+
puts "\n"
|
57
|
+
puts "These elements can probably be removed. They are not used anywhere:"
|
58
|
+
puts "\n"
|
59
|
+
removable_elements.each do |name|
|
60
|
+
puts name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
37
64
|
end
|
38
65
|
end
|
@@ -6,7 +6,8 @@ namespace :alchemy do
|
|
6
6
|
task upgrade: [
|
7
7
|
'alchemy:upgrade:prepare',
|
8
8
|
'alchemy:upgrade:4.1:run', 'alchemy:upgrade:4.1:todo',
|
9
|
-
'alchemy:upgrade:4.2:run', 'alchemy:upgrade:4.2:todo'
|
9
|
+
'alchemy:upgrade:4.2:run', 'alchemy:upgrade:4.2:todo',
|
10
|
+
'alchemy:upgrade:4.4:run', 'alchemy:upgrade:4.4:todo'
|
10
11
|
] do
|
11
12
|
Alchemy::Upgrader.display_todos
|
12
13
|
end
|
@@ -105,5 +106,35 @@ namespace :alchemy do
|
|
105
106
|
Alchemy::Upgrader::FourPointTwo.alchemy_4_2_todos
|
106
107
|
end
|
107
108
|
end
|
109
|
+
|
110
|
+
desc 'Upgrade Alchemy to v4.4'
|
111
|
+
task '4.4' => [
|
112
|
+
'alchemy:upgrade:prepare',
|
113
|
+
'alchemy:upgrade:4.4:run',
|
114
|
+
'alchemy:upgrade:4.4:todo'
|
115
|
+
] do
|
116
|
+
Alchemy::Upgrader.display_todos
|
117
|
+
end
|
118
|
+
|
119
|
+
namespace '4.4' do
|
120
|
+
task run: [
|
121
|
+
'alchemy:upgrade:4.4:rename_element_views',
|
122
|
+
'alchemy:upgrade:4.4:update_local_variable'
|
123
|
+
]
|
124
|
+
|
125
|
+
desc "Remove '_view' suffix from element views."
|
126
|
+
task rename_element_views: [:environment] do
|
127
|
+
Alchemy::Upgrader::FourPointFour.rename_element_views
|
128
|
+
end
|
129
|
+
|
130
|
+
desc 'Update element views local variable to element name.'
|
131
|
+
task update_local_variable: [:environment] do
|
132
|
+
Alchemy::Upgrader::FourPointFour.update_local_variable
|
133
|
+
end
|
134
|
+
|
135
|
+
task :todo do
|
136
|
+
Alchemy::Upgrader::FourPointFour.alchemy_4_4_todos
|
137
|
+
end
|
138
|
+
end
|
108
139
|
end
|
109
140
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alchemy_cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.4.
|
4
|
+
version: 4.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas von Deyen
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2020-01-
|
16
|
+
date: 2020-01-08 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: active_model_serializers
|
@@ -1051,11 +1051,13 @@ files:
|
|
1051
1051
|
- lib/alchemy/test_support/shared_uploader_examples.rb
|
1052
1052
|
- lib/alchemy/tinymce.rb
|
1053
1053
|
- lib/alchemy/upgrader.rb
|
1054
|
+
- lib/alchemy/upgrader/four_point_four.rb
|
1054
1055
|
- lib/alchemy/upgrader/four_point_one.rb
|
1055
1056
|
- lib/alchemy/upgrader/four_point_two.rb
|
1056
1057
|
- lib/alchemy/upgrader/tasks/cells_migration.rb
|
1057
1058
|
- lib/alchemy/upgrader/tasks/cells_upgrader.rb
|
1058
1059
|
- lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb
|
1060
|
+
- lib/alchemy/upgrader/tasks/element_views_updater.rb
|
1059
1061
|
- lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb
|
1060
1062
|
- lib/alchemy/upgrader/tasks/picture_gallery_migration.rb
|
1061
1063
|
- lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb
|
@@ -1188,7 +1190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1188
1190
|
version: '0'
|
1189
1191
|
requirements:
|
1190
1192
|
- ImageMagick (libmagick), v6.6 or greater.
|
1191
|
-
rubygems_version: 3.
|
1193
|
+
rubygems_version: 3.0.3
|
1192
1194
|
signing_key:
|
1193
1195
|
specification_version: 4
|
1194
1196
|
summary: A powerful, userfriendly and flexible CMS for Rails 5
|