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.
Files changed (246) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +14 -0
  3. data/.travis.yml +1 -1
  4. data/Gemfile +7 -6
  5. data/README.md +15 -5
  6. data/alchemy_cms.gemspec +3 -2
  7. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +9 -17
  8. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +70 -0
  9. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +80 -0
  10. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +43 -19
  11. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +3 -1
  12. data/app/assets/javascripts/alchemy/alchemy.js +4 -2
  13. data/app/assets/javascripts/alchemy/alchemy.onload.js.coffee +1 -1
  14. data/app/assets/javascripts/alchemy/alchemy.spinner.js.coffee +14 -0
  15. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee.erb +96 -0
  16. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +22 -0
  17. data/app/assets/javascripts/alchemy/alchemy.windows.js.coffee +28 -17
  18. data/app/assets/stylesheets/alchemy/base.scss +6 -0
  19. data/app/assets/stylesheets/alchemy/elements.scss +2 -28
  20. data/app/assets/stylesheets/alchemy/errors.scss +1 -1
  21. data/app/assets/stylesheets/alchemy/menubar.css.scss +2 -0
  22. data/app/assets/stylesheets/alchemy/sitemap.scss +21 -34
  23. data/app/assets/stylesheets/alchemy/tables.scss +13 -3
  24. data/app/controllers/alchemy/admin/attachments_controller.rb +10 -5
  25. data/app/controllers/alchemy/admin/base_controller.rb +19 -0
  26. data/app/controllers/alchemy/admin/contents_controller.rb +1 -4
  27. data/app/controllers/alchemy/admin/dashboard_controller.rb +2 -1
  28. data/app/controllers/alchemy/admin/elements_controller.rb +1 -1
  29. data/app/controllers/alchemy/admin/essence_files_controller.rb +1 -1
  30. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +70 -56
  31. data/app/controllers/alchemy/admin/pages_controller.rb +37 -114
  32. data/app/controllers/alchemy/admin/pictures_controller.rb +5 -12
  33. data/app/controllers/alchemy/admin/resources_controller.rb +3 -1
  34. data/app/controllers/alchemy/admin/trash_controller.rb +1 -1
  35. data/app/controllers/alchemy/attachments_controller.rb +1 -1
  36. data/app/controllers/alchemy/base_controller.rb +3 -15
  37. data/app/controllers/alchemy/messages_controller.rb +4 -10
  38. data/app/controllers/alchemy/pages_controller.rb +6 -6
  39. data/app/controllers/alchemy/passwords_controller.rb +1 -1
  40. data/app/controllers/alchemy/user_sessions_controller.rb +1 -1
  41. data/app/helpers/alchemy/admin/base_helper.rb +49 -230
  42. data/app/helpers/alchemy/admin/contents_helper.rb +5 -1
  43. data/app/helpers/alchemy/admin/elements_helper.rb +19 -47
  44. data/app/helpers/alchemy/admin/essences_helper.rb +59 -17
  45. data/app/helpers/alchemy/admin/navigation_helper.rb +204 -0
  46. data/app/helpers/alchemy/admin/pages_helper.rb +22 -79
  47. data/app/helpers/alchemy/admin/pictures_helper.rb +1 -1
  48. data/app/helpers/alchemy/admin/tags_helper.rb +42 -0
  49. data/app/helpers/alchemy/base_helper.rb +0 -11
  50. data/app/helpers/alchemy/elements_helper.rb +48 -25
  51. data/app/helpers/alchemy/essences_helper.rb +0 -20
  52. data/app/helpers/alchemy/pages_helper.rb +18 -14
  53. data/app/helpers/alchemy/url_helper.rb +1 -0
  54. data/app/mailers/alchemy/messages.rb +4 -6
  55. data/app/models/alchemy/attachment.rb +3 -0
  56. data/app/models/alchemy/cell.rb +33 -35
  57. data/app/models/alchemy/content.rb +20 -111
  58. data/app/models/alchemy/content/factory.rb +188 -0
  59. data/app/models/alchemy/element.rb +51 -200
  60. data/app/models/alchemy/element/definitions.rb +52 -0
  61. data/app/models/alchemy/element/presenters.rb +87 -0
  62. data/app/models/alchemy/essence_date.rb +1 -1
  63. data/app/models/alchemy/essence_file.rb +6 -7
  64. data/app/models/alchemy/essence_picture.rb +19 -4
  65. data/app/models/alchemy/message.rb +18 -14
  66. data/app/models/alchemy/page.rb +120 -214
  67. data/app/models/alchemy/page/elements.rb +145 -36
  68. data/app/models/alchemy/page/natures.rb +90 -0
  69. data/app/models/alchemy/page/scopes.rb +93 -0
  70. data/app/models/alchemy/page/users.rb +25 -0
  71. data/app/models/alchemy/picture.rb +15 -0
  72. data/app/models/alchemy/site.rb +15 -1
  73. data/app/models/alchemy/site/layout.rb +38 -0
  74. data/app/models/alchemy/user.rb +13 -3
  75. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +7 -7
  76. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +8 -8
  77. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +1 -16
  78. data/app/views/alchemy/admin/attachments/destroy.js.erb +1 -4
  79. data/app/views/alchemy/admin/contents/create.js.erb +1 -1
  80. data/app/views/alchemy/admin/dashboard/index.html.erb +14 -13
  81. data/app/views/alchemy/admin/elements/_element_head.html.erb +7 -7
  82. data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +10 -0
  83. data/app/views/alchemy/admin/elements/create.js.erb +44 -44
  84. data/app/views/alchemy/admin/elements/fold.js.erb +22 -26
  85. data/app/views/alchemy/admin/elements/trash.js.erb +1 -1
  86. data/app/views/alchemy/admin/elements/update.js.erb +22 -25
  87. data/app/views/alchemy/admin/essence_files/assign.js.erb +8 -3
  88. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +14 -12
  89. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +22 -39
  90. data/app/views/alchemy/admin/pages/_page.html.erb +73 -80
  91. data/app/views/alchemy/admin/pages/destroy.js.erb +2 -2
  92. data/app/views/alchemy/admin/pages/edit.html.erb +21 -18
  93. data/app/views/alchemy/admin/pages/fold.js.erb +1 -0
  94. data/app/views/alchemy/admin/pages/info.html.erb +32 -0
  95. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +11 -13
  96. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +20 -20
  97. data/app/views/alchemy/admin/partials/_sub_navigation.html.erb +8 -0
  98. data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +25 -0
  99. data/app/views/alchemy/admin/partials/_upload_form.html.erb +15 -15
  100. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +39 -39
  101. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +10 -10
  102. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +1 -16
  103. data/app/views/alchemy/admin/resources/destroy.js.erb +1 -1
  104. data/app/views/alchemy/base/500.html.erb +1 -1
  105. data/app/views/alchemy/base/permission_denied.js.erb +1 -1
  106. data/app/views/alchemy/base/redirect.js.erb +1 -1
  107. data/app/views/alchemy/essences/_essence_link_editor.html.erb +1 -1
  108. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +1 -1
  109. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +1 -1
  110. data/app/views/alchemy/essences/_essence_text_editor.html.erb +1 -1
  111. data/app/views/alchemy/essences/{_essence_picture_tools.html.erb → shared/_essence_picture_tools.html.erb} +5 -5
  112. data/app/views/alchemy/essences/{_linkable_essence_tools.html.erb → shared/_linkable_essence_tools.html.erb} +0 -0
  113. data/app/views/alchemy/messages/contact_form_mail.de.text.erb +12 -0
  114. data/app/views/alchemy/messages/contact_form_mail.en.text.erb +12 -0
  115. data/app/views/alchemy/notifications/reset_password_instructions.de.text.erb +1 -1
  116. data/app/views/alchemy/notifications/reset_password_instructions.en.text.erb +2 -2
  117. data/app/views/alchemy/pages/sitemap.xml.erb +3 -5
  118. data/app/views/alchemy/user_sessions/leave.html.erb +1 -1
  119. data/app/views/layouts/alchemy/admin.html.erb +4 -2
  120. data/app/views/layouts/alchemy/sitemap.xml.erb +1 -1
  121. data/bin/alchemy +7 -13
  122. data/config/alchemy/config.yml +1 -0
  123. data/config/authorization_rules.rb +2 -3
  124. data/config/initializers/dragonfly.rb +2 -0
  125. data/config/locales/alchemy.de.yml +8 -9
  126. data/config/locales/alchemy.en.yml +7 -4
  127. data/config/routes.rb +3 -0
  128. data/db/migrate/{20130214233001_alchemy_two_point_five.rb → 20130827094554_alchemy_two_point_six.rb} +29 -6
  129. data/lib/alchemy/auth/engine.rb +9 -0
  130. data/lib/alchemy/capistrano.rb +37 -12
  131. data/lib/alchemy/config.rb +48 -35
  132. data/lib/alchemy/engine.rb +35 -6
  133. data/lib/alchemy/essence.rb +25 -29
  134. data/lib/alchemy/ferret/search.rb +86 -0
  135. data/lib/alchemy/{scoped_pagination_url_helper.rb → kaminari/scoped_pagination_url_helper.rb} +0 -0
  136. data/lib/alchemy/logger.rb +3 -4
  137. data/lib/alchemy/page_layout.rb +124 -55
  138. data/lib/alchemy/resource.rb +0 -10
  139. data/lib/alchemy/resources_helper.rb +0 -5
  140. data/lib/alchemy/seeder.rb +1 -32
  141. data/lib/alchemy/shell.rb +6 -1
  142. data/lib/alchemy/tinymce.rb +41 -32
  143. data/lib/alchemy/upgrader.rb +3 -1
  144. data/lib/alchemy/upgrader/two_point_five.rb +15 -8
  145. data/lib/alchemy/upgrader/two_point_one.rb +10 -10
  146. data/lib/alchemy/upgrader/two_point_two.rb +96 -51
  147. data/lib/alchemy/version.rb +1 -1
  148. data/lib/alchemy_cms.rb +5 -46
  149. data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +1 -1
  150. data/lib/rails/generators/alchemy/devise/devise_generator.rb +9 -4
  151. data/lib/rails/generators/alchemy/essence/essence_generator.rb +7 -6
  152. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -1
  153. data/lib/rails/generators/alchemy/scaffold/files/_standard.html.erb +1 -0
  154. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +1 -0
  155. data/lib/rails/generators/alchemy/site_layouts/site_layouts_generator.rb +23 -0
  156. data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.erb +1 -0
  157. data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.haml +1 -0
  158. data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.slim +1 -0
  159. data/lib/rails/templates/alchemy.rb +2 -2
  160. data/lib/tasks/alchemy/db.rake +3 -1
  161. data/lib/tasks/alchemy/tidy.rake +82 -0
  162. data/lib/tasks/alchemy/upgrade.rake +2 -1
  163. data/spec/controllers/admin/attachments_controller_spec.rb +124 -0
  164. data/spec/controllers/admin/base_controller_spec.rb +35 -0
  165. data/spec/controllers/admin/clipboard_controller_spec.rb +1 -1
  166. data/spec/controllers/admin/contents_controller_spec.rb +17 -26
  167. data/spec/controllers/admin/dashboard_controller_spec.rb +121 -0
  168. data/spec/controllers/admin/elements_controller_spec.rb +1 -1
  169. data/spec/controllers/admin/essence_files_controller_spec.rb +67 -0
  170. data/spec/controllers/admin/essence_pictures_controller_spec.rb +161 -0
  171. data/spec/controllers/admin/languages_controller_spec.rb +1 -1
  172. data/spec/controllers/admin/layoutpages_controller_spec.rb +28 -0
  173. data/spec/controllers/admin/pages_controller_spec.rb +164 -118
  174. data/spec/controllers/admin/pictures_controller_spec.rb +89 -0
  175. data/spec/controllers/admin/trash_controller_spec.rb +21 -31
  176. data/spec/controllers/admin/users_controller_spec.rb +114 -85
  177. data/spec/controllers/attachments_controller_spec.rb +6 -2
  178. data/spec/controllers/base_controller_spec.rb +22 -0
  179. data/spec/controllers/elements_controller_spec.rb +1 -1
  180. data/spec/controllers/messages_controller_spec.rb +200 -0
  181. data/spec/controllers/pictures_controller_spec.rb +1 -1
  182. data/spec/controllers/user_sessions_controller_spec.rb +7 -6
  183. data/spec/controllers/users_controller_spec.rb +2 -2
  184. data/spec/dummy/config/alchemy/cells.yml +2 -0
  185. data/spec/dummy/config/application.rb +19 -8
  186. data/spec/dummy/db/migrate/{20130214233001_alchemy_two_point_five.rb → 20130827094554_alchemy_two_point_six.rb} +29 -6
  187. data/spec/dummy/db/schema.rb +1 -1
  188. data/spec/fast_specs.rb +15 -0
  189. data/spec/helpers/admin/base_helper_spec.rb +53 -34
  190. data/spec/helpers/admin/contents_helper_spec.rb +15 -7
  191. data/spec/helpers/admin/elements_helper_spec.rb +79 -34
  192. data/spec/helpers/admin/essences_helper_spec.rb +45 -31
  193. data/spec/helpers/admin/navigation_helper_spec.rb +204 -0
  194. data/spec/helpers/admin/pages_helper_spec.rb +25 -15
  195. data/spec/helpers/admin/tags_helper_spec.rb +62 -2
  196. data/spec/helpers/elements_helper_spec.rb +202 -138
  197. data/spec/helpers/pages_helper_spec.rb +48 -0
  198. data/spec/helpers/url_helper_spec.rb +7 -0
  199. data/spec/libraries/config_spec.rb +110 -3
  200. data/spec/libraries/essence_spec.rb +29 -9
  201. data/spec/libraries/page_layout_spec.rb +134 -0
  202. data/spec/libraries/resource_spec.rb +3 -16
  203. data/spec/libraries/resources_helper_spec.rb +4 -8
  204. data/spec/libraries/shell_spec.rb +1 -0
  205. data/spec/libraries/tinymce_spec.rb +61 -0
  206. data/spec/mailers/messages_spec.rb +23 -0
  207. data/spec/models/attachment_spec.rb +45 -0
  208. data/spec/models/cell_spec.rb +62 -9
  209. data/spec/models/content_spec.rb +110 -28
  210. data/spec/models/element_spec.rb +275 -253
  211. data/spec/models/essence_date_spec.rb +25 -0
  212. data/spec/models/essence_file_spec.rb +23 -0
  213. data/spec/models/essence_html_spec.rb +13 -0
  214. data/spec/models/essence_picture_spec.rb +16 -0
  215. data/spec/models/essence_text_spec.rb +29 -0
  216. data/spec/models/language_spec.rb +34 -0
  217. data/spec/models/message_spec.rb +43 -0
  218. data/spec/models/page_spec.rb +726 -567
  219. data/spec/models/picture_spec.rb +98 -0
  220. data/spec/models/site_spec.rb +60 -2
  221. data/spec/models/tag_spec.rb +31 -0
  222. data/spec/models/user_spec.rb +4 -4
  223. data/spec/spec_helper.rb +49 -58
  224. data/spec/support/alchemy/controller_helpers.rb +35 -0
  225. data/spec/support/alchemy/{specs_helpers.rb → integration_helpers.rb} +4 -8
  226. data/spec/{factories.rb → support/factories.rb} +11 -1
  227. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +2 -8
  228. metadata +166 -106
  229. data/Guardfile +0 -16
  230. data/app/assets/javascripts/alchemy/alchemy.dirty.js +0 -93
  231. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +0 -122
  232. data/app/models/alchemy/tree_node.rb +0 -4
  233. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -3
  234. data/app/views/alchemy/admin/partials/_sub_navigation_tab.html.erb +0 -8
  235. data/app/views/alchemy/messages/contact_form_mail.text.erb +0 -12
  236. data/config/initializers/kaminari_config.rb +0 -9
  237. data/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +0 -21
  238. data/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +0 -11
  239. data/lib/alchemy/auth_engine.rb +0 -7
  240. data/lib/alchemy/authentication_helpers.rb +0 -9
  241. data/lib/alchemy/ferret_search.rb +0 -84
  242. data/lib/extensions/array.rb +0 -25
  243. data/lib/extensions/hash.rb +0 -34
  244. data/spec/dummy/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +0 -21
  245. data/spec/dummy/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +0 -11
  246. data/spec/models/page_layout_spec.rb +0 -60
