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
@@ -19,7 +19,7 @@ module Alchemy
19
19
  :controller => :essence_pictures,
20
20
  :action => :assign,
21
21
  :picture_id => picture_to_assign.id,
22
- :id => @content.id,
22
+ :content_id => @content.id,
23
23
  :options => options
24
24
  }
25
25
  end
@@ -2,6 +2,48 @@ module Alchemy
2
2
  module Admin
3
3
  module TagsHelper
4
4
 
5
+ # Renders tags list items for given class name
6
+ #
7
+ # @param class_name [String]
8
+ # The class_name representing a tagged class
9
+ #
10
+ # @return [String]
11
+ # A HTML string containing <tt><li></tt> tags
12
+ #
13
+ def render_tag_list(class_name, params)
14
+ raise ArgumentError.new('Please provide a String as class_name') if class_name.nil?
15
+ li_s = []
16
+ class_name.constantize.tag_counts.sort { |x, y| x.name.downcase <=> y.name.downcase }.each do |tag|
17
+ tags = filtered_by_tag?(tag) ? tag_filter(remove: tag) : tag_filter(add: tag)
18
+ li_s << content_tag('li', name: tag.name, class: tag_list_tag_active?(tag, params) ? 'active' : nil) do
19
+ link_to(
20
+ "#{tag.name} (#{tag.count})",
21
+ url_for(
22
+ params.delete_if { |k, v| k == "page" }.merge(
23
+ action: 'index',
24
+ tagged_with: tags
25
+ )
26
+ ),
27
+ remote: request.xhr?,
28
+ class: 'please_wait'
29
+ )
30
+ end
31
+ end
32
+ li_s.join.html_safe
33
+ end
34
+
35
+ # Returns true if the given tag is in +params[:tag_list]+
36
+ #
37
+ # @param tag [ActsAsTaggableOn::Tag]
38
+ # the tag
39
+ # @param params [Hash]
40
+ # url params
41
+ # @return [Boolean]
42
+ #
43
+ def tag_list_tag_active?(tag, params)
44
+ params[:tagged_with].to_s.split(',').include?(tag.name)
45
+ end
46
+
5
47
  # Checks if the tagged_with param contains the given tag
6
48
  def filtered_by_tag?(tag)
7
49
  if params[:tagged_with].present?
@@ -11,17 +11,6 @@ module Alchemy
11
11
  text.truncate(:length => length)
12
12
  end
13
13
 
14
- # Returns @language set in the action (e.g. Page.show)
15
- def current_language
16
- ActiveSupport::Deprecation.warn('This Proxy-method is deprecated. Please use @language directly.')
17
- if @language.nil?
18
- warning('@language is not set')
19
- nil
20
- else
21
- @language
22
- end
23
- end
24
-
25
14
  def parse_sitemap_name(page)
26
15
  if multi_language?
27
16
  pathname = "/#{session[:language_code]}/#{page.urlname}"
@@ -196,42 +196,66 @@ module Alchemy
196
196
  end
197
197
  end
198
198
 
199
- # Returns all public elements found by Element.name.
200
- # Pass a count to return only an limited amount of elements.
199
+ # This helper returns all published elements with the given name.
200
+ #
201
+ # @param [Hash] options
202
+ # Additional options.
203
+ #
204
+ # @option options [Number] :count
205
+ # The amount of elements to be returned.
206
+ #
207
+ # @option options [Alchemy::Page/String] :from_page
208
+ # Only elements associated with this page are returned.
209
+ #
210
+ # @note When passing a String for options :from_page, it must be a page_layout name.
211
+ #
201
212
  def all_elements_by_name(name, options = {})
202
213
  warning('options[:language] option not allowed any more in all_elements_by_name helper') unless options[:language].blank?
203
- default_options = {
204
- :count => :all,
205
- :from_page => :all
206
- }
207
- options = default_options.merge(options)
208
- if options[:from_page] == :all
209
- elements = Element.published.where(:name => name).limit(options[:count] == :all ? nil : options[:count])
210
- elsif options[:from_page].class == String
214
+ options = {
215
+ count: :all,
216
+ from_page: :all
217
+ }.merge(options)
218
+
219
+ case options[:from_page]
220
+ when :all
221
+ return Element.published.where(name: name).limit(options[:count] == :all ? nil : options[:count])
222
+ when String
211
223
  page = Page.with_language(session[:language_id]).find_by_page_layout(options[:from_page])
