alchemy_cms 4.5.1 → 4.6.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.
Potentially problematic release.
This version of alchemy_cms might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +11 -14
- data/.rubocop.yml +7 -15
- data/CHANGELOG.md +18 -8
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +5 -5
- data/app/assets/javascripts/alchemy/templates/page.hbs +1 -1
- data/app/assets/stylesheets/alchemy/_mixins.scss +2 -3
- data/app/assets/stylesheets/alchemy/_variables.scss +2 -2
- data/app/assets/stylesheets/alchemy/lists.scss +0 -8
- data/app/assets/stylesheets/alchemy/nodes.scss +1 -1
- data/app/assets/stylesheets/alchemy/sitemap.scss +59 -21
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +6 -6
- data/app/controllers/alchemy/admin/pages_controller.rb +0 -1
- data/app/controllers/alchemy/api/pages_controller.rb +2 -0
- data/app/decorators/alchemy/content_editor.rb +55 -0
- data/app/helpers/alchemy/admin/pages_helper.rb +16 -16
- data/app/models/alchemy/attachment.rb +1 -1
- data/app/models/alchemy/content.rb +9 -23
- data/app/models/alchemy/element.rb +1 -1
- data/app/models/alchemy/node.rb +9 -8
- data/app/models/alchemy/page/url_path.rb +66 -0
- data/app/models/alchemy/page.rb +12 -1
- data/app/models/alchemy/picture.rb +1 -1
- data/app/serializers/alchemy/page_serializer.rb +2 -1
- data/app/serializers/alchemy/page_tree_serializer.rb +4 -3
- data/app/views/alchemy/admin/layoutpages/index.html.erb +5 -1
- data/app/views/alchemy/admin/nodes/_form.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_menu_fields.html.erb +33 -29
- data/app/views/alchemy/admin/pages/_page.html.erb +3 -6
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +6 -0
- data/app/views/alchemy/admin/pages/info.html.erb +1 -1
- data/config/alchemy/config.yml +0 -6
- data/config/locales/alchemy.en.yml +6 -6
- data/lib/alchemy/config.rb +30 -2
- data/lib/alchemy/essence.rb +1 -1
- data/lib/alchemy/resource.rb +4 -6
- data/lib/alchemy/ssl_protection.rb +3 -1
- data/lib/alchemy/upgrader/four_point_six.rb +50 -0
- data/lib/alchemy/upgrader/four_point_two.rb +0 -1
- data/lib/alchemy/upgrader/tasks/cells_migration.rb +1 -2
- data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +3 -21
- data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +4 -8
- data/lib/alchemy/userstamp.rb +1 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/tasks/alchemy/convert.rake +2 -0
- data/lib/tasks/alchemy/upgrade.rake +67 -46
- metadata +8 -6
- data/lib/alchemy/upgrader/tasks/fixed_element_name_finder.rb +0 -31
data/app/models/alchemy/node.rb
CHANGED
@@ -4,12 +4,12 @@ module Alchemy
|
|
4
4
|
class Node < BaseRecord
|
5
5
|
VALID_URL_REGEX = /\A(\/|\D[a-z\+\d\.\-]+:)/
|
6
6
|
|
7
|
-
acts_as_nested_set scope:
|
8
|
-
stampable stamper_class_name: Alchemy.
|
7
|
+
acts_as_nested_set scope: "language_id", touch: true
|
8
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
9
9
|
|
10
|
-
belongs_to :site, class_name:
|
11
|
-
belongs_to :language, class_name:
|
12
|
-
belongs_to :page, class_name:
|
10
|
+
belongs_to :site, class_name: "Alchemy::Site"
|
11
|
+
belongs_to :language, class_name: "Alchemy::Language"
|
12
|
+
belongs_to :page, class_name: "Alchemy::Page", optional: true, inverse_of: :nodes
|
13
13
|
|
14
14
|
validates :name, presence: true, if: -> { page.nil? }
|
15
15
|
validates :url, format: { with: VALID_URL_REGEX }, unless: -> { url.nil? }
|
@@ -25,7 +25,8 @@ module Alchemy
|
|
25
25
|
class << self
|
26
26
|
# Returns all root nodes for current language
|
27
27
|
def language_root_nodes
|
28
|
-
raise
|
28
|
+
raise "No language found" if Language.current.nil?
|
29
|
+
|
29
30
|
roots.where(language_id: Language.current.id)
|
30
31
|
end
|
31
32
|
|
@@ -48,7 +49,7 @@ module Alchemy
|
|
48
49
|
# Returns the +menus.yml+ file path
|
49
50
|
#
|
50
51
|
def definitions_file_path
|
51
|
-
Rails.root.join
|
52
|
+
Rails.root.join "config/alchemy/menus.yml"
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
@@ -57,7 +58,7 @@ module Alchemy
|
|
57
58
|
# Either the value is stored in the database, aka. an external url.
|
58
59
|
# Or, if attached, the values comes from a page.
|
59
60
|
def url
|
60
|
-
page
|
61
|
+
page&.url_path || read_attribute(:url).presence
|
61
62
|
end
|
62
63
|
|
63
64
|
def to_partial_path
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
class Page
|
5
|
+
# = The url_path for this page
|
6
|
+
#
|
7
|
+
# Use this to build relative links to this page
|
8
|
+
#
|
9
|
+
# It takes several circumstances into account:
|
10
|
+
#
|
11
|
+
# 1. It returns just a slash for language root pages of the default langauge
|
12
|
+
# 2. It returns a url path with a leading slash for regular pages
|
13
|
+
# 3. It returns a url path with a leading slash and language code prefix for pages not having the default language
|
14
|
+
# 4. It returns a url path with a leading slash and the language code for language root pages of a non-default language
|
15
|
+
#
|
16
|
+
# == Examples
|
17
|
+
#
|
18
|
+
# Using Rails' link_to helper
|
19
|
+
#
|
20
|
+
# link_to page.url
|
21
|
+
#
|
22
|
+
class UrlPath
|
23
|
+
ROOT_PATH = "/"
|
24
|
+
|
25
|
+
def initialize(page)
|
26
|
+
@page = page
|
27
|
+
@language = @page.language
|
28
|
+
@site = @language.site
|
29
|
+
end
|
30
|
+
|
31
|
+
def call
|
32
|
+
return @page.urlname if @page.definition["redirects_to_external"]
|
33
|
+
|
34
|
+
if @page.language_root?
|
35
|
+
language_root_path
|
36
|
+
elsif @site.languages.select(&:public?).length > 1
|
37
|
+
page_path_with_language_prefix
|
38
|
+
else
|
39
|
+
page_path_with_leading_slash
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def language_root_path
|
46
|
+
@language.default? ? ROOT_PATH : language_path
|
47
|
+
end
|
48
|
+
|
49
|
+
def page_path_with_language_prefix
|
50
|
+
@language.default? ? page_path : language_path + page_path
|
51
|
+
end
|
52
|
+
|
53
|
+
def page_path_with_leading_slash
|
54
|
+
@page.language_root? ? ROOT_PATH : page_path
|
55
|
+
end
|
56
|
+
|
57
|
+
def language_path
|
58
|
+
"/#{@page.language_code}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def page_path
|
62
|
+
"/#{@page.urlname}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/app/models/alchemy/page.rb
CHANGED
@@ -85,7 +85,7 @@ module Alchemy
|
|
85
85
|
|
86
86
|
acts_as_nested_set(dependent: :destroy)
|
87
87
|
|
88
|
-
stampable stamper_class_name: Alchemy.
|
88
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
89
89
|
|
90
90
|
belongs_to :language, optional: true
|
91
91
|
|
@@ -161,6 +161,10 @@ module Alchemy
|
|
161
161
|
|
162
162
|
attr_accessor :menu_id
|
163
163
|
|
164
|
+
deprecate visible: "Page slugs will be visible in URLs of child pages all the time. " \
|
165
|
+
"Please use Menus and Tags instead to re-organize your pages if your page tree does not reflect the URL hierarchy.",
|
166
|
+
deprecator: Alchemy::Deprecation
|
167
|
+
|
164
168
|
# Class methods
|
165
169
|
#
|
166
170
|
class << self
|
@@ -347,6 +351,13 @@ module Alchemy
|
|
347
351
|
finder.elements(page: self)
|
348
352
|
end
|
349
353
|
|
354
|
+
# = The url_path for this page
|
355
|
+
#
|
356
|
+
# @see Alchemy::Page::UrlPath#call
|
357
|
+
def url_path
|
358
|
+
Alchemy::Page::UrlPath.new(self).call
|
359
|
+
end
|
360
|
+
|
350
361
|
# The page's view partial is dependent from its page layout
|
351
362
|
#
|
352
363
|
# == Define page layouts
|
@@ -74,7 +74,7 @@ module Alchemy
|
|
74
74
|
case_sensitive: false,
|
75
75
|
message: Alchemy.t("not a valid image")
|
76
76
|
|
77
|
-
stampable stamper_class_name: Alchemy.
|
77
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
78
78
|
|
79
79
|
scope :named, ->(name) {
|
80
80
|
where("#{table_name}.name LIKE ?", "%#{name}%")
|
@@ -9,7 +9,7 @@ module Alchemy
|
|
9
9
|
def pages
|
10
10
|
tree = []
|
11
11
|
path = [{id: object.parent_id, children: tree}]
|
12
|
-
page_list = object.self_and_descendants
|
12
|
+
page_list = object.self_and_descendants.includes({ language: :site }, :locker)
|
13
13
|
base_level = object.level - 1
|
14
14
|
# Load folded pages in advance
|
15
15
|
folded_user_pages = FoldedPage.folded_for_user(opts[:user]).pluck(:page_id)
|
@@ -60,9 +60,10 @@ module Alchemy
|
|
60
60
|
redirects_to_external: page.definition['redirects_to_external'],
|
61
61
|
urlname: page.urlname,
|
62
62
|
external_urlname: page.definition['redirects_to_external'] ? page.external_urlname : nil,
|
63
|
+
url_path: page.url_path,
|
63
64
|
level: level,
|
64
|
-
root:
|
65
|
-
root_or_leaf:
|
65
|
+
root: page.depth == 1,
|
66
|
+
root_or_leaf: page.depth == 1 || !has_children,
|
66
67
|
children: []
|
67
68
|
}
|
68
69
|
|
@@ -30,6 +30,10 @@
|
|
30
30
|
</div>
|
31
31
|
<% end %>
|
32
32
|
|
33
|
-
<
|
33
|
+
<h4 id="sitemap_heading">
|
34
|
+
<span class="page_name"><%= Alchemy::Page.human_attribute_name(:name) %></span>
|
35
|
+
</h4>
|
36
|
+
|
37
|
+
<ul class="list" id="sitemap">
|
34
38
|
<%= render partial: "layoutpage", collection: @layout_root.children %>
|
35
39
|
</ul>
|
@@ -30,7 +30,7 @@
|
|
30
30
|
initialSelection: {
|
31
31
|
id: <%= node.page_id %>,
|
32
32
|
text: "<%= node.page.name %>",
|
33
|
-
|
33
|
+
url_path: "<%= node.page.url_path %>"
|
34
34
|
}
|
35
35
|
<% end %>
|
36
36
|
}).on('change', function(e) {
|
@@ -39,7 +39,7 @@
|
|
39
39
|
$('#node_url').val('').prop('disabled', false)
|
40
40
|
} else {
|
41
41
|
$('#node_name').attr('placeholder', e.added.name)
|
42
|
-
$('#node_url').val(
|
42
|
+
$('#node_url').val(e.added.url_path).prop('disabled', true)
|
43
43
|
}
|
44
44
|
})
|
45
45
|
</script>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
</div>
|
19
19
|
|
20
20
|
<%= f.input :name, autofocus: true %>
|
21
|
-
<%= f.input :urlname, as: 'string', input_html: {value: @page.slug} %>
|
21
|
+
<%= f.input :urlname, as: 'string', input_html: {value: @page.slug}, label: Alchemy::Page.human_attribute_name(:slug) %>
|
22
22
|
<%= f.input :title,
|
23
23
|
input_html: {'data-alchemy-char-counter' => 60} %>
|
24
24
|
|
@@ -1,33 +1,37 @@
|
|
1
|
-
<% if @page.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
<% if Alchemy::Node.roots.where(language: @page.language).any? %>
|
2
|
+
<% unless @page.language_root %>
|
3
|
+
<%= page_status_checkbox(@page, :visible, label: Alchemy.t("show in url of child pages")) %>
|
4
|
+
<% end %>
|
5
|
+
<% if @page.menus.any? %>
|
6
|
+
<label style="vertical-align: middle">
|
7
|
+
<%= Alchemy.t(:attached_to) %>
|
8
|
+
</label>
|
9
|
+
<% @page.menus.each do |menu| %>
|
10
|
+
<span class="page-menu-name label">
|
11
|
+
<%= I18n.t(menu.name, scope: [:alchemy, :menu_names]) %>
|
12
|
+
</span>
|
13
|
+
<% end %>
|
14
|
+
<% else %>
|
15
|
+
<a class="button small" id="attach-page"><%= Alchemy.t("attach to a menu") %></a>
|
16
|
+
<%= f.input :menu_id, collection: Alchemy::Node.roots.map { |n|
|
17
|
+
[I18n.t(n.name, scope: [:alchemy, :menu_names]), n.id]
|
18
|
+
},
|
19
|
+
prompt: Alchemy.t("Please choose a menu"),
|
20
|
+
input_html: { class: "alchemy_selectbox" },
|
21
|
+
wrapper_html: { class: "hidden" },
|
22
|
+
label: false %>
|
23
|
+
<script>
|
24
|
+
(function() {
|
25
|
+
var wrapper = document.querySelector(".input.page_menu_id")
|
26
|
+
document.querySelector("#attach-page").addEventListener("click", function() {
|
27
|
+
var select = wrapper.querySelector("select")
|
28
|
+
this.classList.toggle("active")
|
29
|
+
wrapper.classList.toggle("hidden")
|
30
|
+
$(select).select2("val", "")
|
31
|
+
})
|
32
|
+
})()
|
33
|
+
</script>
|
10
34
|
<% end %>
|
11
|
-
<% elsif Alchemy::Node.roots.any? %>
|
12
|
-
<%= page_status_checkbox(@page, :visible) %>
|
13
|
-
<%= f.input :menu_id, collection: Alchemy::Node.roots.map { |n| [n.name, n.id] },
|
14
|
-
prompt: Alchemy.t('Please choose a menu'),
|
15
|
-
input_html: { class: 'alchemy_selectbox' },
|
16
|
-
wrapper_html: { style: @page.visible? ? 'display: block' : 'display: none' },
|
17
|
-
label: false %>
|
18
|
-
<script>
|
19
|
-
(function() {
|
20
|
-
var $wrapper = $('.input.page_menu_id')
|
21
|
-
$('#page_visible').click(function() {
|
22
|
-
if ($(this).is(':checked')) {
|
23
|
-
$wrapper.show()
|
24
|
-
} else {
|
25
|
-
$wrapper.find('select').val('')
|
26
|
-
$wrapper.hide()
|
27
|
-
}
|
28
|
-
})
|
29
|
-
})()
|
30
|
-
</script>
|
31
35
|
<% else %>
|
32
36
|
<%= page_status_checkbox(@page, :visible) %>
|
33
37
|
<% end %>
|
@@ -159,12 +159,9 @@
|
|
159
159
|
<span class="hint-bubble">{{status_titles.restricted}}</span>
|
160
160
|
</span>
|
161
161
|
</div>
|
162
|
-
{{
|
163
|
-
|
164
|
-
|
165
|
-
{{ external_urlname }}
|
166
|
-
</div>
|
167
|
-
{{/if}}
|
162
|
+
<div class="sitemap_url" title="{{url_path}}">
|
163
|
+
{{ url_path }}
|
164
|
+
</div>
|
168
165
|
<div class="sitemap_sitename">
|
169
166
|
{{#if redirects_to_external}}
|
170
167
|
<span class="sitemap_pagename_link inactive">{{ name }}</span>
|
@@ -1,4 +1,10 @@
|
|
1
1
|
<div id="sitemap-wrapper">
|
2
|
+
<h4 id="sitemap_heading">
|
3
|
+
<span class="page_name"><%= Alchemy::Page.human_attribute_name(:name) %></span>
|
4
|
+
<span class="page_urlname"><%= Alchemy::Page.human_attribute_name(:urlname) %></span>
|
5
|
+
<span class="page_status"><%= Alchemy.t(:page_status) %></span>
|
6
|
+
</h4>
|
7
|
+
|
2
8
|
<p class="loading"></p>
|
3
9
|
</div>
|
4
10
|
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<label><%= Alchemy::Page.human_attribute_name(:urlname) %></label>
|
19
19
|
<p><%= @page.urlname %></p>
|
20
20
|
<% else %>
|
21
|
-
<label><%= Alchemy::
|
21
|
+
<label><%= Alchemy::Page.human_attribute_name(:urlname) %></label>
|
22
22
|
<p><%= "/#{@page.urlname}" %></p>
|
23
23
|
<% end %>
|
24
24
|
</div>
|
data/config/alchemy/config.yml
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
# == This is the global Alchemy configuration file
|
2
2
|
#
|
3
3
|
|
4
|
-
# === Require SSL for login form and all admin modules
|
5
|
-
#
|
6
|
-
# NOTE: You have to create a SSL certificate on your server to make this work
|
7
|
-
#
|
8
|
-
require_ssl: false
|
9
|
-
|
10
4
|
# === Auto Log Out Time
|
11
5
|
#
|
12
6
|
# The amount of time of inactivity in minutes after which the user is kicked out of his current session.
|
@@ -573,7 +573,6 @@ en:
|
|
573
573
|
button_label: Upload image(s)
|
574
574
|
upload_success: "Picture %{name} uploaded successfully"
|
575
575
|
upload_failure: "Error while uploading %{name}: %{error}"
|
576
|
-
url_name: "URL-Name"
|
577
576
|
visible: "visible"
|
578
577
|
want_to_create_new_language: "Do you want to create a new empty language tree?"
|
579
578
|
want_to_make_copy_of_existing_language: "Do you want to copy an existing language tree?"
|
@@ -670,9 +669,9 @@ en:
|
|
670
669
|
page_layout:
|
671
670
|
blank: "^Please choose a page layout."
|
672
671
|
urlname:
|
673
|
-
too_short: "^
|
674
|
-
taken: "^URL-
|
675
|
-
exclusion: "^URL-
|
672
|
+
too_short: "^URL-Path is too short (minimum of 3 characters)."
|
673
|
+
taken: "^URL-Path already taken."
|
674
|
+
exclusion: "^URL-Path reserved."
|
676
675
|
alchemy/picture:
|
677
676
|
attributes:
|
678
677
|
image_file:
|
@@ -780,7 +779,7 @@ en:
|
|
780
779
|
locale: Localization
|
781
780
|
code: ISO Code
|
782
781
|
alchemy/legacy_page_url:
|
783
|
-
urlname: "URL
|
782
|
+
urlname: "URL-Path"
|
784
783
|
alchemy/node:
|
785
784
|
name: "Name"
|
786
785
|
title: "Title"
|
@@ -805,7 +804,8 @@ en:
|
|
805
804
|
tag_list: Tags
|
806
805
|
title: "Title"
|
807
806
|
updated_at: "Updated at"
|
808
|
-
urlname: "
|
807
|
+
urlname: "URL-Path"
|
808
|
+
slug: "Slug"
|
809
809
|
visible: "visible in navigation"
|
810
810
|
alchemy/picture:
|
811
811
|
image_file_name: "Filename"
|
data/lib/alchemy/config.rb
CHANGED
@@ -8,8 +8,10 @@ module Alchemy
|
|
8
8
|
# @param name [String]
|
9
9
|
#
|
10
10
|
def get(name)
|
11
|
+
check_deprecation(name)
|
11
12
|
show[name.to_s]
|
12
13
|
end
|
14
|
+
|
13
15
|
alias_method :parameter, :get
|
14
16
|
|
15
17
|
# Returns a merged configuration of the following files
|
@@ -25,11 +27,22 @@ module Alchemy
|
|
25
27
|
@config ||= merge_configs!(alchemy_config, main_app_config, env_specific_config)
|
26
28
|
end
|
27
29
|
|
30
|
+
# A list of deprecated configurations
|
31
|
+
# a value of nil means there is no new default
|
32
|
+
# any not nil value is the new default
|
33
|
+
def deprecated_configs
|
34
|
+
{
|
35
|
+
url_nesting: true,
|
36
|
+
require_ssl: nil,
|
37
|
+
auto_logout_time: nil,
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
28
41
|
private
|
29
42
|
|
30
43
|
# Alchemy default configuration
|
31
44
|
def alchemy_config
|
32
|
-
read_file(File.join(File.dirname(__FILE__),
|
45
|
+
read_file(File.join(File.dirname(__FILE__), "..", "..", "config/alchemy/config.yml"))
|
33
46
|
end
|
34
47
|
|
35
48
|
# Application specific configuration
|
@@ -54,11 +67,26 @@ module Alchemy
|
|
54
67
|
# Merges all given configs together
|
55
68
|
#
|
56
69
|
def merge_configs!(*config_files)
|
57
|
-
raise LoadError,
|
70
|
+
raise LoadError, "No Alchemy config file found!" if config_files.map(&:blank?).all?
|
71
|
+
|
58
72
|
config = {}
|
59
73
|
config_files.each { |h| config.merge!(h.stringify_keys!) }
|
60
74
|
config
|
61
75
|
end
|
76
|
+
|
77
|
+
def check_deprecation(name)
|
78
|
+
if deprecated_configs.key?(name.to_sym)
|
79
|
+
config = deprecated_configs[name.to_sym]
|
80
|
+
if config.nil?
|
81
|
+
Alchemy::Deprecation.warn("#{name} configuration is deprecated and will be removed from Alchemy 5.0")
|
82
|
+
else
|
83
|
+
value = show[name.to_s]
|
84
|
+
if value != config
|
85
|
+
Alchemy::Deprecation.warn("Setting #{name} configuration to #{value} is deprecated and will be always #{config} in Alchemy 5.0")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
62
90
|
end
|
63
91
|
end
|
64
92
|
end
|
data/lib/alchemy/essence.rb
CHANGED
@@ -48,7 +48,7 @@ module Alchemy #:nodoc:
|
|
48
48
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
49
49
|
attr_writer :validation_errors
|
50
50
|
include Alchemy::Essence::InstanceMethods
|
51
|
-
stampable stamper_class_name: Alchemy.
|
51
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
52
52
|
validate :validate_ingredient, on: :update, if: -> { validations.any? }
|
53
53
|
|
54
54
|
has_one :content, as: :essence, class_name: "Alchemy::Content", inverse_of: :essence
|
data/lib/alchemy/resource.rb
CHANGED
@@ -131,23 +131,21 @@ module Alchemy
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def namespaced_resource_name
|
134
|
-
@_namespaced_resource_name ||=
|
135
|
-
namespaced_resources_name.to_s.singularize
|
136
|
-
end.to_sym # Rails >= 6.0.3.7 needs symbols in polymorphic routes
|
134
|
+
@_namespaced_resource_name ||= namespaced_resources_name.singularize
|
137
135
|
end
|
138
136
|
|
139
137
|
def namespaced_resources_name
|
140
138
|
@_namespaced_resources_name ||= begin
|
141
139
|
resource_name_array = resource_array.dup
|
142
140
|
resource_name_array.delete(engine_name) if in_engine?
|
143
|
-
resource_name_array.join(
|
144
|
-
end
|
141
|
+
resource_name_array.join('_')
|
142
|
+
end
|
145
143
|
end
|
146
144
|
|
147
145
|
def namespace_for_scope
|
148
146
|
namespace_array = namespace_diff
|
149
147
|
namespace_array.delete(engine_name) if in_engine?
|
150
|
-
namespace_array
|
148
|
+
namespace_array
|
151
149
|
end
|
152
150
|
|
153
151
|
# Returns an array of underscored association names
|
@@ -26,7 +26,9 @@ module Alchemy
|
|
26
26
|
|
27
27
|
# Redirects current request to https.
|
28
28
|
def enforce_ssl
|
29
|
-
redirect_to url_for(request.params.merge(protocol:
|
29
|
+
redirect_to url_for(request.params.merge(protocol: "https"))
|
30
30
|
end
|
31
|
+
|
32
|
+
deprecate :enforce_ssl, deprecator: Alchemy::Deprecation
|
31
33
|
end
|
32
34
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
class Upgrader::FourPointSix < Upgrader
|
5
|
+
class << self
|
6
|
+
def todos
|
7
|
+
notice = <<-NOTE.strip_heredoc
|
8
|
+
|
9
|
+
ℹ️ Page visible attribute is deprecated
|
10
|
+
----------------------------------------
|
11
|
+
|
12
|
+
Page slugs will be visible in URLs of child pages all the time in the future.
|
13
|
+
Please use Menus and Tags instead to re-organize your pages if your page tree does not reflect the URL hierarchy.
|
14
|
+
|
15
|
+
A rake task to help with the migration is available.
|
16
|
+
|
17
|
+
bin/rake alchemy:upgrade:4.6:restructure_page_tree
|
18
|
+
|
19
|
+
NOTE
|
20
|
+
todo notice, "Alchemy v4.6 TODO"
|
21
|
+
end
|
22
|
+
|
23
|
+
def restructure_page_tree
|
24
|
+
desc "Move child pages of invisible pages to visible parent."
|
25
|
+
Alchemy::Deprecation.silence do
|
26
|
+
# All leaves can safely be marked visible
|
27
|
+
Alchemy::Page.leaves.update_all(visible: true)
|
28
|
+
Alchemy::Page.language_roots.each do |root_page|
|
29
|
+
# Root pages are always visible
|
30
|
+
root_page.update!(visible: true)
|
31
|
+
remove_invisible_children(root_page)
|
32
|
+
end
|
33
|
+
Alchemy::Page.update_all(visible: true)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def remove_invisible_children(page)
|
40
|
+
page.children.each { |child| remove_invisible_children(child) }
|
41
|
+
if !page.visible
|
42
|
+
page.children.reload.reverse.each do |child|
|
43
|
+
puts "Moving #{child.urlname} to right of #{page.urlname}"
|
44
|
+
child.move_to_right_of(page)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require_relative 'tasks/picture_gallery_upgrader'
|
2
2
|
require_relative 'tasks/picture_gallery_migration'
|
3
|
-
require_relative 'tasks/fixed_element_name_finder'
|
4
3
|
require_relative 'tasks/cells_upgrader'
|
5
4
|
require_relative 'tasks/cells_migration'
|
6
5
|
require_relative 'tasks/element_partial_name_variable_updater'
|
@@ -8,7 +8,6 @@ module Alchemy::Upgrader::Tasks
|
|
8
8
|
def migrate_cells
|
9
9
|
if ActiveRecord::Base.connection.data_source_exists?('alchemy_cells')
|
10
10
|
cells = Cell.all
|
11
|
-
@fixed_element_name_finder = FixedElementNameFinder.new
|
12
11
|
|
13
12
|
if cells.any?
|
14
13
|
cells.each do |cell|
|
@@ -27,7 +26,7 @@ module Alchemy::Upgrader::Tasks
|
|
27
26
|
def migrate_cell!(cell)
|
28
27
|
# bust element definitions insta cache
|
29
28
|
Alchemy::Element.instance_variable_set('@definitions', nil)
|
30
|
-
fixed_element = Alchemy::Element.find_or_initialize_by(fixed: true, name:
|
29
|
+
fixed_element = Alchemy::Element.find_or_initialize_by(fixed: true, name: cell.name, page: cell.page)
|
31
30
|
elements = Alchemy::Element.where(cell_id: cell.id).order(position: :asc)
|
32
31
|
|
33
32
|
if fixed_element.new_record?
|
@@ -72,13 +72,12 @@ module Alchemy::Upgrader::Tasks
|
|
72
72
|
|
73
73
|
def convert_cell_config
|
74
74
|
puts '-- Converting cells into unique fixed nestable elements.'
|
75
|
-
fixed_element_name_finder = FixedElementNameFinder.new
|
76
75
|
|
77
76
|
YAML.load_file(cells_config_file).each do |cell|
|
78
77
|
append_to_file Rails.root.join('config', 'alchemy', 'elements.yml') do
|
79
78
|
<<-CELL.strip_heredoc
|
80
79
|
|
81
|
-
- name: #{
|
80
|
+
- name: #{cell['name']}
|
82
81
|
fixed: true
|
83
82
|
unique: true
|
84
83
|
nestable_elements: [#{cell['elements'].join(', ')}]
|
@@ -129,25 +128,8 @@ module Alchemy::Upgrader::Tasks
|
|
129
128
|
puts "-- Update render_cell calls"
|
130
129
|
Dir.glob("#{alchemy_views_folder}/**/*").each do |view|
|
131
130
|
next if File.directory?(view)
|
132
|
-
|
133
|
-
|
134
|
-
# <%= render_cell("test", options: true) %>
|
135
|
-
content = File.binread(view)
|
136
|
-
content.gsub!(/render_cell([\s(]+)(['":])(\w+)([^\w])(.*?)/) do
|
137
|
-
element_name = CellNameMigrator.call($3)
|
138
|
-
"render_elements#{$1}only: #{$2}#{element_name}#{$4}, fixed: true#{$5}"
|
139
|
-
end
|
140
|
-
|
141
|
-
# <%= render_elements from_cell: 'page_intro' %>
|
142
|
-
# <%= render_elements testing: 'blubb', from_cell: :page_intro %>
|
143
|
-
# <%= render_elements from_cell: "page_intro", testing: 'blubb' %>
|
144
|
-
# <%= render_elements(from_cell: "page_intro", testing: 'blubb') %>
|
145
|
-
# <%= render_elements(testing: 'blubb', from_cell: "page_intro") %>
|
146
|
-
content.gsub!(/render_elements(.*?)from_cell[:\s=>]+([:'"])(\w+)(['"]?)(.*)/) do
|
147
|
-
element_name = CellNameMigrator.call($3)
|
148
|
-
"render_elements#{$1}only: #{$2}#{element_name}#{$4}, fixed: true#{$5}"
|
149
|
-
end
|
150
|
-
File.open(view, "wb") { |file| file.write(content) }
|
131
|
+
gsub_file(view, /render_cell[\(\s]?([:'"]?[a-z_]+['"]?)\)?/, 'render_elements(only: \1, fixed: true)')
|
132
|
+
gsub_file(view, /render_elements[\(\s](.*):?from_cell:?\s?(=>)?\s?(['"][a-z_]+['"])\)?/, 'render_elements(\1only: \3, fixed: true)')
|
151
133
|
end
|
152
134
|
end
|
153
135
|
|
@@ -11,14 +11,10 @@ module Alchemy::Upgrader::Tasks
|
|
11
11
|
puts "-- Update element views local variable to partial name"
|
12
12
|
Dir.glob("#{elements_view_folder}/*_view.*").each do |view|
|
13
13
|
variable_name = File.basename(view).gsub(/^_([\w-]*)\..*$/, '\1')
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
].each do |method_name|
|
19
|
-
gsub_file(view, /#{method_name}([\s(]+)element([^\w])/, "#{method_name}\\1#{variable_name}\\2")
|
20
|
-
end
|
21
|
-
gsub_file(view, /([\s(%={]+)element([^\w:"'])/, "\\1#{variable_name}\\2")
|
14
|
+
gsub_file(view, /cache\(?element([,\s\w:\-,=>'"\?\/]*)\)?/, "cache(#{variable_name}\\1)")
|
15
|
+
gsub_file(view, /render_essence_view_by_name\(?element([,\s\w:\-,=>'"\?\/]*)\)?/, "render_essence_view_by_name(#{variable_name}\\1)")
|
16
|
+
gsub_file(view, /element_view_for\(?element([,\s\w:\-,=>'"\?\/]*)\)?/, "element_view_for(#{variable_name}\\1)")
|
17
|
+
gsub_file(view, /element\.([\w\?]+)/, "#{variable_name}.\\1")
|
22
18
|
end
|
23
19
|
end
|
24
20
|
end
|