@@ -12,14 +12,7 @@ module Alchemy
12
12
  @size = params[:size].present? ? params[:size] : 'medium'
13
13
  @pictures = Picture.scoped
14
14
  @pictures = @pictures.tagged_with(params[:tagged_with]) if params[:tagged_with].present?
15
- case params[:filter]
16
- when 'recent'
17
- @pictures = @pictures.recent
18
- when 'last_upload'
19
- @pictures = @pictures.last_upload
20
- when 'without_tag'
21
- @pictures = @pictures.where("cached_tag_list IS NULL OR cached_tag_list = ''")
22
- end
15
+ @pictures = @pictures.filtered_by(params[:filter]) if params[:filter]
23
16
  @pictures = @pictures.find_paginated(params, pictures_per_page_for_size(@size))
24
17
  if in_overlay?
25
18
  archive_overlay
@@ -36,7 +29,7 @@ module Alchemy
36
29
  @while_assigning = true
37
30
  @content = Content.find_by_id(params[:content_id], :select => 'id')
38
31
  @element = Element.find(params[:element_id], :select => 'id')
39
- @options = hashified_options
32
+ @options = options_from_params
40
33
  @page = params[:page]
41
34
  @per_page = params[:per_page]
42
35
  end
@@ -55,7 +48,7 @@ module Alchemy
55
48
  @while_assigning = true