212
- return [] if page.blank?
213
- elements = page.elements.published.where(:name => name).limit(options[:count] == :all ? nil : options[:count])
214
224
  else
215
- elements = options[:from_page].elements.published.where(:name => name).limit(options[:count] == :all ? nil : options[:count])
225
+ page = options[:from_page]
216
226
  end
227
+
228
+ return [] if page.blank?
229
+ page.elements.published.where(name: name).limit(options[:count] == :all ? nil : options[:count])
217
230
  end
218
231
 
219
- # Returns the public element found by Element.name from the given public Page, either by Page.id or by Page.urlname
232
+ # This helper returns a published element found by the given name and the given published Page, either by Page.id or by Page.urlname
233
+ #
234
+ # @param [Hash] options
235
+ # Additional options.
236
+ #
237
+ # @option options [String] :page_urlname
238
+ # The urlname of the Page the element is associated with
239
+ #
240
+ # @option options [Integer] :page_id
241
+ # The id of the Page the element is associated with
242
+ #
220
243
  def element_from_page(options = {})
221
244
  default_options = {
222
- :page_urlname => "",
223
- :page_id => nil,
224
- :element_name => ""
225
- }
226
- options = default_options.merge(options)
227
- if options[:page_id].blank?
228
- page = Page.published.find_by_urlname(options[:page_urlname])
245
+ page_urlname: "",
246
+ page_id: nil,
247
+ element_name: ""
248
+ }.merge(options)
249
+
250
+ page = case options[:page_id]
251
+ when nil
252
+ Page.published.find_by_urlname(options[:page_urlname])
229
253
  else
230
- page = Page.published.find_by_id(options[:page_id])
254
+ Page.published.find_by_id(options[:page_id])
231
255
  end
256
+
232
257
  return "" if page.blank?
233
- element = page.elements.published.find_by_name(options[:element_name])
234
- return element
258
+ page.elements.published.find_by_name(options[:element_name])
235
259
  end
236
260
 
237
261
  # Renders all element partials from given cell.
@@ -274,7 +298,6 @@ module Alchemy
274
298
  tag_options(element_tags_attributes(element, options))
275
299
  end
276
300
 
277
-
278
301
  # Returns the element's tags information as an attribute hash.
279
302
  #
280
303
  # @param [Alchemy::Element] element The {Alchemy::Element} you want to render the tags from.
@@ -72,26 +72,6 @@ module Alchemy
72
72
  render_essence_view(content, options, html_options)
73
73
  end
74
74
 
75
- # Renders the +Essence+ view partial from +Element+ by position.
76
- #
77
- # Pass the position of the +Content+ inside the Element as second argument.
78
- #
79
- # == Example:
80
- #
81
- # This renders the second +Content+ from element.
82
- #
83
- # <%= render_essence_view_by_type(element, 2) %>
84
- #
85
- def render_essence_view_by_position(element, position, options = {}, html_options = {})
86
- ActiveSupport::Deprecation.warn 'Alchemy CMS: render_essence_view_by_position is not supported anymore and will be removed.'
87
- if element.blank?
88
- warning('Element is nil')
89
- return ""
90
- end
91
- content = element.contents.find_by_position(position)
92
- render_essence_view(content, options, html_options)
93
- end
94
-
95
75
  # Renders the +Esssence+ partial for given +Content+.
96
76
  #
97
77
  # The helper renders the view partial as default.
@@ -4,15 +4,8 @@ module Alchemy
4
4
  include Alchemy::BaseHelper
5
5
  include Alchemy::ElementsHelper
6
6
 
7
- def render_classes(classes=[])
8
- s = classes.uniq.delete_if { |x| x.blank? }.join(" ")
9
- s.blank? ? "" : "class='#{s}'"
10
- end
11
-
12
7
  def picture_essence_caption(content)
13
- return "" if content.nil?
14
- return "" if content.essence.nil?
15
- content.essence.caption
8
+ content.try(:essence).try(:caption)
16
9
  end
17
10
 
18
11
  # Renders links to language root pages of all published languages.
