alchemy_cms 4.3.2 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +92 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +59 -2
- data/Gemfile +6 -5
- data/README.md +7 -6
- data/alchemy_cms.gemspec +4 -2
- data/app/assets/config/alchemy_manifest.js +15 -0
- data/app/assets/javascripts/alchemy/admin.js +1 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +1 -13
- data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +84 -87
- data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +0 -4
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/page_select.js +41 -0
- data/app/assets/javascripts/alchemy/templates/index.js +1 -0
- data/app/assets/javascripts/alchemy/templates/page.hbs +9 -0
- data/app/assets/stylesheets/alchemy/_mixins.scss +11 -1
- data/app/assets/stylesheets/alchemy/admin.scss +3 -0
- data/app/assets/stylesheets/alchemy/elements.scss +1 -0
- data/app/assets/stylesheets/alchemy/forms.scss +6 -5
- data/app/assets/stylesheets/alchemy/labels.scss +6 -0
- data/app/assets/stylesheets/alchemy/nodes.scss +154 -0
- data/app/assets/stylesheets/alchemy/page-select.scss +30 -0
- data/app/assets/stylesheets/alchemy/selects.scss +39 -22
- data/app/assets/stylesheets/alchemy/sitemap.scss +0 -33
- data/app/assets/stylesheets/alchemy/tags.scss +0 -3
- data/app/controllers/alchemy/admin/base_controller.rb +1 -0
- data/app/controllers/alchemy/admin/elements_controller.rb +24 -11
- data/app/controllers/alchemy/admin/languages_controller.rb +5 -0
- data/app/controllers/alchemy/admin/nodes_controller.rb +43 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +1 -21
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
- data/app/controllers/alchemy/admin/tags_controller.rb +1 -2
- data/app/controllers/alchemy/api/contents_controller.rb +17 -2
- data/app/controllers/alchemy/api/elements_controller.rb +26 -1
- data/app/controllers/alchemy/api/pages_controller.rb +78 -7
- data/app/controllers/alchemy/messages_controller.rb +23 -8
- data/app/helpers/alchemy/admin/contents_helper.rb +1 -1
- data/app/helpers/alchemy/admin/elements_helper.rb +6 -0
- data/app/helpers/alchemy/admin/essences_helper.rb +23 -4
- data/app/helpers/alchemy/elements_block_helper.rb +11 -3
- data/app/helpers/alchemy/elements_helper.rb +3 -3
- data/app/helpers/alchemy/essences_helper.rb +36 -9
- data/app/helpers/alchemy/pages_helper.rb +29 -0
- data/app/models/alchemy/content.rb +1 -1
- data/app/models/alchemy/element.rb +20 -8
- data/app/models/alchemy/element/element_contents.rb +6 -4
- data/app/models/alchemy/element/presenters.rb +2 -2
- data/app/models/alchemy/essence_page.rb +29 -0
- data/app/models/alchemy/essence_picture.rb +8 -3
- data/app/models/alchemy/language.rb +10 -2
- data/app/models/alchemy/node.rb +48 -0
- data/app/models/alchemy/page.rb +74 -3
- data/app/models/alchemy/page/page_elements.rb +12 -4
- data/app/models/alchemy/page/page_natures.rb +6 -0
- data/app/models/alchemy/page/page_scopes.rb +1 -1
- data/app/models/alchemy/picture.rb +5 -1
- data/app/models/concerns/alchemy/content_touching.rb +1 -1
- data/app/serializers/alchemy/element_serializer.rb +7 -1
- data/app/serializers/alchemy/page_serializer.rb +0 -4
- data/app/views/alchemy/_menubar.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element.html.erb +18 -2
- data/app/views/alchemy/admin/leave.html.erb +1 -1
- data/app/views/alchemy/admin/nodes/_form.html.erb +39 -0
- data/app/views/alchemy/admin/nodes/_node.html.erb +87 -0
- data/app/views/alchemy/admin/nodes/edit.html.erb +1 -0
- data/app/views/alchemy/admin/nodes/index.html.erb +58 -0
- data/app/views/alchemy/admin/nodes/new.html.erb +1 -0
- data/app/views/alchemy/admin/pages/_anchor_link.html.erb +22 -0
- data/app/views/alchemy/admin/pages/_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +7 -11
- data/app/views/alchemy/admin/pages/_menu_fields.html.erb +33 -0
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +0 -7
- data/app/views/alchemy/admin/pages/link.html.erb +4 -0
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +7 -3
- data/app/views/alchemy/admin/partials/_routes.html.erb +3 -3
- data/app/views/alchemy/essences/_essence_boolean_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_date_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_file_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_html_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_link_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_page_editor.html.erb +23 -0
- data/app/views/alchemy/essences/_essence_page_view.html.erb +5 -0
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +2 -0
- data/app/views/alchemy/essences/_essence_picture_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_richtext_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_select_editor.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_select_view.html.erb +1 -0
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +3 -0
- data/app/views/alchemy/essences/_essence_text_view.html.erb +1 -0
- data/config/alchemy/modules.yml +13 -4
- data/config/initializers/assets.rb +1 -13
- data/config/locales/alchemy.en.yml +27 -9
- data/config/routes.rb +11 -3
- data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +8 -0
- data/db/migrate/20191029212236_create_alchemy_nodes.rb +24 -0
- data/lib/alchemy/admin/locale.rb +1 -1
- data/lib/alchemy/auth_accessors.rb +8 -2
- data/lib/alchemy/cache_digests/template_tracker.rb +8 -5
- data/lib/alchemy/elements_finder.rb +17 -14
- data/lib/alchemy/engine.rb +4 -0
- data/lib/alchemy/essence.rb +40 -2
- data/lib/alchemy/permissions.rb +2 -0
- data/lib/alchemy/tasks/tidy.rb +1 -1
- data/lib/alchemy/test_support/essence_shared_examples.rb +25 -8
- data/lib/alchemy/test_support/factories/essence_page_factory.rb +10 -0
- data/lib/alchemy/test_support/factories/essence_picture_factory.rb +5 -0
- data/lib/alchemy/test_support/factories/node_factory.rb +21 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +0 -1
- data/lib/rails/generators/alchemy/elements/templates/view.html.erb +3 -3
- data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -3
- data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -3
- data/lib/rails/generators/alchemy/install/files/{_article_view.html.erb → _article.html.erb} +2 -2
- data/lib/rails/generators/alchemy/install/files/application.html.erb +13 -10
- data/lib/rails/generators/alchemy/install/install_generator.rb +2 -11
- data/lib/rails/generators/alchemy/menus/menus_generator.rb +24 -0
- data/lib/rails/generators/alchemy/menus/templates/node.html.erb +19 -0
- data/lib/rails/generators/alchemy/menus/templates/node.html.haml +16 -0
- data/lib/rails/generators/alchemy/menus/templates/node.html.slim +16 -0
- data/lib/rails/generators/alchemy/menus/templates/wrapper.html.erb +8 -0
- data/lib/rails/generators/alchemy/menus/templates/wrapper.html.haml +6 -0
- data/lib/rails/generators/alchemy/menus/templates/wrapper.html.slim +6 -0
- data/lib/rails/generators/alchemy/views/views_generator.rb +1 -1
- data/lib/tasks/alchemy/convert.rake +60 -0
- metadata +79 -20
- data/.rspec +0 -1
- data/.travis.yml +0 -28
- data/app/models/alchemy/page/page_users.rb +0 -60
- data/app/views/alchemy/admin/elements/list.html.erb +0 -16
- data/app/views/alchemy/admin/pages/_page_for_links.html.erb +0 -53
- data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +0 -9
- data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +0 -8
- data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +0 -8
- data/lib/rails/generators/alchemy/install/files/_article_editor.html.erb +0 -5
- data/lib/rails/generators/alchemy/install/files/alchemy.de.yml +0 -31
- data/lib/rails/generators/alchemy/install/files/alchemy.es.yml +0 -31
data/lib/alchemy/permissions.rb
CHANGED
@@ -95,6 +95,7 @@ module Alchemy
|
|
95
95
|
:alchemy_admin_attachments,
|
96
96
|
:alchemy_admin_dashboard,
|
97
97
|
:alchemy_admin_layoutpages,
|
98
|
+
:alchemy_admin_nodes,
|
98
99
|
:alchemy_admin_pages,
|
99
100
|
:alchemy_admin_pictures,
|
100
101
|
:alchemy_admin_tags,
|
@@ -116,6 +117,7 @@ module Alchemy
|
|
116
117
|
can :manage, Alchemy::EssenceFile
|
117
118
|
can :manage, Alchemy::EssencePicture
|
118
119
|
can :manage, Alchemy::LegacyPageUrl
|
120
|
+
can :manage, Alchemy::Node
|
119
121
|
can :read, Alchemy::Picture
|
120
122
|
can [:read, :autocomplete], Alchemy::Tag
|
121
123
|
can(:edit_content, Alchemy::Page) { |p| p.editable_by?(@user) }
|
data/lib/alchemy/tasks/tidy.rb
CHANGED
@@ -45,7 +45,7 @@ module Alchemy
|
|
45
45
|
|
46
46
|
def remove_orphaned_elements
|
47
47
|
puts "\n## Removing orphaned elements"
|
48
|
-
elements = Alchemy::Element.unscoped.
|
48
|
+
elements = Alchemy::Element.unscoped.not_nested
|
49
49
|
if elements.any?
|
50
50
|
orphaned_elements = elements.select do |element|
|
51
51
|
element.page.nil? && element.page_id.present?
|
@@ -1,16 +1,33 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'shoulda-matchers'
|
4
|
+
require 'alchemy/test_support/factories/page_factory'
|
5
|
+
require 'alchemy/test_support/factories/element_factory'
|
6
|
+
require 'alchemy/test_support/factories/content_factory'
|
7
|
+
|
8
|
+
RSpec.shared_examples_for "an essence" do
|
4
9
|
let(:element) { Alchemy::Element.new }
|
5
10
|
let(:content) { Alchemy::Content.new(name: 'foo') }
|
6
11
|
let(:content_definition) { {'name' => 'foo'} }
|
7
12
|
|
13
|
+
describe 'eager loading' do
|
14
|
+
before do
|
15
|
+
2.times { described_class.create! }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'does not throw error if eager loaded' do
|
19
|
+
expect {
|
20
|
+
described_class.all.includes(:ingredient_association).to_a
|
21
|
+
}.to_not raise_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
8
25
|
it "touches the content after update" do
|
9
|
-
element = create(:alchemy_element)
|
10
|
-
content = create(:alchemy_content, element: element, essence: essence, essence_type: essence.class.name)
|
26
|
+
element = FactoryBot.create(:alchemy_element)
|
27
|
+
content = FactoryBot.create(:alchemy_content, element: element, essence: essence, essence_type: essence.class.name)
|
11
28
|
|
12
29
|
content.update_column(:updated_at, 3.days.ago)
|
13
|
-
content.essence.
|
30
|
+
content.essence.update(essence.ingredient_column.to_sym => ingredient_value)
|
14
31
|
|
15
32
|
content.reload
|
16
33
|
expect(content.updated_at).to be_within(3.seconds).of(Time.current)
|
@@ -153,7 +170,7 @@ shared_examples_for "an essence" do
|
|
153
170
|
|
154
171
|
describe 'uniqueness' do
|
155
172
|
before do
|
156
|
-
allow(essence).to receive(:element).and_return(build_stubbed(:alchemy_element))
|
173
|
+
allow(essence).to receive(:element).and_return(FactoryBot.build_stubbed(:alchemy_element))
|
157
174
|
essence.update(essence.ingredient_column.to_sym => ingredient_value)
|
158
175
|
end
|
159
176
|
|
@@ -256,8 +273,8 @@ shared_examples_for "an essence" do
|
|
256
273
|
end
|
257
274
|
|
258
275
|
describe 'essence relations' do
|
259
|
-
let(:page) { create(:alchemy_page, :restricted) }
|
260
|
-
let(:element) { create(:alchemy_element) }
|
276
|
+
let(:page) { FactoryBot.create(:alchemy_page, :restricted) }
|
277
|
+
let(:element) { FactoryBot.create(:alchemy_element) }
|
261
278
|
|
262
279
|
it "registers itself on page as essence relation" do
|
263
280
|
expect(page.respond_to?(essence.class.model_name.route_key)).to be(true)
|
@@ -1,10 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'factory_bot'
|
4
|
+
require 'alchemy/test_support/factories/content_factory'
|
4
5
|
require 'alchemy/test_support/factories/picture_factory'
|
5
6
|
|
6
7
|
FactoryBot.define do
|
7
8
|
factory :alchemy_essence_picture, class: 'Alchemy::EssencePicture' do
|
8
9
|
picture factory: :alchemy_picture
|
10
|
+
|
11
|
+
trait :with_content do
|
12
|
+
association :content, factory: :alchemy_content
|
13
|
+
end
|
9
14
|
end
|
10
15
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'factory_bot'
|
4
|
+
require 'alchemy/test_support/factories/language_factory'
|
5
|
+
require 'alchemy/test_support/factories/page_factory'
|
6
|
+
|
7
|
+
FactoryBot.define do
|
8
|
+
factory :alchemy_node, class: 'Alchemy::Node' do
|
9
|
+
language { Alchemy::Language.default }
|
10
|
+
name { 'A Node' }
|
11
|
+
|
12
|
+
trait :with_page do
|
13
|
+
association :page, factory: :alchemy_page
|
14
|
+
name { nil }
|
15
|
+
end
|
16
|
+
|
17
|
+
trait :with_url do
|
18
|
+
url { 'https://example.com' }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/alchemy/version.rb
CHANGED
@@ -19,7 +19,6 @@ module Alchemy
|
|
19
19
|
raise "Element name '#{element['name']}' has wrong format. Only lowercase and non whitespace characters allowed."
|
20
20
|
end
|
21
21
|
|
22
|
-
conditional_template "editor.html.#{template_engine}", "#{elements_dir}/_#{@element_name}_editor.html.#{template_engine}"
|
23
22
|
conditional_template "view.html.#{template_engine}", "#{elements_dir}/_#{@element_name}_view.html.#{template_engine}"
|
24
23
|
end
|
25
24
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
<%%- cache(<%= @element_name %>
|
2
|
-
<%%= element_view_for(<%= @element_name %>
|
1
|
+
<%%- cache(<%= @element_name %>) do -%>
|
2
|
+
<%%= element_view_for(<%= @element_name %>) do |el| -%>
|
3
3
|
<%- @contents.each do |content| -%>
|
4
4
|
<%- if @contents.length > 1 -%>
|
5
5
|
<div class="<%= content["name"] %>">
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<%- end -%>
|
11
11
|
<%- end -%>
|
12
12
|
<%- if @element['nestable_elements'].present? -%>
|
13
|
-
<%%= render <%= @element_name
|
13
|
+
<%%= render <%= @element_name %>.nested_elements.available %>
|
14
14
|
<%- end -%>
|
15
15
|
<%%- end -%>
|
16
16
|
<%%- end -%>
|
@@ -1,5 +1,5 @@
|
|
1
|
-
- cache(<%= @element_name -%>
|
2
|
-
= element_view_for(<%= @element_name -%>
|
1
|
+
- cache(<%= @element_name -%>) do
|
2
|
+
= element_view_for(<%= @element_name -%>) do |el|
|
3
3
|
<%- @contents.each do |content| -%>
|
4
4
|
<%- if @contents.length > 1 -%>
|
5
5
|
.<%= content["name"] %>
|
@@ -9,5 +9,5 @@
|
|
9
9
|
<%- end -%>
|
10
10
|
<%- end -%>
|
11
11
|
<%- if @element['nestable_elements'].present? -%>
|
12
|
-
= render <%= @element_name
|
12
|
+
= render <%= @element_name -%>.nested_elements.available
|
13
13
|
<%- end -%>
|
@@ -1,5 +1,5 @@
|
|
1
|
-
- cache(<%= @element_name -%>
|
2
|
-
= element_view_for(<%= @element_name -%>
|
1
|
+
- cache(<%= @element_name -%>) do
|
2
|
+
= element_view_for(<%= @element_name -%>) do |el|
|
3
3
|
<%- @contents.each do |content| -%>
|
4
4
|
<%- if @contents.length > 1 -%>
|
5
5
|
.<%= content["name"] %>
|
@@ -9,5 +9,5 @@
|
|
9
9
|
<%- end -%>
|
10
10
|
<%- end -%>
|
11
11
|
<%- if @element['nestable_elements'].present? -%>
|
12
|
-
= render <%= @element_name
|
12
|
+
= render <%= @element_name -%>.nested_elements.available
|
13
13
|
<%- end -%>
|
data/lib/rails/generators/alchemy/install/files/{_article_view.html.erb → _article.html.erb}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
|
-
<%- cache(
|
2
|
-
<%= element_view_for(
|
1
|
+
<%- cache(article) do -%>
|
2
|
+
<%= element_view_for(article, tag: 'article') do |el| -%>
|
3
3
|
<h2><%= el.render :headline %></h2>
|
4
4
|
<%= el.render :picture, size: '1200x600' %>
|
5
5
|
<%= el.render :text %>
|
@@ -1,13 +1,16 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html lang="<%= @page.language_code %>">
|
3
|
-
<head>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
<head>
|
4
|
+
<%= render "alchemy/pages/meta_data" %>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
|
8
|
+
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
9
|
+
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<%= yield %>
|
14
|
+
<%= render "alchemy/edit_mode" %>
|
15
|
+
</body>
|
13
16
|
</html>
|
@@ -41,18 +41,9 @@ module Alchemy
|
|
41
41
|
create_file "app/assets/stylesheets/application.css", "/*\n#{stylesheet_require} */\n"
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
|
-
"_article_editor.html.erb",
|
46
|
-
"_article_view.html.erb"
|
47
|
-
].each do |file|
|
48
|
-
copy_file file, "app/views/alchemy/elements/#{file}"
|
49
|
-
end
|
50
|
-
|
44
|
+
copy_file "_article.html.erb", "app/views/alchemy/elements/_article.html.erb"
|
51
45
|
copy_file "_standard.html.erb", "app/views/alchemy/page_layouts/_standard.html.erb"
|
52
|
-
|
53
|
-
%w(de en es).each do |locale|
|
54
|
-
copy_file "alchemy.#{locale}.yml", "config/locales/alchemy.#{locale}.yml"
|
55
|
-
end
|
46
|
+
copy_file "alchemy.en.yml", "config/locales/alchemy.en.yml"
|
56
47
|
end
|
57
48
|
|
58
49
|
def copy_dragonfly_config
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../base'
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module Generators
|
7
|
+
class MenusGenerator < Base
|
8
|
+
desc "This generator generates Alchemy menu partials."
|
9
|
+
source_root File.expand_path('templates', __dir__)
|
10
|
+
|
11
|
+
def create_partials
|
12
|
+
menus = Alchemy::Node.roots
|
13
|
+
return unless menus
|
14
|
+
|
15
|
+
menus.each do |menu|
|
16
|
+
conditional_template "wrapper.html.#{template_engine}",
|
17
|
+
"app/views/#{menu.view_folder_name}/_wrapper.html.#{template_engine}"
|
18
|
+
conditional_template "node.html.#{template_engine}",
|
19
|
+
"app/views/#{menu.view_folder_name}/_node.html.#{template_engine}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%% cache node do %>
|
2
|
+
<%%= content_tag :li, class: ['nav-item', node.children.any? ? 'dropdown' : nil].compact do %>
|
3
|
+
<%%= link_to_if node.url,
|
4
|
+
node.name,
|
5
|
+
@preview_mode ? 'javascript: void(0)' : node.url,
|
6
|
+
class: ['nav-link', current_page?(node.url) ? 'active' : nil].compact,
|
7
|
+
title: node.title,
|
8
|
+
target: node.external? ? '_blank' : nil,
|
9
|
+
rel: node.nofollow? ? 'nofollow' : nil %>
|
10
|
+
<%% if node.children.any? %>
|
11
|
+
<ul class="dropdown-menu">
|
12
|
+
<%%= render partial: options[:node_partial_name],
|
13
|
+
collection: node.children.includes(:page, :children),
|
14
|
+
locals: { options: options },
|
15
|
+
as: 'node' %>
|
16
|
+
</ul>
|
17
|
+
<%% end %>
|
18
|
+
<%% end %>
|
19
|
+
<%% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
- cache node do
|
2
|
+
= content_tag :li,
|
3
|
+
class: ['nav-item', node.children.any? ? 'dropdown' : nil].compact do
|
4
|
+
= link_to_if node.url,
|
5
|
+
node.name,
|
6
|
+
@preview_mode ? 'javascript: void(0)' : node.url,
|
7
|
+
class: ['nav-link', current_page?(node.url) ? 'active' : nil].compact,
|
8
|
+
title: node.title,
|
9
|
+
target: node.external? ? '_blank' : nil,
|
10
|
+
rel: node.nofollow? ? 'nofollow' : nil
|
11
|
+
- if node.children.any?
|
12
|
+
%ul.dropdown-menu
|
13
|
+
= render partial: options[:node_partial_name],
|
14
|
+
collection: node.children.includes(:page, :children),
|
15
|
+
locals: { options: options },
|
16
|
+
as: 'node'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
- cache node do
|
2
|
+
= content_tag :li,
|
3
|
+
class: ['nav-item', node.children.any? ? 'dropdown' : nil].compact do
|
4
|
+
= link_to_if node.url,
|
5
|
+
node.name,
|
6
|
+
@preview_mode ? 'javascript: void(0)' : node.url,
|
7
|
+
class: ['nav-link', current_page?(node.url) ? 'active' : nil].compact,
|
8
|
+
title: node.title,
|
9
|
+
target: node.external? ? '_blank' : nil,
|
10
|
+
rel: node.nofollow? ? 'nofollow' : nil
|
11
|
+
- if node.children.any?
|
12
|
+
ul.dropdown-menu
|
13
|
+
= render partial: options[:node_partial_name],
|
14
|
+
collection: node.children.includes(:page, :children),
|
15
|
+
locals: { options: options },
|
16
|
+
as: 'node'
|
@@ -3,7 +3,7 @@ require 'rails'
|
|
3
3
|
module Alchemy
|
4
4
|
module Generators
|
5
5
|
class ViewsGenerator < ::Rails::Generators::Base
|
6
|
-
ALCHEMY_VIEWS = %w(breadcrumb language_links messages_mailer
|
6
|
+
ALCHEMY_VIEWS = %w(breadcrumb language_links messages_mailer)
|
7
7
|
|
8
8
|
desc "Generates Alchemy views for #{ALCHEMY_VIEWS.to_sentence}."
|
9
9
|
|
@@ -31,5 +31,65 @@ namespace :alchemy do
|
|
31
31
|
puts "Done."
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
namespace :page_trees do
|
36
|
+
desc "Converts the page tree into a menu."
|
37
|
+
task to_menus: [:environment] do
|
38
|
+
if Alchemy::Node.roots.exists?
|
39
|
+
abort "\n⨯ There are already menus present in your database. Aborting!"
|
40
|
+
end
|
41
|
+
|
42
|
+
def name_for_node(page)
|
43
|
+
if page.visible? && page.public? && !page.redirects_to_external?
|
44
|
+
nil
|
45
|
+
else
|
46
|
+
page.name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def page_for_node(page)
|
51
|
+
if page.visible? && page.public? && !page.redirects_to_external?
|
52
|
+
page
|
53
|
+
elsif Alchemy::Config.get(:redirect_to_public_child) && page.visible? && !page.public? && page.children.published.any?
|
54
|
+
page.children.published.first
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_to_nodes(children, node:)
|
59
|
+
children.each do |page|
|
60
|
+
has_children = page.children.any?
|
61
|
+
next unless page.visible || has_children
|
62
|
+
|
63
|
+
Alchemy::Deprecation.silence do
|
64
|
+
new_node = node.children.create!(
|
65
|
+
name: name_for_node(page),
|
66
|
+
page: page_for_node(page),
|
67
|
+
url: page.redirects_to_external? ? page.urlname : nil,
|
68
|
+
external: page.redirects_to_external? && Alchemy::Config.get(:open_external_links_in_new_tab),
|
69
|
+
language_id: page.language_id
|
70
|
+
)
|
71
|
+
print "."
|
72
|
+
if has_children
|
73
|
+
convert_to_nodes(page.children, node: new_node)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
menu_count = Alchemy::Language.count
|
80
|
+
puts "\n- Converting #{menu_count} page #{'tree'.pluralize(menu_count)} into #{'menu'.pluralize(menu_count)}."
|
81
|
+
Alchemy::BaseRecord.transaction do
|
82
|
+
Alchemy::Language.all.each do |language|
|
83
|
+
locale = language.locale.presence || I18n.default_locale
|
84
|
+
menu_name = I18n.t('Main Navigation', scope: 'alchemy.menu_names', default: 'Main Navigation', locale: locale)
|
85
|
+
root_node = Alchemy::Node.create(language: language, name: menu_name)
|
86
|
+
language.pages.language_roots.each do |root_page|
|
87
|
+
convert_to_nodes(root_page.children, node: root_node)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
puts "\n✓ Done."
|
92
|
+
end
|
93
|
+
end
|
34
94
|
end
|
35
95
|
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
|
+
version: 4.4.0
|
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:
|
16
|
+
date: 2020-01-06 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: active_model_serializers
|
@@ -33,16 +33,22 @@ dependencies:
|
|
33
33
|
name: acts_as_list
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
35
35
|
requirements:
|
36
|
-
- - "
|
36
|
+
- - ">="
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: '0.3'
|
39
|
+
- - "<"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2'
|
39
42
|
type: :runtime
|
40
43
|
prerelease: false
|
41
44
|
version_requirements: !ruby/object:Gem::Requirement
|
42
45
|
requirements:
|
43
|
-
- - "
|
46
|
+
- - ">="
|
44
47
|
- !ruby/object:Gem::Version
|
45
48
|
version: '0.3'
|
49
|
+
- - "<"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '2'
|
46
52
|
- !ruby/object:Gem::Dependency
|
47
53
|
name: awesome_nested_set
|
48
54
|
requirement: !ruby/object:Gem::Requirement
|
@@ -355,6 +361,26 @@ dependencies:
|
|
355
361
|
- - "<"
|
356
362
|
- !ruby/object:Gem::Version
|
357
363
|
version: '6'
|
364
|
+
- !ruby/object:Gem::Dependency
|
365
|
+
name: sprockets
|
366
|
+
requirement: !ruby/object:Gem::Requirement
|
367
|
+
requirements:
|
368
|
+
- - ">="
|
369
|
+
- !ruby/object:Gem::Version
|
370
|
+
version: '3.0'
|
371
|
+
- - "<"
|
372
|
+
- !ruby/object:Gem::Version
|
373
|
+
version: '5'
|
374
|
+
type: :runtime
|
375
|
+
prerelease: false
|
376
|
+
version_requirements: !ruby/object:Gem::Requirement
|
377
|
+
requirements:
|
378
|
+
- - ">="
|
379
|
+
- !ruby/object:Gem::Version
|
380
|
+
version: '3.0'
|
381
|
+
- - "<"
|
382
|
+
- !ruby/object:Gem::Version
|
383
|
+
version: '5'
|
358
384
|
- !ruby/object:Gem::Dependency
|
359
385
|
name: turbolinks
|
360
386
|
requirement: !ruby/object:Gem::Requirement
|
@@ -411,6 +437,20 @@ dependencies:
|
|
411
437
|
- - "~>"
|
412
438
|
- !ruby/object:Gem::Version
|
413
439
|
version: '5.0'
|
440
|
+
- !ruby/object:Gem::Dependency
|
441
|
+
name: puma
|
442
|
+
requirement: !ruby/object:Gem::Requirement
|
443
|
+
requirements:
|
444
|
+
- - "~>"
|
445
|
+
- !ruby/object:Gem::Version
|
446
|
+
version: '4.0'
|
447
|
+
type: :development
|
448
|
+
prerelease: false
|
449
|
+
version_requirements: !ruby/object:Gem::Requirement
|
450
|
+
requirements:
|
451
|
+
- - "~>"
|
452
|
+
- !ruby/object:Gem::Version
|
453
|
+
version: '4.0'
|
414
454
|
- !ruby/object:Gem::Dependency
|
415
455
|
name: rails-controller-testing
|
416
456
|
requirement: !ruby/object:Gem::Requirement
|
@@ -454,19 +494,19 @@ dependencies:
|
|
454
494
|
- !ruby/object:Gem::Version
|
455
495
|
version: 4.0.0.beta2
|
456
496
|
- !ruby/object:Gem::Dependency
|
457
|
-
name:
|
497
|
+
name: webdrivers
|
458
498
|
requirement: !ruby/object:Gem::Requirement
|
459
499
|
requirements:
|
460
500
|
- - "~>"
|
461
501
|
- !ruby/object:Gem::Version
|
462
|
-
version: '
|
502
|
+
version: '4.0'
|
463
503
|
type: :development
|
464
504
|
prerelease: false
|
465
505
|
version_requirements: !ruby/object:Gem::Requirement
|
466
506
|
requirements:
|
467
507
|
- - "~>"
|
468
508
|
- !ruby/object:Gem::Version
|
469
|
-
version: '
|
509
|
+
version: '4.0'
|
470
510
|
- !ruby/object:Gem::Dependency
|
471
511
|
name: shoulda-matchers
|
472
512
|
requirement: !ruby/object:Gem::Requirement
|
@@ -493,12 +533,11 @@ files:
|
|
493
533
|
- ".github/FUNDING.yml"
|
494
534
|
- ".github/ISSUE_TEMPLATE/Bug_report.md"
|
495
535
|
- ".github/ISSUE_TEMPLATE/Feature_request.md"
|
536
|
+
- ".github/workflows/ci.yml"
|
496
537
|
- ".gitignore"
|
497
538
|
- ".hound.yml"
|
498
539
|
- ".localeapp/config.rb"
|
499
|
-
- ".rspec"
|
500
540
|
- ".rubocop.yml"
|
501
|
-
- ".travis.yml"
|
502
541
|
- ".yardopts"
|
503
542
|
- CHANGELOG.md
|
504
543
|
- CODE_OF_CONDUCT.md
|
@@ -509,6 +548,7 @@ files:
|
|
509
548
|
- README.md
|
510
549
|
- Rakefile
|
511
550
|
- alchemy_cms.gemspec
|
551
|
+
- app/assets/config/alchemy_manifest.js
|
512
552
|
- app/assets/images/alchemy/alchemy-logo.png
|
513
553
|
- app/assets/images/alchemy/alchemy-logo.svg
|
514
554
|
- app/assets/images/alchemy/favicon.ico
|
@@ -552,8 +592,10 @@ files:
|
|
552
592
|
- app/assets/javascripts/alchemy/alchemy.trash_window.js.coffee
|
553
593
|
- app/assets/javascripts/alchemy/alchemy.uploader.js.coffee
|
554
594
|
- app/assets/javascripts/alchemy/menubar.js.coffee
|
595
|
+
- app/assets/javascripts/alchemy/page_select.js
|
555
596
|
- app/assets/javascripts/alchemy/preview.js
|
556
597
|
- app/assets/javascripts/alchemy/templates/index.js
|
598
|
+
- app/assets/javascripts/alchemy/templates/page.hbs
|
557
599
|
- app/assets/javascripts/alchemy/templates/spinner.hbs
|
558
600
|
- app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js
|
559
601
|
- app/assets/stylesheets/alchemy/_defaults.scss
|
@@ -581,10 +623,13 @@ files:
|
|
581
623
|
- app/assets/stylesheets/alchemy/icons.scss
|
582
624
|
- app/assets/stylesheets/alchemy/image_library.scss
|
583
625
|
- app/assets/stylesheets/alchemy/jquery-ui.scss
|
626
|
+
- app/assets/stylesheets/alchemy/labels.scss
|
584
627
|
- app/assets/stylesheets/alchemy/lists.scss
|
585
628
|
- app/assets/stylesheets/alchemy/menubar.scss
|
586
629
|
- app/assets/stylesheets/alchemy/navigation.scss
|
630
|
+
- app/assets/stylesheets/alchemy/nodes.scss
|
587
631
|
- app/assets/stylesheets/alchemy/notices.scss
|
632
|
+
- app/assets/stylesheets/alchemy/page-select.scss
|
588
633
|
- app/assets/stylesheets/alchemy/pagination.scss
|
589
634
|
- app/assets/stylesheets/alchemy/preview_window.scss
|
590
635
|
- app/assets/stylesheets/alchemy/print.scss
|
@@ -623,6 +668,7 @@ files:
|
|
623
668
|
- app/controllers/alchemy/admin/languages_controller.rb
|
624
669
|
- app/controllers/alchemy/admin/layoutpages_controller.rb
|
625
670
|
- app/controllers/alchemy/admin/legacy_page_urls_controller.rb
|
671
|
+
- app/controllers/alchemy/admin/nodes_controller.rb
|
626
672
|
- app/controllers/alchemy/admin/pages_controller.rb
|
627
673
|
- app/controllers/alchemy/admin/pictures_controller.rb
|
628
674
|
- app/controllers/alchemy/admin/resources_controller.rb
|
@@ -678,6 +724,7 @@ files:
|
|
678
724
|
- app/models/alchemy/essence_file.rb
|
679
725
|
- app/models/alchemy/essence_html.rb
|
680
726
|
- app/models/alchemy/essence_link.rb
|
727
|
+
- app/models/alchemy/essence_page.rb
|
681
728
|
- app/models/alchemy/essence_picture.rb
|
682
729
|
- app/models/alchemy/essence_picture_view.rb
|
683
730
|
- app/models/alchemy/essence_richtext.rb
|
@@ -688,13 +735,13 @@ files:
|
|
688
735
|
- app/models/alchemy/language/code.rb
|
689
736
|
- app/models/alchemy/legacy_page_url.rb
|
690
737
|
- app/models/alchemy/message.rb
|
738
|
+
- app/models/alchemy/node.rb
|
691
739
|
- app/models/alchemy/page.rb
|
692
740
|
- app/models/alchemy/page/fixed_attributes.rb
|
693
741
|
- app/models/alchemy/page/page_elements.rb
|
694
742
|
- app/models/alchemy/page/page_naming.rb
|
695
743
|
- app/models/alchemy/page/page_natures.rb
|
696
744
|
- app/models/alchemy/page/page_scopes.rb
|
697
|
-
- app/models/alchemy/page/page_users.rb
|
698
745
|
- app/models/alchemy/picture.rb
|
699
746
|
- app/models/alchemy/picture/transformations.rb
|
700
747
|
- app/models/alchemy/picture/url.rb
|
@@ -757,7 +804,6 @@ files:
|
|
757
804
|
- app/views/alchemy/admin/elements/create.js.erb
|
758
805
|
- app/views/alchemy/admin/elements/fold.js.erb
|
759
806
|
- app/views/alchemy/admin/elements/index.html.erb
|
760
|
-
- app/views/alchemy/admin/elements/list.html.erb
|
761
807
|
- app/views/alchemy/admin/elements/new.html.erb
|
762
808
|
- app/views/alchemy/admin/elements/order.js.erb
|
763
809
|
- app/views/alchemy/admin/elements/publish.js.erb
|
@@ -786,6 +832,12 @@ files:
|
|
786
832
|
- app/views/alchemy/admin/legacy_page_urls/create.js.erb
|
787
833
|
- app/views/alchemy/admin/legacy_page_urls/destroy.js.erb
|
788
834
|
- app/views/alchemy/admin/legacy_page_urls/update.js.erb
|
835
|
+
- app/views/alchemy/admin/nodes/_form.html.erb
|
836
|
+
- app/views/alchemy/admin/nodes/_node.html.erb
|
837
|
+
- app/views/alchemy/admin/nodes/edit.html.erb
|
838
|
+
- app/views/alchemy/admin/nodes/index.html.erb
|
839
|
+
- app/views/alchemy/admin/nodes/new.html.erb
|
840
|
+
- app/views/alchemy/admin/pages/_anchor_link.html.erb
|
789
841
|
- app/views/alchemy/admin/pages/_create_language_form.html.erb
|
790
842
|
- app/views/alchemy/admin/pages/_current_page.html.erb
|
791
843
|
- app/views/alchemy/admin/pages/_external_link.html.erb
|
@@ -794,9 +846,9 @@ files:
|
|
794
846
|
- app/views/alchemy/admin/pages/_internal_link.html.erb
|
795
847
|
- app/views/alchemy/admin/pages/_legacy_urls.html.erb
|
796
848
|
- app/views/alchemy/admin/pages/_locked_page.html.erb
|
849
|
+
- app/views/alchemy/admin/pages/_menu_fields.html.erb
|
797
850
|
- app/views/alchemy/admin/pages/_new_page_form.html.erb
|
798
851
|
- app/views/alchemy/admin/pages/_page.html.erb
|
799
|
-
- app/views/alchemy/admin/pages/_page_for_links.html.erb
|
800
852
|
- app/views/alchemy/admin/pages/_page_infos.html.erb
|
801
853
|
- app/views/alchemy/admin/pages/_page_status.html.erb
|
802
854
|
- app/views/alchemy/admin/pages/_publication_fields.html.erb
|
@@ -889,6 +941,8 @@ files:
|
|
889
941
|
- app/views/alchemy/essences/_essence_html_view.html.erb
|
890
942
|
- app/views/alchemy/essences/_essence_link_editor.html.erb
|
891
943
|
- app/views/alchemy/essences/_essence_link_view.html.erb
|
944
|
+
- app/views/alchemy/essences/_essence_page_editor.html.erb
|
945
|
+
- app/views/alchemy/essences/_essence_page_view.html.erb
|
892
946
|
- app/views/alchemy/essences/_essence_picture_editor.html.erb
|
893
947
|
- app/views/alchemy/essences/_essence_picture_view.html.erb
|
894
948
|
- app/views/alchemy/essences/_essence_richtext_editor.html.erb
|
@@ -938,6 +992,8 @@ files:
|
|
938
992
|
- db/migrate/20180226123013_alchemy_four_point_zero.rb
|
939
993
|
- db/migrate/20180227224537_migrate_tags_to_gutentag.rb
|
940
994
|
- db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb
|
995
|
+
- db/migrate/20191016073858_create_alchemy_essence_pages.rb
|
996
|
+
- db/migrate/20191029212236_create_alchemy_nodes.rb
|
941
997
|
- lib/alchemy/ability_helper.rb
|
942
998
|
- lib/alchemy/admin/locale.rb
|
943
999
|
- lib/alchemy/auth_accessors.rb
|
@@ -981,9 +1037,11 @@ files:
|
|
981
1037
|
- lib/alchemy/test_support/factories/dummy_user_factory.rb
|
982
1038
|
- lib/alchemy/test_support/factories/element_factory.rb
|
983
1039
|
- lib/alchemy/test_support/factories/essence_file_factory.rb
|
1040
|
+
- lib/alchemy/test_support/factories/essence_page_factory.rb
|
984
1041
|
- lib/alchemy/test_support/factories/essence_picture_factory.rb
|
985
1042
|
- lib/alchemy/test_support/factories/essence_text_factory.rb
|
986
1043
|
- lib/alchemy/test_support/factories/language_factory.rb
|
1044
|
+
- lib/alchemy/test_support/factories/node_factory.rb
|
987
1045
|
- lib/alchemy/test_support/factories/page_factory.rb
|
988
1046
|
- lib/alchemy/test_support/factories/picture_factory.rb
|
989
1047
|
- lib/alchemy/test_support/factories/site_factory.rb
|
@@ -1007,21 +1065,15 @@ files:
|
|
1007
1065
|
- lib/kaminari/scoped_pagination_url_helper.rb
|
1008
1066
|
- lib/rails/generators/alchemy/base.rb
|
1009
1067
|
- lib/rails/generators/alchemy/elements/elements_generator.rb
|
1010
|
-
- lib/rails/generators/alchemy/elements/templates/editor.html.erb
|
1011
|
-
- lib/rails/generators/alchemy/elements/templates/editor.html.haml
|
1012
|
-
- lib/rails/generators/alchemy/elements/templates/editor.html.slim
|
1013
1068
|
- lib/rails/generators/alchemy/elements/templates/view.html.erb
|
1014
1069
|
- lib/rails/generators/alchemy/elements/templates/view.html.haml
|
1015
1070
|
- lib/rails/generators/alchemy/elements/templates/view.html.slim
|
1016
1071
|
- lib/rails/generators/alchemy/essence/essence_generator.rb
|
1017
1072
|
- lib/rails/generators/alchemy/essence/templates/editor.html.erb
|
1018
1073
|
- lib/rails/generators/alchemy/essence/templates/view.html.erb
|
1019
|
-
- lib/rails/generators/alchemy/install/files/
|
1020
|
-
- lib/rails/generators/alchemy/install/files/_article_view.html.erb
|
1074
|
+
- lib/rails/generators/alchemy/install/files/_article.html.erb
|
1021
1075
|
- lib/rails/generators/alchemy/install/files/_standard.html.erb
|
1022
|
-
- lib/rails/generators/alchemy/install/files/alchemy.de.yml
|
1023
1076
|
- lib/rails/generators/alchemy/install/files/alchemy.en.yml
|
1024
|
-
- lib/rails/generators/alchemy/install/files/alchemy.es.yml
|
1025
1077
|
- lib/rails/generators/alchemy/install/files/all.css
|
1026
1078
|
- lib/rails/generators/alchemy/install/files/all.js
|
1027
1079
|
- lib/rails/generators/alchemy/install/files/application.html.erb
|
@@ -1030,6 +1082,13 @@ files:
|
|
1030
1082
|
- lib/rails/generators/alchemy/install/templates/dragonfly.rb.tt
|
1031
1083
|
- lib/rails/generators/alchemy/install/templates/elements.yml.tt
|
1032
1084
|
- lib/rails/generators/alchemy/install/templates/page_layouts.yml.tt
|
1085
|
+
- lib/rails/generators/alchemy/menus/menus_generator.rb
|
1086
|
+
- lib/rails/generators/alchemy/menus/templates/node.html.erb
|
1087
|
+
- lib/rails/generators/alchemy/menus/templates/node.html.haml
|
1088
|
+
- lib/rails/generators/alchemy/menus/templates/node.html.slim
|
1089
|
+
- lib/rails/generators/alchemy/menus/templates/wrapper.html.erb
|
1090
|
+
- lib/rails/generators/alchemy/menus/templates/wrapper.html.haml
|
1091
|
+
- lib/rails/generators/alchemy/menus/templates/wrapper.html.slim
|
1033
1092
|
- lib/rails/generators/alchemy/module/module_generator.rb
|
1034
1093
|
- lib/rails/generators/alchemy/module/templates/ability.rb.tt
|
1035
1094
|
- lib/rails/generators/alchemy/module/templates/controller.rb.tt
|
@@ -1129,7 +1188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1129
1188
|
version: '0'
|
1130
1189
|
requirements:
|
1131
1190
|
- ImageMagick (libmagick), v6.6 or greater.
|
1132
|
-
rubygems_version: 3.
|
1191
|
+
rubygems_version: 3.1.2
|
1133
1192
|
signing_key:
|
1134
1193
|
specification_version: 4
|
1135
1194
|
summary: A powerful, userfriendly and flexible CMS for Rails 5
|