56
49
  @content = Content.find(params[:content_id], :select => 'id') if !params[:content_id].blank?
57
50
  @element = Element.find(params[:element_id], :select => 'id')
58
- @options = hashified_options
51
+ @options = options_from_params
59
52
  @page = params[:page] || 1
60
53
  @per_page = pictures_per_page_for_size(@size)
61
54
  end
@@ -123,7 +116,7 @@ module Alchemy
123
116
  end
124
117
  end
125
118
  if not_deletable.any?
126
- flash[:warn] = _t("These pictures could not be deleted, because they where in use", :names => not_deletable.to_sentence)
119
+ flash[:warn] = _t("These pictures could not be deleted, because they were in use", :names => not_deletable.to_sentence)
127
120
  else
128
121
  flash[:notice] = _t("Pictures deleted successfully", :names => names.to_sentence)
129
122
  end
@@ -180,7 +173,7 @@ module Alchemy
180
173
  def archive_overlay
181
174
  @content = Content.find_by_id(params[:content_id], :select => 'id')
182
175
  @element = Element.find_by_id(params[:element_id], :select => 'id')
183
- @options = hashified_options
176
+ @options = options_from_params
184
177
  respond_to do |format|
185
178
  format.html {
186
179
  render :partial => 'archive_overlay'
@@ -1,9 +1,11 @@
1
1
  require 'csv'
2
+ require 'alchemy/resource'
3
+ require 'alchemy/resources_helper'
4
+ require 'handles_sortable_columns'
2
5
 
3
6
  module Alchemy
4
7
  module Admin
5
8
  class ResourcesController < Alchemy::Admin::BaseController
6
-
7
9
  include Alchemy::ResourcesHelper
8
10
  helper Alchemy::ResourcesHelper
9
11
  helper_method :resource_handler
@@ -7,7 +7,7 @@ module Alchemy
7
7
  def index
8
8
  @elements = Element.trashed
9
9
  @page = Page.find(params[:page_id])
10
- @allowed_elements = Element.all_for_page(@page)
10
+ @allowed_elements = @page.available_element_definitions
11
11
  @draggable_trash_items = {}
12
12
  @elements.each { |e| @draggable_trash_items["element_#{e.id}"] = e.belonging_cellnames(@page) }
13
13
  render layout: !request.xhr?
@@ -28,7 +28,7 @@ module Alchemy
28
28
  private
29
29
 
30
30
  def load_attachment
31
- @attachment = Attachment.where(:id => params[:id]).first
31
+ @attachment = Attachment.find(params[:id])
32
32
  end
33
33
 
34
34
  end
@@ -1,7 +1,6 @@
1
- # This is the main Alchemy controller all other controllers inheret from.
1
+ # This is the main Alchemy controller all other controllers inherit from.
2
2
  module Alchemy
3
3
  class BaseController < ApplicationController
4
-
5
4
  include Alchemy::Modules
6
5
 
7
6
  protect_from_forgery
@@ -139,15 +138,6 @@ module Alchemy
139
138
  ActionMailer::Base.default_url_options[:host] = request.host_with_port
140
139
  end
141
140
 
142
- def hashified_options
143
- return nil if params[:options].blank?
144
- if params[:options].is_a?(String)
145
- Rack::Utils.parse_query(params[:options])
146
- else
147
- params[:options]
148
- end
149
- end
150
-
151
141
  # Returns the layout to be used by the current page. This method is being
152
142
  # used in PageController#show's invocation of #render.
153
143
  #
@@ -204,14 +194,12 @@ module Alchemy
204
194
 
205
195
  def permission_denied
206
196
  if current_user
207
- if permitted_to? :index_alchemy_admin_dashboard
197
+ if permitted_to? :index, :alchemy_admin_dashboard
208
198
  if request.referer == alchemy.login_url
209
199
  render :file => Rails.root.join('public/422'), :status => 422
210
200
  elsif request.xhr?
211
201
  respond_to do |format|
212
- format.js {
213
- render :js => "Alchemy.growl('#{_t('You are not authorized')}', 'warning'); Alchemy.Buttons.enable();"
214
- }
202
+ format.js { render status: 403 }
215
203
  format.html {
216
204
  render :partial => 'alchemy/admin/partials/flash', :locals => {:message => _t('You are not authorized'), :flash_type => 'warning'}
217
205
  }
@@ -42,7 +42,7 @@ module Alchemy
42
42
  # Please have a look at the +alchemy/config/config.yml+ file for further Message settings.
43
43
  #
44
44
  class MessagesController < Alchemy::BaseController
45
- include Alchemy::FerretSearch
45
+ include Alchemy::Ferret::Search
46
46
 
47
47
  before_filter :get_page, :except => :create
48
48
 
@@ -81,21 +81,15 @@ module Alchemy
81
81
  end
82
82
 
83
83
  def mail_to
84
- @element.ingredient("mail_to")
85
- rescue
86
- mailer_config['mail_to']
84
+ @element.ingredient(:mail_to) || mailer_config['mail_to']
87
85
  end
88
86
 
89
87
  def mail_from
90
- @element.ingredient("mail_from")
91
- rescue
92
- mailer_config['mail_from']
88
+ @element.ingredient(:mail_from) || mailer_config['mail_from']
93
89
  end
94
90
 
95
91
  def subject
96
- @element.ingredient("subject")
97
- rescue
98
- mailer_config['subject']
92
+ @element.ingredient(:subject) || mailer_config['subject']
99
93
  end
100
94
 
101
95
  def redirect_to_success_page
@@ -1,17 +1,17 @@
1
1
  module Alchemy
2
2
  class PagesController < Alchemy::BaseController
3
- include Alchemy::FerretSearch
3
+ include Ferret::Search
4
4
 
5
5
  # We need to include this helper because we need the breadcrumb method.
6
6
  # And we cannot define the breadcrump method as helper_method, because rspec does not see helper_methods.
7
7
  # Not the best solution, but's working.
8
8
  # Anyone with a better idea please provide a patch.
9
- include Alchemy::BaseHelper
9
+ include BaseHelper
10
10
 
11
11
  rescue_from ActionController::RoutingError, :with => :render_404
12
12
 
13
13
  before_filter :enforce_primary_host_for_site
14
- before_filter :render_page_or_redirect, :only => [:show, :sitemap]
14
+ before_filter :render_page_or_redirect, :only => [:show]
15
15
  before_filter :perform_search, :only => :show, :if => proc { configuration(:ferret) }
16
16
 
17
17
  filter_access_to :show, :attribute_check => true, :model => Alchemy::Page, :load_method => :load_page
@@ -49,11 +49,11 @@ module Alchemy
49
49
  end
50
50
  end
51
51
 
52
- # Renders a Google conform sitemap in xml
52
+ # Renders a search engine compatible xml sitemap.
53
53
  def sitemap
54
- @pages = Page.find_all_by_sitemap_and_public(true, true)
54
+ @pages = Page.sitemap
55
55
  respond_to do |format|
56
- format.xml { render :layout => "sitemap" }
56
+ format.xml { render layout: 'alchemy/sitemap' }
57
57
  end
58
58
  end
59
59
 
@@ -1,6 +1,6 @@
1
1
  module Alchemy
2
2
  class PasswordsController < Devise::PasswordsController
3
- include Alchemy::FerretSearch
3
+ include Ferret::Search
4
4
  helper 'Alchemy::Admin::Base', 'Alchemy::Pages'
5
5
 
6
6
  before_filter { enforce_ssl if ssl_required? && !request.ssl? }
@@ -1,7 +1,7 @@
1
1
  module Alchemy
2
2
  class UserSessionsController < Devise::SessionsController
3
3
  # Necessary because this controller is also used for general login.
4
- include Alchemy::FerretSearch
4
+ include Ferret::Search
5
5
  helper 'Alchemy::Admin::Base', 'Alchemy::Pages'
6
6
 
7
7
  before_filter(except: 'destroy') { enforce_ssl if ssl_required? && !request.ssl? }
@@ -12,6 +12,7 @@ module Alchemy
12
12
  #
13
13
  module BaseHelper
14
14
  include Alchemy::BaseHelper
15
+ include Alchemy::Admin::NavigationHelper
15
16
 
16
17
  # This helper renders the link to an overlay window.
17
18
  #
@@ -61,27 +62,6 @@ module Alchemy
61
62
  )