@@ -57,12 +50,23 @@ module Alchemy
57
50
  render :partial => "alchemy/page_layouts/standard"
58
51
  end
59
52
 
60
- def sitename_from_header_page
61
- header_page = Page.find_by_page_layout_and_layoutpage('layout_header', true)
62
- return "" if header_page.nil?
63
- page_title = header_page.elements.find_by_name('sitename')
64
- return "" if page_title.nil?
65
- page_title.ingredient('name')
53
+ # Renders a partial for current site
54
+ #
55
+ # Place a rails partial into +app/views/alchemy/site_layouts+
56
+ #
57
+ # and name it like your site name.
58
+ #
59
+ # == Example:
60
+ #
61
+ # <%= render_site_layout %>
62
+ #
63
+ # renders +app/views/alchemy/site_layouts/_default_site.html.erb+ for the site named "Default Site".
64
+ #
65
+ def render_site_layout
66
+ render current_site
67
+ rescue ActionView::MissingTemplate
68
+ warning("Site layout for #{current_site.try(:name)} not found. Please run `rails g alchemy:site_layouts`")
69
+ return ""
66
70
  end
67
71
 
68
72
  # Renders the navigation.
@@ -25,6 +25,7 @@ module Alchemy
25
25
  # <%= link_to '&raquo order now', page_path_for(:page_layout => 'orderform', :product_id => element.id) %>
26
26
  #
27
27
  def page_path_for(options={})
28
+ ActiveSupport::Deprecation.warn("Used deprecated page_path_for helper. Please use show_alchemy_page_path instead.")
28
29
  return warning("No page_layout, or urlname given. I got #{options.inspect} ") if options[:page_layout].blank? && options[:urlname].blank?
29
30
  if options[:urlname].blank?
30
31
  page = Page.find_by_page_layout(options[:page_layout])
@@ -1,15 +1,13 @@
1
1
  module Alchemy
2
2
  class Messages < ActionMailer::Base
3
3
 
4
- default :from => Alchemy::Config.get(:mailer)['mail_from']
5
-
6
4
  def contact_form_mail(message, mail_to, mail_from, subject)
7
5
  @message = message
8
6
  mail(
9
- :from => mail_from,
10
- :to => mail_to,
11
- :reply_to => message.email,
12
- :subject => subject
7
+ from: mail_from,
8
+ to: mail_to,
9
+ reply_to: message.try(:email),
10
+ subject: subject
13
11
  )
14
12
  end
15
13
 
@@ -1,3 +1,6 @@
1
+ require 'userstamp'
2
+ require 'acts-as-taggable-on'
3
+
1
4
  module Alchemy
2
5
  class Attachment < ActiveRecord::Base
3
6
  include Filetypes
@@ -20,58 +20,56 @@ module Alchemy
20
20
  validates_uniqueness_of :name, :scope => :page_id
21
21
  has_many :elements, :dependent => :destroy, :order => :position
22
22
 
23
- def self.definitions
24
- cell_yml = ::File.join(::Rails.root, 'config', 'alchemy', 'cells.yml')
25
- ::YAML.load_file(cell_yml)
26
- end
23
+ class << self
24
+ def definitions
25
+ @definitions ||= read_yml_file
26
+ end
27
27
 
28
- def self.definition_for(cellname)
29
- return nil if cellname.blank?
30
- definitions.detect { |c| c['name'] == cellname }
31
- end
28
+ def definition_for(cellname)
29
+ return nil if cellname.blank?
30
+ definitions.detect { |c| c['name'] == cellname }
31
+ end
32
32
 
33
- def self.all_definitions_for(cellnames)
34
- definitions.select { |c| cellnames.include? c['name'] }
35
- end
33
+ def all_definitions_for(cellnames)
34
+ definitions.select { |c| cellnames.include? c['name'] }
35
+ end
36
36
 
37
- def self.all_element_definitions_for(cellnames)
38
- element_names = []
39
- all_definitions_for(cellnames).each do |cell|
40
- element_names += cell['elements']
37
+ def definitions_for_element(element_name)
38
+ return [] if definitions.blank?
39
+ definitions.select { |d| d['elements'].include?(element_name) }
41
40
  end
42
- Element.all_definitions_for(element_names.uniq)
43
- end
44
41
 
