alchemy_cms 4.3.2 → 4.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.
- 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
|
@@ -25,9 +25,13 @@
|
|
|
25
25
|
|
|
26
26
|
module Alchemy
|
|
27
27
|
class EssencePicture < BaseRecord
|
|
28
|
-
acts_as_essence ingredient_column:
|
|
28
|
+
acts_as_essence ingredient_column: :picture, belongs_to: {
|
|
29
|
+
class_name: 'Alchemy::Picture',
|
|
30
|
+
foreign_key: :picture_id,
|
|
31
|
+
inverse_of: :essence_pictures,
|
|
32
|
+
optional: true
|
|
33
|
+
}
|
|
29
34
|
|
|
30
|
-
belongs_to :picture, optional: true
|
|
31
35
|
delegate :image_file_width, :image_file_height, :image_file, to: :picture
|
|
32
36
|
before_save :fix_crop_values
|
|
33
37
|
before_save :replace_newlines
|
|
@@ -75,7 +79,8 @@ module Alchemy
|
|
|
75
79
|
{
|
|
76
80
|
format: picture.default_render_format,
|
|
77
81
|
crop_from: crop_from.presence,
|
|
78
|
-
crop_size: crop_size.presence
|
|
82
|
+
crop_size: crop_size.presence,
|
|
83
|
+
size: content.settings[:size]
|
|
79
84
|
}.with_indifferent_access
|
|
80
85
|
end
|
|
81
86
|
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
# locale :string
|
|
21
21
|
#
|
|
22
22
|
|
|
23
|
+
require_dependency 'alchemy/site'
|
|
24
|
+
|
|
23
25
|
module Alchemy
|
|
24
26
|
class Language < BaseRecord
|
|
25
27
|
belongs_to :site
|
|
@@ -57,10 +59,16 @@ module Alchemy
|
|
|
57
59
|
|
|
58
60
|
scope :published, -> { where(public: true) }
|
|
59
61
|
scope :with_root_page, -> { joins(:pages).where(Page.table_name => {language_root: true}) }
|
|
60
|
-
scope :on_site, ->(s) { s ? where(site_id: s.id) : all }
|
|
61
|
-
scope :on_current_site, -> { on_site(Site.current) }
|
|
62
62
|
|
|
63
63
|
class << self
|
|
64
|
+
def on_site(site)
|
|
65
|
+
site ? where(site_id: site.id) : all
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def on_current_site
|
|
69
|
+
on_site(Site.current)
|
|
70
|
+
end
|
|
71
|
+
|
|
64
72
|
# Store the current language in the current thread.
|
|
65
73
|
def current=(language)
|
|
66
74
|
RequestStore.store[:alchemy_current_language] = language
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Alchemy
|
|
4
|
+
class Node < BaseRecord
|
|
5
|
+
VALID_URL_REGEX = /\A(\/|\D[a-z\+\d\.\-]+:)/
|
|
6
|
+
|
|
7
|
+
acts_as_nested_set scope: 'language_id', touch: true
|
|
8
|
+
stampable stamper_class_name: Alchemy.user_class_name
|
|
9
|
+
|
|
10
|
+
belongs_to :language, class_name: 'Alchemy::Language'
|
|
11
|
+
belongs_to :page, class_name: 'Alchemy::Page', optional: true, inverse_of: :nodes
|
|
12
|
+
|
|
13
|
+
validates :name, presence: true, if: -> { page.nil? }
|
|
14
|
+
validates :url, format: { with: VALID_URL_REGEX }, unless: -> { url.nil? }
|
|
15
|
+
|
|
16
|
+
# Returns the name
|
|
17
|
+
#
|
|
18
|
+
# Either the value is stored in the database
|
|
19
|
+
# or, if attached, the values comes from a page.
|
|
20
|
+
def name
|
|
21
|
+
read_attribute(:name).presence || page&.name
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class << self
|
|
25
|
+
# Returns all root nodes for current language
|
|
26
|
+
def language_root_nodes
|
|
27
|
+
raise 'No language found' if Language.current.nil?
|
|
28
|
+
roots.where(language_id: Language.current.id)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns the url
|
|
33
|
+
#
|
|
34
|
+
# Either the value is stored in the database, aka. an external url.
|
|
35
|
+
# Or, if attached, the values comes from a page.
|
|
36
|
+
def url
|
|
37
|
+
page && "/#{page.urlname}" || read_attribute(:url).presence
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def to_partial_path
|
|
41
|
+
"#{view_folder_name}/wrapper"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def view_folder_name
|
|
45
|
+
"alchemy/menus/#{name.parameterize.underscore}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/app/models/alchemy/page.rb
CHANGED
|
@@ -79,7 +79,8 @@ module Alchemy
|
|
|
79
79
|
:title,
|
|
80
80
|
:urlname,
|
|
81
81
|
:visible,
|
|
82
|
-
:layoutpage
|
|
82
|
+
:layoutpage,
|
|
83
|
+
:menu_id
|
|
83
84
|
]
|
|
84
85
|
|
|
85
86
|
acts_as_nested_set(dependent: :destroy)
|
|
@@ -88,10 +89,29 @@ module Alchemy
|
|
|
88
89
|
|
|
89
90
|
belongs_to :language, optional: true
|
|
90
91
|
|
|
92
|
+
belongs_to :creator,
|
|
93
|
+
primary_key: Alchemy.user_class.primary_key,
|
|
94
|
+
class_name: Alchemy.user_class_name,
|
|
95
|
+
foreign_key: :creator_id,
|
|
96
|
+
optional: true
|
|
97
|
+
|
|
98
|
+
belongs_to :updater,
|
|
99
|
+
primary_key: Alchemy.user_class.primary_key,
|
|
100
|
+
class_name: Alchemy.user_class_name,
|
|
101
|
+
foreign_key: :updater_id,
|
|
102
|
+
optional: true
|
|
103
|
+
|
|
104
|
+
belongs_to :locker,
|
|
105
|
+
primary_key: Alchemy.user_class.primary_key,
|
|
106
|
+
class_name: Alchemy.user_class_name,
|
|
107
|
+
foreign_key: :locked_by,
|
|
108
|
+
optional: true
|
|
109
|
+
|
|
91
110
|
has_one :site, through: :language
|
|
92
111
|
has_many :site_languages, through: :site, source: :languages
|
|
93
112
|
has_many :folded_pages
|
|
94
113
|
has_many :legacy_urls, class_name: 'Alchemy::LegacyPageUrl'
|
|
114
|
+
has_many :nodes, class_name: 'Alchemy::Node', inverse_of: :page
|
|
95
115
|
|
|
96
116
|
validates_presence_of :language, on: :create, unless: :root
|
|
97
117
|
validates_presence_of :page_layout, unless: :systempage?
|
|
@@ -125,16 +145,22 @@ module Alchemy
|
|
|
125
145
|
if: :should_create_legacy_url?,
|
|
126
146
|
unless: :redirects_to_external?
|
|
127
147
|
|
|
148
|
+
after_update :attach_to_menu!,
|
|
149
|
+
if: :should_attach_to_menu?
|
|
150
|
+
|
|
151
|
+
after_update -> { nodes.update_all(updated_at: Time.current) }
|
|
152
|
+
|
|
128
153
|
# Concerns
|
|
129
154
|
include Alchemy::Page::PageScopes
|
|
130
155
|
include Alchemy::Page::PageNatures
|
|
131
156
|
include Alchemy::Page::PageNaming
|
|
132
|
-
include Alchemy::Page::PageUsers
|
|
133
157
|
include Alchemy::Page::PageElements
|
|
134
158
|
|
|
135
159
|
# site_name accessor
|
|
136
160
|
delegate :name, to: :site, prefix: true, allow_nil: true
|
|
137
161
|
|
|
162
|
+
attr_accessor :menu_id
|
|
163
|
+
|
|
138
164
|
# Class methods
|
|
139
165
|
#
|
|
140
166
|
class << self
|
|
@@ -387,7 +413,7 @@ module Alchemy
|
|
|
387
413
|
|
|
388
414
|
def set_restrictions_to_child_pages
|
|
389
415
|
descendants.each do |child|
|
|
390
|
-
child.
|
|
416
|
+
child.update(restricted: restricted?)
|
|
391
417
|
end
|
|
392
418
|
end
|
|
393
419
|
|
|
@@ -488,6 +514,39 @@ module Alchemy
|
|
|
488
514
|
attribute_fixed?(:public_until) ? fixed_attributes[:public_until] : self[:public_until]
|
|
489
515
|
end
|
|
490
516
|
|
|
517
|
+
# Returns the name of the creator of this page.
|
|
518
|
+
#
|
|
519
|
+
# If no creator could be found or associated user model
|
|
520
|
+
# does not respond to +#name+ it returns +'unknown'+
|
|
521
|
+
#
|
|
522
|
+
def creator_name
|
|
523
|
+
creator.try(:name) || Alchemy.t('unknown')
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
# Returns the name of the last updater of this page.
|
|
527
|
+
#
|
|
528
|
+
# If no updater could be found or associated user model
|
|
529
|
+
# does not respond to +#name+ it returns +'unknown'+
|
|
530
|
+
#
|
|
531
|
+
def updater_name
|
|
532
|
+
updater.try(:name) || Alchemy.t('unknown')
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
# Returns the name of the user currently editing this page.
|
|
536
|
+
#
|
|
537
|
+
# If no locker could be found or associated user model
|
|
538
|
+
# does not respond to +#name+ it returns +'unknown'+
|
|
539
|
+
#
|
|
540
|
+
def locker_name
|
|
541
|
+
locker.try(:name) || Alchemy.t('unknown')
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
# Menus (aka. root nodes) this page is attached to
|
|
545
|
+
#
|
|
546
|
+
def menus
|
|
547
|
+
@_menus ||= nodes.map(&:root)
|
|
548
|
+
end
|
|
549
|
+
|
|
491
550
|
private
|
|
492
551
|
|
|
493
552
|
def set_fixed_attributes
|
|
@@ -533,5 +592,17 @@ module Alchemy
|
|
|
533
592
|
def set_published_at
|
|
534
593
|
self.published_at = Time.current
|
|
535
594
|
end
|
|
595
|
+
|
|
596
|
+
def attach_to_menu!
|
|
597
|
+
Alchemy::Node.find(menu_id).children.create!(
|
|
598
|
+
language_id: language_id,
|
|
599
|
+
page_id: id,
|
|
600
|
+
name: name
|
|
601
|
+
)
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
def should_attach_to_menu?
|
|
605
|
+
menu_id && nodes.none?
|
|
606
|
+
end
|
|
536
607
|
end
|
|
537
608
|
end
|
|
@@ -9,16 +9,24 @@ module Alchemy
|
|
|
9
9
|
|
|
10
10
|
has_many :all_elements,
|
|
11
11
|
-> { order(:position) },
|
|
12
|
-
class_name: 'Alchemy::Element'
|
|
12
|
+
class_name: 'Alchemy::Element',
|
|
13
|
+
inverse_of: :page
|
|
13
14
|
has_many :elements,
|
|
14
15
|
-> { order(:position).not_nested.unfixed.available },
|
|
15
|
-
class_name: 'Alchemy::Element'
|
|
16
|
+
class_name: 'Alchemy::Element',
|
|
17
|
+
inverse_of: :page
|
|
16
18
|
has_many :trashed_elements,
|
|
17
19
|
-> { Element.trashed.order(:position) },
|
|
18
|
-
class_name: 'Alchemy::Element'
|
|
20
|
+
class_name: 'Alchemy::Element',
|
|
21
|
+
inverse_of: :page
|
|
19
22
|
has_many :fixed_elements,
|
|
20
23
|
-> { order(:position).fixed.available },
|
|
21
|
-
class_name: 'Alchemy::Element'
|
|
24
|
+
class_name: 'Alchemy::Element',
|
|
25
|
+
inverse_of: :page
|
|
26
|
+
has_many :dependent_destroyable_elements,
|
|
27
|
+
-> { not_nested },
|
|
28
|
+
class_name: 'Alchemy::Element',
|
|
29
|
+
dependent: :destroy
|
|
22
30
|
has_many :contents, through: :elements
|
|
23
31
|
has_and_belongs_to_many :to_be_swept_elements, -> { distinct },
|
|
24
32
|
class_name: 'Alchemy::Element',
|
|
@@ -55,19 +55,24 @@ module Alchemy
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# Returns true or false if the pages definition for config/alchemy/page_layouts.yml contains redirects_to_external: true
|
|
58
|
+
# @deprecated Please use a menu node with an external url instead.
|
|
58
59
|
def redirects_to_external?
|
|
59
60
|
!!definition["redirects_to_external"]
|
|
60
61
|
end
|
|
62
|
+
deprecate redirects_to_external?: 'Please use a menu node with an external url instead.', deprecator: Alchemy::Deprecation
|
|
61
63
|
|
|
64
|
+
# @deprecated
|
|
62
65
|
def has_controller?
|
|
63
66
|
!PageLayout.get(page_layout).nil? && !PageLayout.get(page_layout)["controller"].blank?
|
|
64
67
|
end
|
|
68
|
+
deprecate :has_controller?, deprecator: Alchemy::Deprecation
|
|
65
69
|
|
|
66
70
|
# True if page locked_at timestamp and locked_by id are set
|
|
67
71
|
def locked?
|
|
68
72
|
locked_by? && locked_at?
|
|
69
73
|
end
|
|
70
74
|
|
|
75
|
+
# @deprecated Please use a menu node with an url pointing to your controller path instead.
|
|
71
76
|
def controller_and_action
|
|
72
77
|
if has_controller?
|
|
73
78
|
{
|
|
@@ -76,6 +81,7 @@ module Alchemy
|
|
|
76
81
|
}
|
|
77
82
|
end
|
|
78
83
|
end
|
|
84
|
+
deprecate controller_and_action: 'Please use a menu node with an url pointing to your controller path instead.', deprecator: Alchemy::Deprecation
|
|
79
85
|
|
|
80
86
|
# Returns a Hash describing the status of the Page.
|
|
81
87
|
#
|
|
@@ -30,7 +30,11 @@ module Alchemy
|
|
|
30
30
|
include Alchemy::Picture::Transformations
|
|
31
31
|
include Alchemy::Picture::Url
|
|
32
32
|
|
|
33
|
-
has_many :essence_pictures,
|
|
33
|
+
has_many :essence_pictures,
|
|
34
|
+
class_name: 'Alchemy::EssencePicture',
|
|
35
|
+
foreign_key: 'picture_id',
|
|
36
|
+
inverse_of: :ingredient_association
|
|
37
|
+
|
|
34
38
|
has_many :contents, through: :essence_pictures
|
|
35
39
|
has_many :elements, through: :contents
|
|
36
40
|
has_many :pages, through: :elements
|
|
@@ -10,12 +10,18 @@ module Alchemy
|
|
|
10
10
|
:created_at,
|
|
11
11
|
:updated_at,
|
|
12
12
|
:ingredients,
|
|
13
|
-
:content_ids
|
|
13
|
+
:content_ids,
|
|
14
|
+
:dom_id,
|
|
15
|
+
:display_name
|
|
14
16
|
|
|
15
17
|
has_many :nested_elements
|
|
16
18
|
|
|
17
19
|
def ingredients
|
|
18
20
|
object.contents.collect(&:serialize)
|
|
19
21
|
end
|
|
22
|
+
|
|
23
|
+
def display_name
|
|
24
|
+
object.display_name_with_preview_text
|
|
25
|
+
end
|
|
20
26
|
end
|
|
21
27
|
end
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<li><%= link_to Alchemy.t(:to_alchemy), alchemy.admin_dashboard_url %></li>
|
|
5
5
|
<li><%= link_to Alchemy.t(:edit_page), alchemy.edit_admin_page_url(@page) %></li>
|
|
6
6
|
<li>
|
|
7
|
-
<%= form_tag Alchemy.logout_path, method:
|
|
7
|
+
<%= form_tag Alchemy.logout_path, method: Alchemy.logout_method do %>
|
|
8
8
|
<%= button_tag Alchemy.t(:logout) %>
|
|
9
9
|
<% end %>
|
|
10
10
|
</li>
|
|
@@ -16,7 +16,23 @@
|
|
|
16
16
|
<div id="element_<%= element.id %>_errors" class="element_errors"></div>
|
|
17
17
|
|
|
18
18
|
<div id="element_<%= element.id %>_content" class="element-content-editors">
|
|
19
|
-
|
|
19
|
+
<% element.definition[:message].tap do |message| %>
|
|
20
|
+
<%= render_message(:info, sanitize(message)) if message %>
|
|
21
|
+
<% end %>
|
|
22
|
+
<% element.definition[:warning].tap do |warning| %>
|
|
23
|
+
<%= render_message(:warning, sanitize(warning)) if warning %>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% if lookup_context.exists?("#{element.name}_editor", ["alchemy/elements"], true) %>
|
|
26
|
+
<%= render_editor(element) %>
|
|
27
|
+
<% else %>
|
|
28
|
+
<%= element_editor_for(element) do %>
|
|
29
|
+
<% element.contents.each do |content| %>
|
|
30
|
+
<%= render "alchemy/essences/#{content.essence_partial_name}_editor", {
|
|
31
|
+
content: content
|
|
32
|
+
} %>
|
|
33
|
+
<% end %>
|
|
34
|
+
<% end %>
|
|
35
|
+
<% end %>
|
|
20
36
|
</div>
|
|
21
37
|
|
|
22
38
|
<% if element.taggable? %>
|
|
@@ -38,7 +54,7 @@
|
|
|
38
54
|
'droppable-elements' => element.nestable_elements.join(' ')
|
|
39
55
|
} do %>
|
|
40
56
|
<%= render partial: 'alchemy/admin/elements/element',
|
|
41
|
-
collection: element.all_nested_elements
|
|
57
|
+
collection: element.all_nested_elements %>
|
|
42
58
|
<% end %>
|
|
43
59
|
|
|
44
60
|
<% if element.expanded? || element.fixed? %>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<label><%= Alchemy.t("Do you want to") %></label>
|
|
6
6
|
<%= link_to Alchemy.t('stay logged in'), alchemy.root_path, class: 'button secondary' %>
|
|
7
7
|
</p>
|
|
8
|
-
<%= form_tag Alchemy.logout_path, method:
|
|
8
|
+
<%= form_tag Alchemy.logout_path, method: Alchemy.logout_method, class: 'buttons' do %>
|
|
9
9
|
<label><%= Alchemy.t('or to completely') %></label>
|
|
10
10
|
<%= button_tag Alchemy.t(:logout), autofocus: true %>
|
|
11
11
|
<% end %>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<%= alchemy_form_for([:admin, node]) do |f| %>
|
|
2
|
+
<%= f.input :name, input_html: {
|
|
3
|
+
autofocus: true,
|
|
4
|
+
value: node.page && node.read_attribute(:name).blank? ? nil : node.name,
|
|
5
|
+
placeholder: node.page ? node.page.name : nil
|
|
6
|
+
} %>
|
|
7
|
+
<% unless node.root? %>
|
|
8
|
+
<%= f.input :page_id, label: Alchemy::Page.model_name.human, input_html: { class: 'alchemy_selectbox' } %>
|
|
9
|
+
<%= f.input :url, input_html: { disabled: node.page }, hint: Alchemy.t(:node_url_hint) %>
|
|
10
|
+
<%= f.input :title %>
|
|
11
|
+
<%= f.input :nofollow %>
|
|
12
|
+
<%= f.input :external %>
|
|
13
|
+
<%= f.hidden_field :parent_id %>
|
|
14
|
+
<% end %>
|
|
15
|
+
<%= f.hidden_field :language_id %>
|
|
16
|
+
<%= f.submit button_label %>
|
|
17
|
+
<% end %>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
$('#node_page_id').alchemyPageSelect({
|
|
21
|
+
placeholder: "<%= Alchemy.t(:search_page) %>",
|
|
22
|
+
url: "<%= alchemy.api_pages_path %>",
|
|
23
|
+
<% if node.page %>
|
|
24
|
+
initialSelection: {
|
|
25
|
+
id: <%= node.page_id %>,
|
|
26
|
+
text: "<%= node.page.name %>",
|
|
27
|
+
url: "/<%= node.page.urlname %>"
|
|
28
|
+
}
|
|
29
|
+
<% end %>
|
|
30
|
+
}).on('change', function(e) {
|
|
31
|
+
if (e.val === '') {
|
|
32
|
+
$('#node_name').removeAttr('placeholder')
|
|
33
|
+
$('#node_url').val('').prop('disabled', false)
|
|
34
|
+
} else {
|
|
35
|
+
$('#node_name').attr('placeholder', e.added.name)
|
|
36
|
+
$('#node_url').val('/' + e.added.urlname).prop('disabled', true)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
</script>
|