62
63
  end
63
64
 
64
- # (internal) Used for rendering the folder link in +Admin::Pages#index+ sitemap.
65
- def sitemapFolderLink(page)
66
- return '' if page.level == 1
67
- if page.folded?(current_user.id)
68
- css_class = 'folded'
69
- title = _t('Show childpages')
70
- else
71
- css_class = 'collapsed'
72
- title = _t('Hide childpages')
73
- end
74
- link_to(
75
- '',
76
- alchemy.fold_admin_page_path(page),
77
- :remote => true,
78
- :method => :post,
79
- :class => "page_folder #{css_class}",
80
- :title => title,
81
- :id => "fold_button_#{page.id}"
82
- )
83
- end
84
-
85
65
  # Used for language selector in Alchemy cockpit sitemap. So the user can select the language branche of the page.
86
66
  def language_codes_for_select
87
67
  configuration(:languages).collect { |language|
@@ -202,175 +182,6 @@ module Alchemy
202
182
  end
203
183
  end
204
184
 
205
- # Returns an Array build for passing it to the options_for_select helper inside an essence editor partial.
206
- #
207
- # Useful for the <tt>select_values</tt> options from the {Alchemy::Admin::EssencesHelper#render_essence_editor} helpers.
208
- #
209
- # @option options [String or Page] :from_page (nil)
210
- # Return only elements from this page. You can either pass a Page instance, or a page_layout name
211
- # @option options [Array or String] :elements_with_name (nil)
212
- # Return only elements with this name(s).
213
- # @option options [String] :prompt (_t('Please choose'))
214
- # Prompt inside the select tag.
215
- #
216
- def elements_for_essence_editor_select(options={})
217
- defaults = {
218
- :from_page => nil,
219
- :elements_with_name => nil,
220
- :prompt => _t('Please choose')
221
- }
222
- options = defaults.merge(options)
223
- if options[:from_page]
224
- page = options[:from_page].is_a?(String) ? Page.find_by_page_layout(options[:from_page]) : options[:from_page]
225
- end
226
- if page
227
- elements = options[:elements_with_name].blank? ? page.elements.published : page.elements.published.where(:name => options[:elements_with_name])
228
- else
229
- elements = options[:elements_with_name].blank? ? Element.published : Element.published.where(:name => options[:elements_with_name])
230
- end
231
- select_options = [[options[:prompt], ""]]
232
- elements.each do |e|
233
- select_options << [e.display_name_with_preview_text, e.id.to_s]
234
- end
235
- select_options
236
- end
237
-
238
- # Returns all public pages from current language as an option tags string suitable or the Rails +select_tag+ helper.
239
- #
240
- # @param [Array]
241
- # A collection of pages so it only returns these pages and does not query the database.
242
- # @param [String]
243
- # Pass a +Page#name+ or +Page#id+ as selected item to the +options_for_select+ helper.
244
- # @param [String]
245
- # Used as prompt message in the select tag
246
- # @param [Symbol]
247
- # Method that is called on the page object to get the value that is passed with the params of the form.
248
- #
249
- def pages_for_select(pages = nil, selected = nil, prompt = "", page_attribute = :id)
250
- result = [[prompt.blank? ? _t('Choose page') : prompt, ""]]
251
- if pages.blank?
252
- pages = Page.with_language(session[:language_id]).published.order(:lft)
253
- pages.each do |p|
254
- result << [("&nbsp;&nbsp;" * (p.level - 1) + p.name).html_safe, p.send(page_attribute).to_s]
255
- end
256
- else
257
- pages.each do |p|
258
- result << [p.name, p.send(page_attribute).to_s]
259
- end
260
- end
261
- options_for_select(result, selected.to_s)
262
- end
263
-
264
- def render_essence_selection_editor(element, content, select_options)
265
- if content.class == String
266
- content = element.contents.find_by_name(content)
267
- else
268
- content = element.contents[content - 1]
269
- end
270
- if content.essence.nil?
271
- return warning('Element', _t(:content_essence_not_found))
272
- end
273
- select_options = options_for_select(select_options, content.essence.content)
274
- select_tag(
275
- "contents[content_#{content.id}]",
276
- select_options,
277
- :class => 'alchemy_selectbox'
278
- )
279
- end
280
-
281
- # Renders the admin main navigation
282
- def admin_main_navigation
283
- entries = ""
284
- alchemy_modules.each do |alchemy_module|
285
- entries << alchemy_main_navigation_entry(alchemy_module)
286
- end
287
- entries.html_safe
288
- end
289
-
290
- # Renders one admin main navigation entry
291
- #
292
- # @param [Hash] alchemy_module
293
- # The Hash representing a Alchemy module
294
- #
295
- def alchemy_main_navigation_entry(alchemy_module)
296
- render 'alchemy/admin/partials/main_navigation_entry', :alchemy_module => alchemy_module.stringify_keys, :navigation => alchemy_module['navigation'].stringify_keys
297
- end
298
-
299
- # Renders the subnavigation in the admin areas
300
- def admin_subnavigation
301
- alchemy_module = module_definition_for(:controller => params[:controller], :action => 'index')
302
- unless alchemy_module.nil?
303
- entries = alchemy_module["navigation"].stringify_keys['sub_navigation']
304
- render_admin_subnavigation(entries) unless entries.nil?
305
- else
306
- ""
307
- end
308
- end
309
-
310
- # Renders the Subnavigation for the admin interface.
311
- def render_admin_subnavigation(entries)
312
- render "alchemy/admin/partials/sub_navigation_tab", :entries => entries
313
- end
314
-
315
- # Used for checking the main navi permissions
316
- def navigate_module(navigation)
317
- [navigation["action"].to_sym, navigation["controller"].gsub(/^\//, '').gsub(/\//, '_').to_sym]
318
- end
319
-
320
- # Returns true if the current controller and action is in a modules navigation definition.
321
- def admin_mainnavi_active?(mainnav)
322
- mainnav.stringify_keys!
323
- subnavi = mainnav["sub_navigation"].map(&:stringify_keys) if mainnav["sub_navigation"]
324
- nested = mainnav["nested"].map(&:stringify_keys) if mainnav["nested"]
325
- if subnavi
326
- (!subnavi.detect { |subnav| subnav["controller"].gsub(/^\//, '') == params[:controller] && subnav["action"] == params[:action] }.blank?) ||
327
- (nested && !nested.detect { |n| n["controller"] == params[:controller] && n["action"] == params[:action] }.blank?)
328
- else
329
- mainnav["controller"] == params[:controller] && mainnav["action"] == params["action"]
330
- end
331
- end
332
-
333
- # Returns true if the subnavigation entry is in the current params
334
- def admin_sub_navigation_entry_active?(entry)
335
- params[:controller] == entry["controller"].gsub(/^\//, '') && (params[:action] == entry["action"] || entry["nested_actions"] && entry["nested_actions"].include?(params[:action]))
336
- end
337
-
338
- # Calls the url_for helper on either an alchemy module engine, or the app alchemy is mounted at.
339
- def url_for_module(alchemy_module)
340
- navigation = alchemy_module['navigation'].stringify_keys
341
- url_options = {
342
- :controller => navigation['controller'],
343
- :action => navigation['action']
344
- }
345
- if alchemy_module['engine_name']
346
- eval(alchemy_module['engine_name']).url_for(url_options)
347
- else
348
- # hack to prefix any controller-path with / so it doesn't refer to alchemy/...
349
- url_options[:controller] = url_options[:controller].gsub(/^([^\/])/, "/#{$1}")
350
- main_app.url_for(url_options)
351
- end
352
- end
353
-
354
- # Calls the url_for helper on either an alchemy module engine, or the app alchemy is mounted at.
355
- def url_for_module_sub_navigation(navigation)
356
- alchemy_module = module_definition_for(navigation)
357
- engine_name = alchemy_module['engine_name'] if alchemy_module
358
- navigation.stringify_keys!
359
- url_options = {
360
- :controller => navigation['controller'],
361
- :action => navigation['action']
362
- }
363
- if engine_name
364
- eval(engine_name).url_for(url_options)
365
- else
366
- main_app.url_for(url_options)
367
- end
368
- end
369
-
370
- def main_navigation_css_classes(navigation)
371
- ['main_navi_entry', admin_mainnavi_active?(navigation) ? 'active' : nil].compact.join(" ")
372
- end
373
-
374
185
  # (internal) Renders translated Module Names for html title element.
375
186
  def render_alchemy_title
376
187
  if content_for?(:title)
@@ -414,6 +225,21 @@ module Alchemy
414
225
 
415
226
  # Renders a toolbar button for the Alchemy toolbar
416
227
  #
228
+ # == Example
229
+ #
230
+ # <%= toolbar_button(
231
+ # icon: 'create',
232
+ # label: 'Create',
233
+ # url: new_resource_path,
234
+ # title: 'Create Resource',
235
+ # hotkey: 'alt-n',
236
+ # overlay_options: {
237
+ # title: 'Create Resource',
238
+ # size: "430x400"
239
+ # },
240
+ # if_permitted_to: [:new, resource_permission_scope]
241
+ # ) %>
242
+ #
417
243
  # @option options [String] :icon
418
244
  # Icon class. See +app/assets/stylesheets/alchemy/icons.css.sccs+ for available icons, or make your own.
419
245
  # @option options [String] :label
@@ -436,47 +262,22 @@ module Alchemy
436
262
  # Shows the please wait overlay while loading. Only for buttons not opening an overlay window.
437
263
  #
438
264
  def toolbar_button(options = {})
439
- options.symbolize_keys!
440
- defaults = {
441
- :overlay => true,
442
- :skip_permission_check => false,
443
- :active => false,
444
- :link_options => {},
445
- :overlay_options => {},
446
- :loading_indicator => true
447
- }
448
- options = defaults.merge(options)
449
- button = content_tag('div', :class => 'button_with_label' + (options[:active] ? ' active' : '')) do
450
- link = if options[:overlay]
451
- link_to_overlay_window(
452
- render_icon(options[:icon]),
453
- options[:url],
454
- options[:overlay_options],
455
- {
456
- :class => 'icon_button',
457
- :title => options[:title],
458
- 'data-alchemy-hotkey' => options[:hotkey]
459
- }.merge(options[:link_options])
460
- )
461
- else
462
- link_to options[:url], {:class => ("icon_button#{options[:loading_indicator] ? ' please_wait' : nil}"), :title => options[:title], 'data-alchemy-hotkey' => options[:hotkey]}.merge(options[:link_options]) do
463
- render_icon(options[:icon])
464
- end
465
- end
466
- link += content_tag('label', options[:label])
467
- end
468
- if options[:skip_permission_check]
469
- return button
265
+ options = {
266
+ overlay: true,
267
+ skip_permission_check: false,
268
+ active: false,
269
+ link_options: {},
270
+ overlay_options: {},
271
+ loading_indicator: true
272
+ }.merge(options.symbolize_keys)
273
+ button = render(
274
+ 'alchemy/admin/partials/toolbar_button',
275
+ options: options
276
+ )
277
+ if options[:skip_permission_check] || permitted_to?(*permission_from_options(options))
278
+ button
470
279
  else
471
- if options[:if_permitted_to].blank?
472
- action_controller = options[:url].gsub(/^\//, '').split('/')
473
- options[:if_permitted_to] = [action_controller.last.to_sym, action_controller[0..action_controller.length-2].join('_').to_sym]
474
- end
475
- if permitted_to?(*options[:if_permitted_to])
476
- return button
477
- else
478
- return ""
479
- end
280
+ ""
480
281
  end
481
282
  end
482
283
 
@@ -624,6 +425,24 @@ module Alchemy
624
425
  "#{controller_name} #{action_name}"
625
426
  end
626
427
 
428
+ private
429
+
430
+ def permission_from_options(options)
431
+ if options[:if_permitted_to].blank?
432
+ options[:if_permitted_to] = permission_array_from_url(options)
433
+ else
434
+ options[:if_permitted_to]
435
+ end
436
+ end
437
+
438
+ def permission_array_from_url(options)
439
+ action_controller = options[:url].gsub(/^\//, '').split('/')
440
+ [
441
+ action_controller.last.to_sym,
442
+ action_controller[0..action_controller.length-2].join('_').to_sym
443
+ ]
444
+ end
445
+
627
446
  end
628
447
  end
629
448
  end