45
- def self.definitions_for_element(element_name)
46
- return [] if definitions.blank?
47
- definitions.select { |d| d['elements'].include?(element_name) }
48
- end
42
+ def translated_label_for(cell_name)
43
+ I18n.t(cell_name, scope: 'cell_names', default: cell_name.to_s.humanize)
44
+ end
49
45
 
50
- def self.names_for_element(element_name)
51
- definitions = definitions_for_element(element_name)
52
- return nil if definitions.blank?
53
- definitions.collect { |d| d['name'] }
54
- end
46
+ private
55
47
 
56
- def self.translated_label_for(cell_name)
57
- I18n.t(cell_name, scope: 'cell_names', default: cell_name.to_s.humanize)
48
+ def read_yml_file
49
+ ::YAML.load_file(yml_file_path) || []
50
+ end
51
+
52
+ def yml_file_path
53
+ Rails.root.join('config', 'alchemy', 'cells.yml')
54
+ end
58
55
  end
59
56
 
60
57
  # Returns the cell definition defined in +config/alchemy/cells.yml+
61
- def description
62
- description = self.class.definition_for(self.name)
63
- if description.blank?
64
- warn "Could not find cell definition for #{self.name}. Please check your cells.yml!"
58
+ #
59
+ def definition
60
+ definition = self.class.definition_for(self.name)
61
+ if definition.blank?
62
+ log_warning "Could not find cell definition for #{self.name}. Please check your cells.yml!"
65
63
  return {}
66
64
  else
67
- description
65
+ definition
68
66
  end
69
67
  end
70
- alias_method :definition, :description
68
+ alias_method :description, :definition
71
69
 
72
70
  # Returns all elements that can be placed in this cell
73
71
  def available_elements
74
- description['elements'] || []
72
+ definition['elements'] || []
75
73
  end
76
74
 
77
75
  def name_for_label
@@ -1,7 +1,13 @@
1
+ require 'userstamp'
2
+ require 'acts_as_list'
3
+
1
4
  module Alchemy
2
5
  class Content < ActiveRecord::Base
3
6
  include Logger
4
7
 
8
+ # Concerns
9
+ include Factory
10
+
5
11
  attr_accessible(
6
12
  :do_not_index,
7
13
  :element_id,
@@ -14,7 +20,7 @@ module Alchemy
14
20
  belongs_to :essence, :polymorphic => true, :dependent => :destroy
15
21
  belongs_to :element
16
22
 
17
- stampable(:stamper_class_name => 'Alchemy::User')
23
+ stampable stamper_class_name: 'Alchemy::User'
18
24
 
19
25
  acts_as_list
20
26
 
@@ -38,64 +44,6 @@ module Alchemy
38
44
  scope :essence_texts, where(:essence_type => "Alchemy::EssenceText")
39
45
 
40
46
  class << self
41
-
42
- # Creates a new Content as descriped in the elements.yml file
43
- def create_from_scratch(element, essences_hash)
44
- # If no name given, we can create the content from essence type.
45
- # Used in picture gallery
46
- if essences_hash[:name].blank? && !essences_hash[:essence_type].blank?
47
- essences_of_same_type = element.contents.where(
48
- :essence_type => Content.normalize_essence_type(essences_hash[:essence_type])
49
- )
50
- description = {
51
- 'type' => essences_hash[:essence_type],
52
- 'name' => "#{essences_hash[:essence_type].classify.demodulize.underscore}_#{essences_of_same_type.count + 1}"
53
- }
54
- # Normal way to create
55
- else
56
- description = element.content_description_for(essences_hash[:name])
57
- description = element.available_content_description_for(essences_hash[:name]) if description.blank?
58
- end
59
- if description.blank?
60
- raise ContentDefinitionError, "No description found in elements.yml for #{essences_hash.inspect} and #{element.inspect}"
61
- end
62
- content = new(:name => description['name'], :element_id => element.id)
63
- content.create_essence!(description)
64
- content
65
- end
66
-
67
- # Makes a copy of source and also copies the associated essence.
68
- #
69
- # You can pass a differences hash to update the attributes of the copy.
70
- #
71
- # === Example
72
- #
73
- # @copy = Alchemy::Content.copy(@content, {:element_id => 3})
74
- # @copy.element_id # => 3
75
- #
76
- def copy(source, differences = {})
77
- attributes = source.attributes.except(
78
- "position",
79
- "created_at",
80
- "updated_at",
81
- "creator_id",
82
- "updater_id",
83
- "id"
84
- ).merge(differences.stringify_keys)
85
- content = self.create!(attributes)
86
- new_essence = content.essence.class.new(content.essence.attributes.except(
87
- "id",
88
- "creator_id",
89
- "updater_id",
90
- "created_at",
91
- "updated_at"
92
- ))
93
- new_essence.save!
94
- raise "Essence not cloned" if new_essence.id == content.essence_id
95
- content.update_attributes(:essence_id => new_essence.id)
96
- content
97
- end
98
-
99
47
  # Returns the translated label for a content name.
100
48
  #
101
49
  # Translate it in your locale yml file:
@@ -118,21 +66,6 @@ module Alchemy
118
66
  default: I18n.t("content_names.#{content_name}", default: content_name.humanize)
119
67
  )
