alchemy_cms 2.6.3 → 2.7.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/.simplecov +14 -0
- data/.travis.yml +1 -1
- data/Gemfile +7 -6
- data/README.md +15 -5
- data/alchemy_cms.gemspec +3 -2
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +9 -17
- data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +70 -0
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +80 -0
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +43 -19
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +3 -1
- data/app/assets/javascripts/alchemy/alchemy.js +4 -2
- data/app/assets/javascripts/alchemy/alchemy.onload.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.spinner.js.coffee +14 -0
- data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee.erb +96 -0
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +22 -0
- data/app/assets/javascripts/alchemy/alchemy.windows.js.coffee +28 -17
- data/app/assets/stylesheets/alchemy/base.scss +6 -0
- data/app/assets/stylesheets/alchemy/elements.scss +2 -28
- data/app/assets/stylesheets/alchemy/errors.scss +1 -1
- data/app/assets/stylesheets/alchemy/menubar.css.scss +2 -0
- data/app/assets/stylesheets/alchemy/sitemap.scss +21 -34
- data/app/assets/stylesheets/alchemy/tables.scss +13 -3
- data/app/controllers/alchemy/admin/attachments_controller.rb +10 -5
- data/app/controllers/alchemy/admin/base_controller.rb +19 -0
- data/app/controllers/alchemy/admin/contents_controller.rb +1 -4
- data/app/controllers/alchemy/admin/dashboard_controller.rb +2 -1
- data/app/controllers/alchemy/admin/elements_controller.rb +1 -1
- data/app/controllers/alchemy/admin/essence_files_controller.rb +1 -1
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +70 -56
- data/app/controllers/alchemy/admin/pages_controller.rb +37 -114
- data/app/controllers/alchemy/admin/pictures_controller.rb +5 -12
- data/app/controllers/alchemy/admin/resources_controller.rb +3 -1
- data/app/controllers/alchemy/admin/trash_controller.rb +1 -1
- data/app/controllers/alchemy/attachments_controller.rb +1 -1
- data/app/controllers/alchemy/base_controller.rb +3 -15
- data/app/controllers/alchemy/messages_controller.rb +4 -10
- data/app/controllers/alchemy/pages_controller.rb +6 -6
- data/app/controllers/alchemy/passwords_controller.rb +1 -1
- data/app/controllers/alchemy/user_sessions_controller.rb +1 -1
- data/app/helpers/alchemy/admin/base_helper.rb +49 -230
- data/app/helpers/alchemy/admin/contents_helper.rb +5 -1
- data/app/helpers/alchemy/admin/elements_helper.rb +19 -47
- data/app/helpers/alchemy/admin/essences_helper.rb +59 -17
- data/app/helpers/alchemy/admin/navigation_helper.rb +204 -0
- data/app/helpers/alchemy/admin/pages_helper.rb +22 -79
- data/app/helpers/alchemy/admin/pictures_helper.rb +1 -1
- data/app/helpers/alchemy/admin/tags_helper.rb +42 -0
- data/app/helpers/alchemy/base_helper.rb +0 -11
- data/app/helpers/alchemy/elements_helper.rb +48 -25
- data/app/helpers/alchemy/essences_helper.rb +0 -20
- data/app/helpers/alchemy/pages_helper.rb +18 -14
- data/app/helpers/alchemy/url_helper.rb +1 -0
- data/app/mailers/alchemy/messages.rb +4 -6
- data/app/models/alchemy/attachment.rb +3 -0
- data/app/models/alchemy/cell.rb +33 -35
- data/app/models/alchemy/content.rb +20 -111
- data/app/models/alchemy/content/factory.rb +188 -0
- data/app/models/alchemy/element.rb +51 -200
- data/app/models/alchemy/element/definitions.rb +52 -0
- data/app/models/alchemy/element/presenters.rb +87 -0
- data/app/models/alchemy/essence_date.rb +1 -1
- data/app/models/alchemy/essence_file.rb +6 -7
- data/app/models/alchemy/essence_picture.rb +19 -4
- data/app/models/alchemy/message.rb +18 -14
- data/app/models/alchemy/page.rb +120 -214
- data/app/models/alchemy/page/elements.rb +145 -36
- data/app/models/alchemy/page/natures.rb +90 -0
- data/app/models/alchemy/page/scopes.rb +93 -0
- data/app/models/alchemy/page/users.rb +25 -0
- data/app/models/alchemy/picture.rb +15 -0
- data/app/models/alchemy/site.rb +15 -1
- data/app/models/alchemy/site/layout.rb +38 -0
- data/app/models/alchemy/user.rb +13 -3
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +7 -7
- data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +8 -8
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +1 -16
- data/app/views/alchemy/admin/attachments/destroy.js.erb +1 -4
- data/app/views/alchemy/admin/contents/create.js.erb +1 -1
- data/app/views/alchemy/admin/dashboard/index.html.erb +14 -13
- data/app/views/alchemy/admin/elements/_element_head.html.erb +7 -7
- data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +10 -0
- data/app/views/alchemy/admin/elements/create.js.erb +44 -44
- data/app/views/alchemy/admin/elements/fold.js.erb +22 -26
- data/app/views/alchemy/admin/elements/trash.js.erb +1 -1
- data/app/views/alchemy/admin/elements/update.js.erb +22 -25
- data/app/views/alchemy/admin/essence_files/assign.js.erb +8 -3
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +14 -12
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +22 -39
- data/app/views/alchemy/admin/pages/_page.html.erb +73 -80
- data/app/views/alchemy/admin/pages/destroy.js.erb +2 -2
- data/app/views/alchemy/admin/pages/edit.html.erb +21 -18
- data/app/views/alchemy/admin/pages/fold.js.erb +1 -0
- data/app/views/alchemy/admin/pages/info.html.erb +32 -0
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +11 -13
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +20 -20
- data/app/views/alchemy/admin/partials/_sub_navigation.html.erb +8 -0
- data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +25 -0
- data/app/views/alchemy/admin/partials/_upload_form.html.erb +15 -15
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +39 -39
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +10 -10
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +1 -16
- data/app/views/alchemy/admin/resources/destroy.js.erb +1 -1
- data/app/views/alchemy/base/500.html.erb +1 -1
- data/app/views/alchemy/base/permission_denied.js.erb +1 -1
- data/app/views/alchemy/base/redirect.js.erb +1 -1
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +1 -1
- data/app/views/alchemy/essences/{_essence_picture_tools.html.erb → shared/_essence_picture_tools.html.erb} +5 -5
- data/app/views/alchemy/essences/{_linkable_essence_tools.html.erb → shared/_linkable_essence_tools.html.erb} +0 -0
- data/app/views/alchemy/messages/contact_form_mail.de.text.erb +12 -0
- data/app/views/alchemy/messages/contact_form_mail.en.text.erb +12 -0
- data/app/views/alchemy/notifications/reset_password_instructions.de.text.erb +1 -1
- data/app/views/alchemy/notifications/reset_password_instructions.en.text.erb +2 -2
- data/app/views/alchemy/pages/sitemap.xml.erb +3 -5
- data/app/views/alchemy/user_sessions/leave.html.erb +1 -1
- data/app/views/layouts/alchemy/admin.html.erb +4 -2
- data/app/views/layouts/alchemy/sitemap.xml.erb +1 -1
- data/bin/alchemy +7 -13
- data/config/alchemy/config.yml +1 -0
- data/config/authorization_rules.rb +2 -3
- data/config/initializers/dragonfly.rb +2 -0
- data/config/locales/alchemy.de.yml +8 -9
- data/config/locales/alchemy.en.yml +7 -4
- data/config/routes.rb +3 -0
- data/db/migrate/{20130214233001_alchemy_two_point_five.rb → 20130827094554_alchemy_two_point_six.rb} +29 -6
- data/lib/alchemy/auth/engine.rb +9 -0
- data/lib/alchemy/capistrano.rb +37 -12
- data/lib/alchemy/config.rb +48 -35
- data/lib/alchemy/engine.rb +35 -6
- data/lib/alchemy/essence.rb +25 -29
- data/lib/alchemy/ferret/search.rb +86 -0
- data/lib/alchemy/{scoped_pagination_url_helper.rb → kaminari/scoped_pagination_url_helper.rb} +0 -0
- data/lib/alchemy/logger.rb +3 -4
- data/lib/alchemy/page_layout.rb +124 -55
- data/lib/alchemy/resource.rb +0 -10
- data/lib/alchemy/resources_helper.rb +0 -5
- data/lib/alchemy/seeder.rb +1 -32
- data/lib/alchemy/shell.rb +6 -1
- data/lib/alchemy/tinymce.rb +41 -32
- data/lib/alchemy/upgrader.rb +3 -1
- data/lib/alchemy/upgrader/two_point_five.rb +15 -8
- data/lib/alchemy/upgrader/two_point_one.rb +10 -10
- data/lib/alchemy/upgrader/two_point_two.rb +96 -51
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +5 -46
- data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +1 -1
- data/lib/rails/generators/alchemy/devise/devise_generator.rb +9 -4
- data/lib/rails/generators/alchemy/essence/essence_generator.rb +7 -6
- data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -1
- data/lib/rails/generators/alchemy/scaffold/files/_standard.html.erb +1 -0
- data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +1 -0
- data/lib/rails/generators/alchemy/site_layouts/site_layouts_generator.rb +23 -0
- data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.erb +1 -0
- data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.haml +1 -0
- data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.slim +1 -0
- data/lib/rails/templates/alchemy.rb +2 -2
- data/lib/tasks/alchemy/db.rake +3 -1
- data/lib/tasks/alchemy/tidy.rake +82 -0
- data/lib/tasks/alchemy/upgrade.rake +2 -1
- data/spec/controllers/admin/attachments_controller_spec.rb +124 -0
- data/spec/controllers/admin/base_controller_spec.rb +35 -0
- data/spec/controllers/admin/clipboard_controller_spec.rb +1 -1
- data/spec/controllers/admin/contents_controller_spec.rb +17 -26
- data/spec/controllers/admin/dashboard_controller_spec.rb +121 -0
- data/spec/controllers/admin/elements_controller_spec.rb +1 -1
- data/spec/controllers/admin/essence_files_controller_spec.rb +67 -0
- data/spec/controllers/admin/essence_pictures_controller_spec.rb +161 -0
- data/spec/controllers/admin/languages_controller_spec.rb +1 -1
- data/spec/controllers/admin/layoutpages_controller_spec.rb +28 -0
- data/spec/controllers/admin/pages_controller_spec.rb +164 -118
- data/spec/controllers/admin/pictures_controller_spec.rb +89 -0
- data/spec/controllers/admin/trash_controller_spec.rb +21 -31
- data/spec/controllers/admin/users_controller_spec.rb +114 -85
- data/spec/controllers/attachments_controller_spec.rb +6 -2
- data/spec/controllers/base_controller_spec.rb +22 -0
- data/spec/controllers/elements_controller_spec.rb +1 -1
- data/spec/controllers/messages_controller_spec.rb +200 -0
- data/spec/controllers/pictures_controller_spec.rb +1 -1
- data/spec/controllers/user_sessions_controller_spec.rb +7 -6
- data/spec/controllers/users_controller_spec.rb +2 -2
- data/spec/dummy/config/alchemy/cells.yml +2 -0
- data/spec/dummy/config/application.rb +19 -8
- data/spec/dummy/db/migrate/{20130214233001_alchemy_two_point_five.rb → 20130827094554_alchemy_two_point_six.rb} +29 -6
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/fast_specs.rb +15 -0
- data/spec/helpers/admin/base_helper_spec.rb +53 -34
- data/spec/helpers/admin/contents_helper_spec.rb +15 -7
- data/spec/helpers/admin/elements_helper_spec.rb +79 -34
- data/spec/helpers/admin/essences_helper_spec.rb +45 -31
- data/spec/helpers/admin/navigation_helper_spec.rb +204 -0
- data/spec/helpers/admin/pages_helper_spec.rb +25 -15
- data/spec/helpers/admin/tags_helper_spec.rb +62 -2
- data/spec/helpers/elements_helper_spec.rb +202 -138
- data/spec/helpers/pages_helper_spec.rb +48 -0
- data/spec/helpers/url_helper_spec.rb +7 -0
- data/spec/libraries/config_spec.rb +110 -3
- data/spec/libraries/essence_spec.rb +29 -9
- data/spec/libraries/page_layout_spec.rb +134 -0
- data/spec/libraries/resource_spec.rb +3 -16
- data/spec/libraries/resources_helper_spec.rb +4 -8
- data/spec/libraries/shell_spec.rb +1 -0
- data/spec/libraries/tinymce_spec.rb +61 -0
- data/spec/mailers/messages_spec.rb +23 -0
- data/spec/models/attachment_spec.rb +45 -0
- data/spec/models/cell_spec.rb +62 -9
- data/spec/models/content_spec.rb +110 -28
- data/spec/models/element_spec.rb +275 -253
- data/spec/models/essence_date_spec.rb +25 -0
- data/spec/models/essence_file_spec.rb +23 -0
- data/spec/models/essence_html_spec.rb +13 -0
- data/spec/models/essence_picture_spec.rb +16 -0
- data/spec/models/essence_text_spec.rb +29 -0
- data/spec/models/language_spec.rb +34 -0
- data/spec/models/message_spec.rb +43 -0
- data/spec/models/page_spec.rb +726 -567
- data/spec/models/picture_spec.rb +98 -0
- data/spec/models/site_spec.rb +60 -2
- data/spec/models/tag_spec.rb +31 -0
- data/spec/models/user_spec.rb +4 -4
- data/spec/spec_helper.rb +49 -58
- data/spec/support/alchemy/controller_helpers.rb +35 -0
- data/spec/support/alchemy/{specs_helpers.rb → integration_helpers.rb} +4 -8
- data/spec/{factories.rb → support/factories.rb} +11 -1
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +2 -8
- metadata +166 -106
- data/Guardfile +0 -16
- data/app/assets/javascripts/alchemy/alchemy.dirty.js +0 -93
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +0 -122
- data/app/models/alchemy/tree_node.rb +0 -4
- data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -3
- data/app/views/alchemy/admin/partials/_sub_navigation_tab.html.erb +0 -8
- data/app/views/alchemy/messages/contact_form_mail.text.erb +0 -12
- data/config/initializers/kaminari_config.rb +0 -9
- data/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +0 -21
- data/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +0 -11
- data/lib/alchemy/auth_engine.rb +0 -7
- data/lib/alchemy/authentication_helpers.rb +0 -9
- data/lib/alchemy/ferret_search.rb +0 -84
- data/lib/extensions/array.rb +0 -25
- data/lib/extensions/hash.rb +0 -34
- data/spec/dummy/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +0 -21
- data/spec/dummy/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +0 -11
- data/spec/models/page_layout_spec.rb +0 -60
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module Alchemy
|
|
2
2
|
module Admin
|
|
3
3
|
module ContentsHelper
|
|
4
|
-
|
|
5
4
|
include Alchemy::Admin::BaseHelper
|
|
6
5
|
|
|
7
6
|
# Returns a string for the id attribute of a html element for the given content
|
|
@@ -16,6 +15,11 @@ module Alchemy
|
|
|
16
15
|
"#{c.essence_type.demodulize.underscore}_#{c.id}"
|
|
17
16
|
end
|
|
18
17
|
|
|
18
|
+
# Returns a jquery selector string of form field ids from given contents
|
|
19
|
+
def contents_form_field_ids_string(contents)
|
|
20
|
+
contents.collect { |c| "##{c.form_field_id}" }.join(', ')
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
# Renders the name of elements content or the default name defined in elements.yml
|
|
20
24
|
def render_content_name(content)
|
|
21
25
|
if content.blank?
|
|
@@ -8,31 +8,6 @@ module Alchemy
|
|
|
8
8
|
include Alchemy::Admin::ContentsHelper
|
|
9
9
|
include Alchemy::Admin::EssencesHelper
|
|
10
10
|
|
|
11
|
-
# Returns an Array for essence_text_editor select options_for_select.
|
|
12
|
-
def elements_by_name_for_select(name, options={})
|
|
13
|
-
defaults = {
|
|
14
|
-
:grouped_by_page => true,
|
|
15
|
-
:from_page => :all
|
|
16
|
-
}
|
|
17
|
-
options = defaults.merge(options)
|
|
18
|
-
elements = all_elements_by_name(
|
|
19
|
-
name,
|
|
20
|
-
:from_page => options[:from_page]
|
|
21
|
-
)
|
|
22
|
-
if options[:grouped_by_page] && options[:from_page] == :all
|
|
23
|
-
elements_for_options = {}
|
|
24
|
-
pages = elements.collect(&:page).compact.uniq
|
|
25
|
-
pages.sort { |x, y| x.name <=> y.name }.each do |page|
|
|
26
|
-
page_elements = page.elements.select { |e| e.name == name }
|
|
27
|
-
elements_for_options[page.name] = page_elements.map { |pe| [pe.preview_text, pe.id.to_s] }
|
|
28
|
-
end
|
|
29
|
-
else
|
|
30
|
-
elements_for_options = elements.map { |e| [e.preview_text, e.id.to_s] }
|
|
31
|
-
elements_for_options = [''] + elements_for_options
|
|
32
|
-
end
|
|
33
|
-
return elements_for_options
|
|
34
|
-
end
|
|
35
|
-
|
|
36
11
|
# Renders the element editor partial
|
|
37
12
|
def render_editor(element)
|
|
38
13
|
render_element(element, :editor)
|
|
@@ -73,7 +48,7 @@ module Alchemy
|
|
|
73
48
|
return [] if elements.nil?
|
|
74
49
|
options = elements.collect do |e|
|
|
75
50
|
[
|
|
76
|
-
|
|
51
|
+
Element.display_name_for(e['name']),
|
|
77
52
|
e['name']
|
|
78
53
|
]
|
|
79
54
|
end
|
|
@@ -114,32 +89,29 @@ module Alchemy
|
|
|
114
89
|
]
|
|
115
90
|
else
|
|
116
91
|
[
|
|
117
|
-
|
|
92
|
+
Element.display_name_for(e['name']),
|
|
118
93
|
e[object_method] + (cell ? "##{cell['name']}" : "")
|
|
119
94
|
]
|
|
120
95
|
end
|
|
121
96
|
end
|
|
122
97
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
else
|
|
141
|
-
nil
|
|
142
|
-
end
|
|
98
|
+
# This helper loads all elements from page that have EssenceSelects in them.
|
|
99
|
+
#
|
|
100
|
+
# It returns a javascript function that replaces all editor partials of this elements.
|
|
101
|
+
#
|
|
102
|
+
# We need this while updating, creating or trashing an element,
|
|
103
|
+
# because another element on the same page could have a element selector in it.
|
|
104
|
+
#
|
|
105
|
+
# In cases like this one wants Ember.js databinding!
|
|
106
|
+
#
|
|
107
|
+
def update_essence_select_elements(page, element)
|
|
108
|
+
elements = page.elements.not_trashed.joins(:contents)
|
|
109
|
+
.where("alchemy_contents.element_id != #{element.id}")
|
|
110
|
+
.where("alchemy_contents.essence_type" => "Alchemy::EssenceSelect")
|
|
111
|
+
return if elements.blank?
|
|
112
|
+
elements.collect do |element|
|
|
113
|
+
render 'alchemy/admin/elements/refresh_editor', element: element
|
|
114
|
+
end.join.html_safe
|
|
143
115
|
end
|
|
144
116
|
|
|
145
117
|
end
|
|
@@ -43,22 +43,6 @@ module Alchemy
|
|
|
43
43
|
return_string
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
# Renders the Content editor partial from the given Element by position (e.g. 1).
|
|
47
|
-
# For options see -> render_essence
|
|
48
|
-
def render_essence_editor_by_position(element, position, options = {})
|
|
49
|
-
ActiveSupport::Deprecation.warn 'Alchemy CMS: render_essence_editor_by_position is not supported anymore and will be removed.'
|
|
50
|
-
if element.blank?
|
|
51
|
-
warning('Element is nil')
|
|
52
|
-
return ""
|
|
53
|
-
end
|
|
54
|
-
content = element.contents.find_by_position(position)
|
|
55
|
-
if content.nil?
|
|
56
|
-
render_missing_content(element, position, options)
|
|
57
|
-
else
|
|
58
|
-
render_essence_editor(content, options)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
46
|
# Renders the Content editor partial found in views/contents/ for the content with name inside the passed Element.
|
|
63
47
|
# For options see -> render_essence
|
|
64
48
|
#
|
|
@@ -121,8 +105,31 @@ module Alchemy
|
|
|
121
105
|
end
|
|
122
106
|
end
|
|
123
107
|
|
|
108
|
+
# Returns all public pages from current language as an option tags string suitable or the Rails +select_tag+ helper.
|
|
109
|
+
#
|
|
110
|
+
# @param [Array]
|
|
111
|
+
# A collection of pages so it only returns these pages and does not query the database.
|
|
112
|
+
# @param [String]
|
|
113
|
+
# Pass a +Page#name+ or +Page#id+ as selected item to the +options_for_select+ helper.
|
|
114
|
+
# @param [String]
|
|
115
|
+
# Used as prompt message in the select tag
|
|
116
|
+
# @param [Symbol]
|
|
117
|
+
# Method that is called on the page object to get the value that is passed with the params of the form.
|
|
118
|
+
#
|
|
119
|
+
def pages_for_select(pages = nil, selected = nil, prompt = "Choose page", page_attribute = :id)
|
|
120
|
+
values = [[_t(prompt), ""]]
|
|
121
|
+
pages ||= begin
|
|
122
|
+
nested = true
|
|
123
|
+
Page.with_language(session[:language_id]).published.order(:lft)
|
|
124
|
+
end
|
|
125
|
+
values += pages_attributes_for_select(pages, page_attribute, nested)
|
|
126
|
+
options_for_select(values, selected.to_s)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Renders the missing content partial
|
|
130
|
+
#
|
|
124
131
|
def render_missing_content(element, name, options)
|
|
125
|
-
render
|
|
132
|
+
render 'alchemy/admin/contents/missing', {element: element, name: name, options: options}
|
|
126
133
|
end
|
|
127
134
|
|
|
128
135
|
def essence_picture_thumbnail(content, options)
|
|
@@ -145,6 +152,41 @@ module Alchemy
|
|
|
145
152
|
)
|
|
146
153
|
end
|
|
147
154
|
|
|
155
|
+
private
|
|
156
|
+
|
|
157
|
+
# Returns an Array with page attributes for select options
|
|
158
|
+
#
|
|
159
|
+
# @param [Array]
|
|
160
|
+
# The pages
|
|
161
|
+
# @param [String || Symbol]
|
|
162
|
+
# The attribute that is used as value
|
|
163
|
+
# @param [Boolean] (false)
|
|
164
|
+
# Should the name be indented or not
|
|
165
|
+
#
|
|
166
|
+
def pages_attributes_for_select(pages, page_attribute, indent = false)
|
|
167
|
+
pages.map do |page|
|
|
168
|
+
[
|
|
169
|
+
page_name_attribute_for_select(page, indent),
|
|
170
|
+
page.send(page_attribute).to_s
|
|
171
|
+
]
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Returns the page name for pages_for_select helper
|
|
176
|
+
#
|
|
177
|
+
# @param [Alchemy::Page]
|
|
178
|
+
# The page
|
|
179
|
+
# @param [Boolean] (false)
|
|
180
|
+
# Should the page be indented or not
|
|
181
|
+
#
|
|
182
|
+
def page_name_attribute_for_select(page, indent = false)
|
|
183
|
+
if indent
|
|
184
|
+
(" " * (page.level - 1) + page.name).html_safe
|
|
185
|
+
else
|
|
186
|
+
page.name
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
148
190
|
end
|
|
149
191
|
end
|
|
150
192
|
end
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
module Alchemy
|
|
2
|
+
module Admin
|
|
3
|
+
|
|
4
|
+
# This module contains helper methods for rendering the admin navigation.
|
|
5
|
+
#
|
|
6
|
+
module NavigationHelper
|
|
7
|
+
|
|
8
|
+
# Renders one admin main navigation entry
|
|
9
|
+
#
|
|
10
|
+
# @param [Hash] alchemy_module
|
|
11
|
+
# The Hash representing a Alchemy module
|
|
12
|
+
#
|
|
13
|
+
def alchemy_main_navigation_entry(alchemy_module)
|
|
14
|
+
render(
|
|
15
|
+
'alchemy/admin/partials/main_navigation_entry',
|
|
16
|
+
alchemy_module: alchemy_module.stringify_keys,
|
|
17
|
+
navigation: module_main_navigation(alchemy_module)
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Renders the subnavigation from current module
|
|
22
|
+
#
|
|
23
|
+
# We find the module from current controller and index action.
|
|
24
|
+
#
|
|
25
|
+
def admin_subnavigation
|
|
26
|
+
if current_alchemy_module.present?
|
|
27
|
+
render(
|
|
28
|
+
'alchemy/admin/partials/sub_navigation',
|
|
29
|
+
entries: current_sub_navigation
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Used for checking the main navi permissions
|
|
35
|
+
#
|
|
36
|
+
def navigate_module(navigation)
|
|
37
|
+
[
|
|
38
|
+
navigation['action'].to_sym,
|
|
39
|
+
navigation['controller'].gsub(/^\//, '').gsub(/\//, '_').to_sym
|
|
40
|
+
]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# CSS classes for main navigation entry.
|
|
44
|
+
#
|
|
45
|
+
def main_navigation_css_classes(navigation)
|
|
46
|
+
[
|
|
47
|
+
'main_navi_entry',
|
|
48
|
+
admin_mainnavi_active?(navigation) ? 'active' : nil
|
|
49
|
+
].compact.join(' ')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns true if given navi entry is in params controller and action
|
|
53
|
+
#
|
|
54
|
+
# == Example
|
|
55
|
+
# <%= entry_active?({controller: 'admin/users', action: 'index'}) %>
|
|
56
|
+
#
|
|
57
|
+
# @param [Hash]
|
|
58
|
+
# A Alchemy module definition navigation entry
|
|
59
|
+
#
|
|
60
|
+
def entry_active?(entry)
|
|
61
|
+
is_entry_controller_active?(entry) && is_entry_action_active?(entry)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Returns url for given Alchemy module.
|
|
65
|
+
#
|
|
66
|
+
# If the module is inside an engine it calls the +url_for+ helper on the engines routing proxy.
|
|
67
|
+
#
|
|
68
|
+
# If the module is inside the host rails app it calls the +url_for+ helper on the main_app routing proxy.
|
|
69
|
+
#
|
|
70
|
+
# @param [Hash]
|
|
71
|
+
# A Alchemy module definition
|
|
72
|
+
#
|
|
73
|
+
def url_for_module(alchemy_module)
|
|
74
|
+
route_from_engine_or_main_app(
|
|
75
|
+
alchemy_module['engine_name'],
|
|
76
|
+
url_options_for_module(alchemy_module)
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns url for given Alchemy module sub navigation entry.
|
|
81
|
+
#
|
|
82
|
+
# If the module is inside an engine it calls the +url_for+ helper on the engines routing proxy.
|
|
83
|
+
#
|
|
84
|
+
# If the module is inside the host rails app it calls the +url_for+ helper on the main_app routing proxy.
|
|
85
|
+
#
|
|
86
|
+
# @param [Hash]
|
|
87
|
+
# A Alchemy module sub navigation definition
|
|
88
|
+
#
|
|
89
|
+
def url_for_module_sub_navigation(navigation)
|
|
90
|
+
alchemy_module = module_definition_for(navigation)
|
|
91
|
+
route_from_engine_or_main_app(
|
|
92
|
+
alchemy_module['engine_name'],
|
|
93
|
+
url_options_for_navigation_entry(navigation)
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
# Calls +url_for+ helper on engine if present or on host app.
|
|
100
|
+
#
|
|
101
|
+
# @param [String]
|
|
102
|
+
# A name of an engine
|
|
103
|
+
# @param [Hash]
|
|
104
|
+
# url options hash passed to +url_for+ helper
|
|
105
|
+
#
|
|
106
|
+
def route_from_engine_or_main_app(engine_name, url_options)
|
|
107
|
+
if engine_name.present?
|
|
108
|
+
eval(engine_name).url_for(url_options)
|
|
109
|
+
else
|
|
110
|
+
main_app.url_for(url_options)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Returns a url options hash for given Alchemy module.
|
|
115
|
+
#
|
|
116
|
+
# @param [Hash]
|
|
117
|
+
# A Alchemy module definition
|
|
118
|
+
#
|
|
119
|
+
def url_options_for_module(alchemy_module)
|
|
120
|
+
url_options_for_navigation_entry(module_main_navigation(alchemy_module))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Returns a url options hash for given navigation entry.
|
|
124
|
+
#
|
|
125
|
+
# @param [Hash]
|
|
126
|
+
# A Alchemy module navigation entry
|
|
127
|
+
#
|
|
128
|
+
def url_options_for_navigation_entry(entry)
|
|
129
|
+
entry.stringify_keys!
|
|
130
|
+
{
|
|
131
|
+
controller: entry['controller'],
|
|
132
|
+
action: entry['action'],
|
|
133
|
+
only_path: true
|
|
134
|
+
}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Retrieves the current Alchemy module from controller and index action.
|
|
138
|
+
#
|
|
139
|
+
def current_alchemy_module
|
|
140
|
+
module_definition_for(controller: params[:controller], action: 'index')
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Returns the sub navigation for current Alchemy module.
|
|
144
|
+
#
|
|
145
|
+
def current_sub_navigation
|
|
146
|
+
module_sub_navigation(module_main_navigation(current_alchemy_module))
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Returns navigation entries from given module.
|
|
150
|
+
#
|
|
151
|
+
def module_main_navigation(alchemy_module)
|
|
152
|
+
alchemy_module.fetch('navigation', {}).stringify_keys
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Returns sub navigation entries from given module.
|
|
156
|
+
#
|
|
157
|
+
def module_sub_navigation(alchemy_module)
|
|
158
|
+
alchemy_module.fetch('sub_navigation', []).map(&:stringify_keys)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Returns nested navigation entries for given module.
|
|
162
|
+
#
|
|
163
|
+
def module_nested_navigation(alchemy_module)
|
|
164
|
+
alchemy_module.fetch('nested', []).map(&:stringify_keys)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Returns true if the current controller and action is in a modules navigation definition.
|
|
168
|
+
#
|
|
169
|
+
def admin_mainnavi_active?(main_navigation)
|
|
170
|
+
main_navigation.stringify_keys!
|
|
171
|
+
# Has the given navigation entry a active sub navigation?
|
|
172
|
+
has_active_entry?(module_sub_navigation(main_navigation)) or
|
|
173
|
+
# Has the given navigation entry a active nested navigation?
|
|
174
|
+
has_active_entry?(module_nested_navigation(main_navigation)) or
|
|
175
|
+
# Is the navigation entry active?
|
|
176
|
+
entry_active?(main_navigation)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Returns true if the given entry's controller is current controller
|
|
180
|
+
#
|
|
181
|
+
def is_entry_controller_active?(entry)
|
|
182
|
+
entry['controller'].gsub(/^\//, '') == params[:controller]
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Returns true if the given entry's action is current controllers action
|
|
186
|
+
#
|
|
187
|
+
# Also checks if given entry has a +nested_actions+ key, if so it checks if one of them is current controller's action
|
|
188
|
+
#
|
|
189
|
+
def is_entry_action_active?(entry)
|
|
190
|
+
entry['action'] == params[:action] || entry['nested_actions'].to_a.include?(params[:action])
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Returns true if an entry of given entries is active.
|
|
194
|
+
#
|
|
195
|
+
# @param [Array]
|
|
196
|
+
# Alchemy module navigation entries.
|
|
197
|
+
#
|
|
198
|
+
def has_active_entry?(entries)
|
|
199
|
+
!entries.detect { |entry| entry_active?(entry) }.nil?
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
@@ -3,88 +3,29 @@ module Alchemy
|
|
|
3
3
|
module PagesHelper
|
|
4
4
|
include Alchemy::BaseHelper
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
init = init.collect { |key, value| "#{key} : #{value.to_json}" }.join(', ')
|
|
15
|
-
setup = "init.setup = #{Alchemy::Tinymce.setup};" if Alchemy::Tinymce.setup
|
|
16
|
-
tinymce_javascript_string = "
|
|
17
|
-
<script type='text/javascript'>
|
|
18
|
-
jQuery(function($) {
|
|
19
|
-
if (typeof(Alchemy) !== 'object') { Alchemy = {}; };
|
|
20
|
-
Alchemy.Tinymce = {
|
|
21
|
-
init : function(callback) {
|
|
22
|
-
var init = { #{init} };
|
|
23
|
-
var spinner = Alchemy.Spinner.small();
|
|
24
|
-
$('.tinymce_container').prepend(spinner.spin().el);
|
|
25
|
-
init.mode = 'specific_textareas';
|
|
26
|
-
init.editor_selector = 'default_tinymce';
|
|
27
|
-
init.plugins = '#{Alchemy::Tinymce.plugins.join(',')}';
|
|
28
|
-
init.language = '#{::I18n.locale.to_s.split('-')[0].downcase }';
|
|
29
|
-
init.init_instance_callback = function(inst) {
|
|
30
|
-
$('#' + inst.editorId).prev('.spinner').remove();
|
|
31
|
-
}
|
|
32
|
-
if (callback)
|
|
33
|
-
init.oninit = callback;
|
|
34
|
-
#{setup}
|
|
35
|
-
tinymce.init(init);
|
|
36
|
-
},
|
|
37
|
-
addEditor : function(dom_id) {
|
|
38
|
-
tinymce.execCommand('mceAddControl', true, dom_id);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
</script>"
|
|
43
|
-
if Alchemy::Tinymce.custom_config_contents.any?
|
|
44
|
-
(tinymce_javascript_string + custom_tinymce_javascript_tags).html_safe
|
|
6
|
+
# Used for rendering the folder link in +Admin::Pages#index+ sitemap.
|
|
7
|
+
#
|
|
8
|
+
def sitemap_folder_link(page)
|
|
9
|
+
if page.folded?(current_user.id)
|
|
10
|
+
css_class = 'folded'
|
|
11
|
+
title = _t('Show childpages')
|
|
45
12
|
else
|
|
46
|
-
|
|
13
|
+
css_class = 'collapsed'
|
|
14
|
+
title = _t('Hide childpages')
|
|
47
15
|
end
|
|
16
|
+
link_to(
|
|
17
|
+
'',
|
|
18
|
+
alchemy.fold_admin_page_path(page),
|
|
19
|
+
remote: true,
|
|
20
|
+
method: :post,
|
|
21
|
+
class: "page_folder #{css_class} spinner",
|
|
22
|
+
title: title,
|
|
23
|
+
id: "fold_button_#{page.id}"
|
|
24
|
+
)
|
|
48
25
|
end
|
|
49
26
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<script type='text/javascript'>
|
|
53
|
-
jQuery(function($) {
|
|
54
|
-
Alchemy.Tinymce.customInits = [];"
|
|
55
|
-
custom_config_contents = Alchemy::Tinymce.custom_config_contents
|
|
56
|
-
content_names = custom_config_contents.collect{ |c| c['name'] }
|
|
57
|
-
if content_names.uniq.length != content_names.length
|
|
58
|
-
raise TinymceError, "Duplicated content names with tinymce setting in elements.yml found. Please rename these contents."
|
|
59
|
-
end
|
|
60
|
-
custom_config_contents.each do |content|
|
|
61
|
-
next unless content['settings']['tinymce']
|
|
62
|
-
config = Alchemy::Tinymce.init.merge(content['settings']['tinymce'].symbolize_keys)
|
|
63
|
-
config = config.collect { |key, value| "#{key} : #{value.to_json}" }.join(', ')
|
|
64
|
-
custom_config_string += "
|
|
65
|
-
Alchemy.Tinymce.customInits.push(function(callback) {
|
|
66
|
-
var init = { #{config} };
|
|
67
|
-
init.mode = 'specific_textareas';
|
|
68
|
-
init.editor_selector = /custom_tinymce #{Regexp.escape(content['name'])}/;
|
|
69
|
-
init.plugins = '#{Alchemy::Tinymce.plugins.join(',')}';
|
|
70
|
-
init.language = '#{::I18n.locale.to_s.split('-')[0].downcase }';
|
|
71
|
-
init.init_instance_callback = function(inst) {
|
|
72
|
-
var $this = $('#' + inst.editorId);
|
|
73
|
-
var parent = $this.parents('.element_editor');
|
|
74
|
-
parent.find('.spinner').remove();
|
|
75
|
-
inst.onChange.add(function (ed, l) {
|
|
76
|
-
Alchemy.setElementDirty(parent);
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
tinymce.init(init);
|
|
80
|
-
});"
|
|
81
|
-
end
|
|
82
|
-
custom_config_string += "
|
|
83
|
-
});
|
|
84
|
-
</script>"
|
|
85
|
-
custom_config_string.html_safe
|
|
86
|
-
end
|
|
87
|
-
|
|
27
|
+
# Returns options tags for the screen sizes select in page edit view.
|
|
28
|
+
#
|
|
88
29
|
def preview_sizes_for_select
|
|
89
30
|
options_for_select([
|
|
90
31
|
'auto',
|
|
@@ -101,7 +42,9 @@ module Alchemy
|
|
|
101
42
|
#
|
|
102
43
|
def combined_page_status(page)
|
|
103
44
|
page.status.map do |state, value|
|
|
104
|
-
|
|
45
|
+
next if state == :locked
|
|
46
|
+
val = content_tag(:span, '', class: page.send(state) ? "page_status #{state}" : "page_status not_#{state}")
|
|
47
|
+
val += page.status_title(state)
|
|
105
48
|
end.delete_if(&:blank?).join("<br>").html_safe
|
|
106
49
|
end
|
|
107
50
|
|