120
68
  end
121
-
122
- # Returns all content descriptions from elements.yml
123
- def descriptions
124
- Element.descriptions.collect { |e| e['contents'] }.flatten.compact
125
- end
126
-
127
- def normalize_essence_type(essence_type)
128
- essence_type = essence_type.classify
129
- if not essence_type.match(/^Alchemy::/)
130
- essence_type.gsub!(/^Essence/, 'Alchemy::Essence')
131
- else
132
- essence_type
133
- end
134
- end
135
-
136
69
  end
137
70
 
138
71
  # Settings from the elements.yml definition
@@ -148,21 +81,6 @@ module Alchemy
148
81
  self.element.contents
149
82
  end
150
83
 
151
- # Returns my description hash from elements.yml
152
- # Returns the description from available_contents if my own description is blank
153
- def description
154
- if element.blank?
155
- warn "Content with id #{self.id} is missing its Element."
156
- return {}
157
- end
158
- desc = self.element.content_description_for(self.name)
159
- if desc.blank?
160
- self.element.available_content_description_for(self.name)
161
- end
162
- desc || {}
163
- end
164
- alias_method :definition, :description
165
-
166
84
  # Gets the ingredient from essence
167
85
  def ingredient
168
86
  return nil if essence.nil?
@@ -230,6 +148,17 @@ module Alchemy
230
148
  essence && !essence.link.blank?
231
149
  end
232
150
 
151
+ # Returns true if this content should be taken for element preview.
152
+ def preview_content?
153
+ !!description['take_me_for_preview']
154
+ end
155
+
156
+ # Proxy method that returns the preview text from essence.
157
+ #
158
+ def preview_text(maxlength = 30)
159
+ essence.preview_text(maxlength)
160
+ end
161
+
233
162
  def essence_partial_name
234
163
  essence.partial_name
235
164
  end
@@ -239,37 +168,17 @@ module Alchemy
239
168
  end
240
169
 
241
170
  def has_custom_tinymce_config?
242
- !settings[:tinymce].nil?
171
+ settings[:tinymce].present?
243
172
  end
244
173
 
245
174
  def tinymce_class_name
246
175
  if has_custom_tinymce_config?
247
- if settings[:tinymce]
248
- "custom_tinymce #{name}"
249
- end
176
+ "custom_tinymce #{element.name}_#{name}"
250
177
  else
251
178
  "default_tinymce"
252
179
  end
253
180
  end
254
181
 
255
- # Creates self.essence from description.
256
- def create_essence!(description)
257
- essence_class = self.class.normalize_essence_type(description['type']).constantize
258
- attributes = {
259
- :ingredient => default_text(description['default'])
260
- }
261
- if description['type'] == "EssenceRichtext" || description['type'] == "EssenceText"
262
- attributes.merge!(:do_not_index => !description['do_not_index'].nil?)
263
- end
264
- essence = essence_class.create(attributes)
265
- if essence
266
- self.essence = essence
267
- save!
268
- else
269
- false
270
- end
271
- end
272
-
273
182
  # Returns the default value from content description
274
183
  # If the value is a symbol it gets passed through i18n inside the +alchemy.default_content_texts+ scope
275
184
  def default_text(default)