alchemy_cms 3.2.1 → 3.3.0.rc1

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 (556) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +28 -0
  3. data/.gitignore +2 -2
  4. data/.travis.yml +11 -3
  5. data/CHANGELOG.md +100 -0
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile +12 -1
  8. data/README.md +25 -7
  9. data/Rakefile +1 -3
  10. data/alchemy_cms.gemspec +7 -15
  11. data/app/assets/fonts/alchemy/icons.eot +0 -0
  12. data/app/assets/fonts/alchemy/icons.svg +28 -66
  13. data/app/assets/fonts/alchemy/icons.ttf +0 -0
  14. data/app/assets/fonts/alchemy/icons.woff +0 -0
  15. data/app/assets/images/alchemy/icons.png +0 -0
  16. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +10 -3
  17. data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +15 -6
  18. data/app/assets/javascripts/alchemy/alchemy.char_counter.js.coffee +1 -1
  19. data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +1 -1
  20. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +10 -4
  21. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +16 -22
  22. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +69 -32
  23. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +147 -83
  24. data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +14 -14
  25. data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +1 -1
  26. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +1 -1
  27. data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +55 -0
  28. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +8 -1
  29. data/app/assets/javascripts/alchemy/alchemy.js +3 -1
  30. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +36 -31
  31. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +35 -29
  32. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +51 -5
  33. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +26 -10
  34. data/app/assets/javascripts/alchemy/{alchemy.windows.js.coffee → alchemy.trash_window.js.coffee} +1 -13
  35. data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +15 -17
  36. data/app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js +3 -3
  37. data/app/assets/stylesheets/alchemy/_extends.scss +1 -1
  38. data/app/assets/stylesheets/alchemy/_mixins.scss +27 -0
  39. data/app/assets/stylesheets/alchemy/_variables.scss +1 -0
  40. data/app/assets/stylesheets/alchemy/admin.scss +1 -0
  41. data/app/assets/stylesheets/alchemy/archive.scss +0 -57
  42. data/app/assets/stylesheets/alchemy/base.scss +1 -18
  43. data/app/assets/stylesheets/alchemy/buttons.scss +30 -25
  44. data/app/assets/stylesheets/alchemy/dialogs.scss +25 -9
  45. data/app/assets/stylesheets/alchemy/elements.scss +182 -126
  46. data/app/assets/stylesheets/alchemy/form_fields.scss +14 -8
  47. data/app/assets/stylesheets/alchemy/forms.scss +10 -1
  48. data/app/assets/stylesheets/alchemy/frame.scss +3 -10
  49. data/app/assets/stylesheets/alchemy/icon-font.scss +13 -6
  50. data/app/assets/stylesheets/alchemy/icons.scss +16 -0
  51. data/app/assets/stylesheets/alchemy/image_library.scss +269 -0
  52. data/app/assets/stylesheets/alchemy/selects.scss +1 -0
  53. data/app/assets/stylesheets/alchemy/sitemap.scss +12 -1
  54. data/app/assets/stylesheets/alchemy/toolbar.scss +2 -2
  55. data/app/assets/stylesheets/alchemy/upload.scss +97 -87
  56. data/app/assets/stylesheets/alchemy/welcome.sass +49 -0
  57. data/app/controllers/alchemy/admin/attachments_controller.rb +21 -29
  58. data/app/controllers/alchemy/admin/base_controller.rb +23 -4
  59. data/app/controllers/alchemy/admin/clipboard_controller.rb +0 -1
  60. data/app/controllers/alchemy/admin/contents_controller.rb +2 -4
  61. data/app/controllers/alchemy/admin/dashboard_controller.rb +4 -4
  62. data/app/controllers/alchemy/admin/elements_controller.rb +20 -11
  63. data/app/controllers/alchemy/admin/essence_files_controller.rb +2 -2
  64. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +10 -9
  65. data/app/controllers/alchemy/admin/languages_controller.rb +0 -1
  66. data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -2
  67. data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +0 -1
  68. data/app/controllers/alchemy/admin/pages_controller.rb +46 -29
  69. data/app/controllers/alchemy/admin/pictures_controller.rb +44 -55
  70. data/app/controllers/alchemy/admin/resources_controller.rb +8 -75
  71. data/app/controllers/alchemy/admin/tags_controller.rb +10 -8
  72. data/app/controllers/alchemy/admin/trash_controller.rb +0 -6
  73. data/app/controllers/alchemy/api/contents_controller.rb +0 -1
  74. data/app/controllers/alchemy/api/elements_controller.rb +0 -1
  75. data/app/controllers/alchemy/api/pages_controller.rb +4 -1
  76. data/app/controllers/alchemy/attachments_controller.rb +4 -5
  77. data/app/controllers/alchemy/base_controller.rb +6 -5
  78. data/app/controllers/alchemy/elements_controller.rb +1 -1
  79. data/app/controllers/alchemy/messages_controller.rb +9 -4
  80. data/app/controllers/alchemy/pages_controller.rb +133 -137
  81. data/app/controllers/alchemy/pictures_controller.rb +12 -10
  82. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +41 -0
  83. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +56 -0
  84. data/app/controllers/concerns/alchemy/locale_redirects.rb +38 -0
  85. data/app/controllers/concerns/alchemy/page_redirects.rb +80 -0
  86. data/app/controllers/concerns/alchemy/site_redirects.rb +22 -0
  87. data/app/helpers/alchemy/admin/attachments_helper.rb +1 -2
  88. data/app/helpers/alchemy/admin/base_helper.rb +36 -62
  89. data/app/helpers/alchemy/admin/contents_helper.rb +6 -80
  90. data/app/helpers/alchemy/admin/elements_helper.rb +36 -15
  91. data/app/helpers/alchemy/admin/essences_helper.rb +15 -8
  92. data/app/helpers/alchemy/admin/form_helper.rb +6 -10
  93. data/app/helpers/alchemy/admin/navigation_helper.rb +4 -7
  94. data/app/helpers/alchemy/admin/pages_helper.rb +14 -35
  95. data/app/helpers/alchemy/admin/pictures_helper.rb +12 -14
  96. data/app/helpers/alchemy/admin/tags_helper.rb +5 -7
  97. data/app/helpers/alchemy/base_helper.rb +9 -17
  98. data/app/helpers/alchemy/elements_block_helper.rb +5 -13
  99. data/app/helpers/alchemy/elements_helper.rb +6 -6
  100. data/app/helpers/alchemy/essences_helper.rb +3 -16
  101. data/app/helpers/alchemy/pages_helper.rb +32 -25
  102. data/app/helpers/alchemy/url_helper.rb +14 -16
  103. data/app/mailers/alchemy/messages.rb +0 -2
  104. data/app/models/alchemy.rb +0 -2
  105. data/app/models/alchemy/attachment.rb +45 -56
  106. data/app/models/alchemy/cell.rb +7 -8
  107. data/app/models/alchemy/content.rb +39 -24
  108. data/app/models/alchemy/content/factory.rb +27 -44
  109. data/app/models/alchemy/element.rb +101 -267
  110. data/app/models/alchemy/element/definitions.rb +9 -8
  111. data/app/models/alchemy/element/element_contents.rb +150 -0
  112. data/app/models/alchemy/element/element_essences.rb +109 -0
  113. data/app/models/alchemy/element/presenters.rb +18 -7
  114. data/app/models/alchemy/essence_date.rb +1 -2
  115. data/app/models/alchemy/essence_file.rb +10 -6
  116. data/app/models/alchemy/essence_html.rb +0 -1
  117. data/app/models/alchemy/essence_picture.rb +12 -4
  118. data/app/models/alchemy/essence_richtext.rb +6 -3
  119. data/app/models/alchemy/language.rb +48 -21
  120. data/app/models/alchemy/language/code.rb +1 -4
  121. data/app/models/alchemy/page.rb +33 -35
  122. data/app/models/alchemy/page/page_cells.rb +6 -10
  123. data/app/models/alchemy/page/page_elements.rb +130 -100
  124. data/app/models/alchemy/page/page_naming.rb +2 -3
  125. data/app/models/alchemy/page/page_natures.rb +50 -16
  126. data/app/models/alchemy/page/page_scopes.rb +7 -7
  127. data/app/models/alchemy/page/page_users.rb +3 -3
  128. data/app/models/alchemy/picture.rb +48 -33
  129. data/app/models/alchemy/picture/transformations.rb +8 -9
  130. data/app/models/alchemy/site.rb +19 -17
  131. data/app/models/alchemy/site/layout.rb +9 -9
  132. data/app/models/alchemy/tag.rb +0 -2
  133. data/app/models/alchemy/tree_node.rb +5 -4
  134. data/app/serializers/alchemy/attachment_serializer.rb +0 -1
  135. data/app/serializers/alchemy/base_serializer.rb +30 -0
  136. data/app/serializers/alchemy/cell_serializer.rb +0 -1
  137. data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -1
  138. data/app/serializers/alchemy/essence_date_serializer.rb +0 -1
  139. data/app/serializers/alchemy/essence_file_serializer.rb +0 -1
  140. data/app/serializers/alchemy/essence_html_serializer.rb +0 -1
  141. data/app/serializers/alchemy/essence_link_serializer.rb +0 -1
  142. data/app/serializers/alchemy/essence_picture_serializer.rb +0 -1
  143. data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -1
  144. data/app/serializers/alchemy/essence_select_serializer.rb +0 -1
  145. data/app/serializers/alchemy/essence_text_serializer.rb +0 -1
  146. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -1
  147. data/app/serializers/alchemy/page_serializer.rb +0 -1
  148. data/app/serializers/alchemy/page_tree_serializer.rb +90 -0
  149. data/app/serializers/alchemy/picture_serializer.rb +0 -1
  150. data/app/views/alchemy/_menubar.html.erb +3 -3
  151. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +11 -16
  152. data/app/views/alchemy/admin/attachments/_attachment.html.erb +9 -9
  153. data/app/views/alchemy/admin/attachments/_files_list.html.erb +7 -15
  154. data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
  155. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -2
  156. data/app/views/alchemy/admin/attachments/edit.html.erb +3 -3
  157. data/app/views/alchemy/admin/attachments/index.html.erb +10 -17
  158. data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
  159. data/app/views/alchemy/admin/clipboard/index.html.erb +3 -3
  160. data/app/views/alchemy/admin/clipboard/insert.js.erb +3 -3
  161. data/app/views/alchemy/admin/clipboard/remove.js.erb +2 -2
  162. data/app/views/alchemy/admin/contents/_missing.html.erb +5 -7
  163. data/app/views/alchemy/admin/contents/create.js.erb +1 -1
  164. data/app/views/alchemy/admin/contents/new.html.erb +2 -2
  165. data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +6 -6
  166. data/app/views/alchemy/admin/dashboard/_recent_pages.html.erb +2 -2
  167. data/app/views/alchemy/admin/dashboard/_users.html.erb +2 -2
  168. data/app/views/alchemy/admin/dashboard/help.html.erb +15 -15
  169. data/app/views/alchemy/admin/dashboard/index.html.erb +6 -6
  170. data/app/views/alchemy/admin/dashboard/info.html.erb +5 -5
  171. data/app/views/alchemy/admin/elements/_add_picture.html.erb +1 -1
  172. data/app/views/alchemy/admin/elements/_element.html.erb +52 -18
  173. data/app/views/alchemy/admin/elements/_element_footer.html.erb +11 -0
  174. data/app/views/alchemy/admin/elements/{_element_head.html.erb → _element_header.html.erb} +8 -8
  175. data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +49 -0
  176. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +7 -6
  177. data/app/views/alchemy/admin/elements/_picture_gallery_editor.html.erb +1 -1
  178. data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +1 -1
  179. data/app/views/alchemy/admin/elements/create.js.erb +13 -8
  180. data/app/views/alchemy/admin/elements/fold.js.erb +12 -7
  181. data/app/views/alchemy/admin/elements/index.html.erb +12 -8
  182. data/app/views/alchemy/admin/elements/list.html.erb +3 -3
  183. data/app/views/alchemy/admin/elements/new.html.erb +4 -4
  184. data/app/views/alchemy/admin/elements/order.js.erb +3 -4
  185. data/app/views/alchemy/admin/elements/publish.js.erb +15 -0
  186. data/app/views/alchemy/admin/elements/trash.js.erb +3 -3
  187. data/app/views/alchemy/admin/elements/update.js.erb +7 -8
  188. data/app/views/alchemy/admin/essence_files/edit.html.erb +16 -13
  189. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +3 -3
  190. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +8 -8
  191. data/app/views/alchemy/admin/languages/_form.html.erb +12 -3
  192. data/app/views/alchemy/admin/languages/_language.html.erb +8 -2
  193. data/app/views/alchemy/admin/languages/_table.html.erb +11 -5
  194. data/app/views/alchemy/admin/languages/index.html.erb +1 -1
  195. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +8 -8
  196. data/app/views/alchemy/admin/layoutpages/edit.html.erb +2 -2
  197. data/app/views/alchemy/admin/layoutpages/index.html.erb +6 -13
  198. data/app/views/alchemy/admin/leave.html.erb +5 -5
  199. data/app/views/alchemy/admin/legacy_page_urls/_form.html.erb +1 -1
  200. data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +4 -4
  201. data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +1 -1
  202. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +9 -9
  203. data/app/views/alchemy/admin/pages/_external_link.html.erb +6 -6
  204. data/app/views/alchemy/admin/pages/_file_link.html.erb +6 -6
  205. data/app/views/alchemy/admin/pages/_form.html.erb +6 -6
  206. data/app/views/alchemy/admin/pages/_internal_link.html.erb +9 -11
  207. data/app/views/alchemy/admin/pages/_legacy_urls.html.erb +3 -3
  208. data/app/views/alchemy/admin/pages/_locked_page.html.erb +4 -4
  209. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +2 -2
  210. data/app/views/alchemy/admin/pages/_page.html.erb +95 -80
  211. data/app/views/alchemy/admin/pages/_page_for_links.html.erb +22 -22
  212. data/app/views/alchemy/admin/pages/_page_infos.html.erb +12 -0
  213. data/app/views/alchemy/admin/pages/_page_status.html.erb +7 -9
  214. data/app/views/alchemy/admin/pages/_sitemap.html.erb +35 -6
  215. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +0 -3
  216. data/app/views/alchemy/admin/pages/configure.html.erb +1 -1
  217. data/app/views/alchemy/admin/pages/configure_external.html.erb +4 -4
  218. data/app/views/alchemy/admin/pages/edit.html.erb +39 -44
  219. data/app/views/alchemy/admin/pages/flush.js.erb +1 -1
  220. data/app/views/alchemy/admin/pages/fold.js.erb +2 -3
  221. data/app/views/alchemy/admin/pages/index.html.erb +15 -22
  222. data/app/views/alchemy/admin/pages/info.html.erb +8 -8
  223. data/app/views/alchemy/admin/pages/link.html.erb +3 -3
  224. data/app/views/alchemy/admin/pages/locked.html.erb +1 -1
  225. data/app/views/alchemy/admin/pages/new.html.erb +4 -4
  226. data/app/views/alchemy/admin/pages/sort.js.erb +1 -2
  227. data/app/views/alchemy/admin/pages/unlock.js.erb +1 -1
  228. data/app/views/alchemy/admin/pages/update.js.erb +3 -3
  229. data/app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb +1 -1
  230. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
  231. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +1 -1
  232. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +9 -15
  233. data/app/views/alchemy/admin/partials/_search_form.html.erb +14 -13
  234. data/app/views/alchemy/admin/partials/_sub_navigation.html.erb +1 -1
  235. data/app/views/alchemy/admin/pictures/_archive.html.erb +14 -14
  236. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +30 -36
  237. data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +5 -5
  238. data/app/views/alchemy/admin/pictures/{edit.html.erb → _form.html.erb} +7 -6
  239. data/app/views/alchemy/admin/pictures/_infos.html.erb +50 -0
  240. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  241. data/app/views/alchemy/admin/pictures/_picture.html.erb +17 -51
  242. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -1
  243. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -2
  244. data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +6 -6
  245. data/app/views/alchemy/admin/pictures/index.html.erb +28 -36
  246. data/app/views/alchemy/admin/pictures/show.html.erb +46 -9
  247. data/app/views/alchemy/admin/pictures/update.js.erb +6 -0
  248. data/app/views/alchemy/admin/resources/_form.html.erb +3 -3
  249. data/app/views/alchemy/admin/resources/_resource.html.erb +4 -4
  250. data/app/views/alchemy/admin/resources/_table.html.erb +5 -6
  251. data/app/views/alchemy/admin/resources/index.csv.erb +12 -10
  252. data/app/views/alchemy/admin/resources/index.html.erb +4 -4
  253. data/app/views/alchemy/admin/sites/index.html.erb +1 -1
  254. data/app/views/alchemy/admin/tags/_tag.html.erb +4 -4
  255. data/app/views/alchemy/admin/tags/edit.html.erb +5 -5
  256. data/app/views/alchemy/admin/tags/index.html.erb +8 -8
  257. data/app/views/alchemy/admin/tags/new.html.erb +2 -2
  258. data/app/views/alchemy/admin/trash/clear.js.erb +1 -1
  259. data/app/views/alchemy/admin/trash/index.html.erb +8 -6
  260. data/app/views/alchemy/admin/uploader/_button.html.erb +39 -0
  261. data/app/views/alchemy/admin/uploader/_setup.html.erb +13 -0
  262. data/app/views/alchemy/base/500.html.erb +4 -4
  263. data/app/views/alchemy/elements/_editor_not_found.html.erb +1 -1
  264. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +3 -4
  265. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +1 -1
  266. data/app/views/alchemy/essences/_essence_date_editor.html.erb +2 -6
  267. data/app/views/alchemy/essences/_essence_date_view.html.erb +1 -1
  268. data/app/views/alchemy/essences/_essence_file_editor.html.erb +9 -11
  269. data/app/views/alchemy/essences/_essence_file_view.html.erb +11 -5
  270. data/app/views/alchemy/essences/_essence_html_editor.html.erb +1 -1
  271. data/app/views/alchemy/essences/_essence_link_editor.html.erb +1 -1
  272. data/app/views/alchemy/essences/_essence_link_view.html.erb +1 -1
  273. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +47 -52
  274. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +1 -1
  275. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +1 -1
  276. data/app/views/alchemy/essences/_essence_select_editor.html.erb +23 -13
  277. data/app/views/alchemy/essences/_essence_text_editor.html.erb +1 -1
  278. data/app/views/alchemy/essences/_essence_text_view.html.erb +1 -1
  279. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +29 -36
  280. data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +5 -5
  281. data/app/views/alchemy/language_links/_language.html.erb +15 -9
  282. data/app/views/alchemy/messages/contact_form_mail.de.text.erb +1 -1
  283. data/app/views/alchemy/messages/contact_form_mail.en.text.erb +1 -1
  284. data/app/views/alchemy/messages/contact_form_mail.es.text.erb +1 -1
  285. data/app/views/alchemy/navigation/_link.html.erb +0 -1
  286. data/app/views/alchemy/pages/show.rss.builder +6 -4
  287. data/app/views/alchemy/welcome.html.erb +28 -0
  288. data/app/views/layouts/alchemy/admin.html.erb +14 -10
  289. data/bin/alchemy +3 -4
  290. data/bin/rspec +7 -0
  291. data/bin/spring +15 -0
  292. data/config/alchemy/config.yml +16 -17
  293. data/config/initializers/assets.rb +13 -0
  294. data/config/locales/alchemy.de.yml +27 -29
  295. data/config/locales/alchemy.en.yml +23 -29
  296. data/config/locales/alchemy.es.yml +23 -29
  297. data/config/locales/alchemy.fr.yml +19 -28
  298. data/config/locales/alchemy.nl.yml +19 -27
  299. data/config/locales/alchemy.ru.yml +19 -28
  300. data/config/routes.rb +53 -54
  301. data/config/spring.rb +2 -0
  302. data/db/migrate/20130827094554_alchemy_two_point_six.rb +1 -3
  303. data/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +6 -0
  304. data/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +5 -0
  305. data/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +7 -0
  306. data/lib/alchemy/auth_accessors.rb +1 -1
  307. data/lib/alchemy/cache_digests/template_tracker.rb +7 -13
  308. data/lib/alchemy/config.rb +5 -7
  309. data/lib/alchemy/configuration_methods.rb +11 -1
  310. data/lib/alchemy/controller_actions.rb +9 -12
  311. data/lib/alchemy/engine.rb +11 -28
  312. data/lib/alchemy/errors.rb +0 -1
  313. data/lib/alchemy/essence.rb +20 -20
  314. data/lib/alchemy/filetypes.rb +1 -3
  315. data/lib/alchemy/forms/builder.rb +0 -2
  316. data/lib/alchemy/hints.rb +1 -3
  317. data/lib/alchemy/i18n.rb +81 -53
  318. data/lib/alchemy/kaminari/scoped_pagination_url_helper.rb +0 -2
  319. data/lib/alchemy/locale.rb +0 -1
  320. data/lib/alchemy/logger.rb +1 -3
  321. data/lib/alchemy/modules.rb +3 -3
  322. data/lib/alchemy/mount_point.rb +0 -2
  323. data/lib/alchemy/name_conversions.rb +1 -3
  324. data/lib/alchemy/on_page_layout.rb +37 -23
  325. data/lib/alchemy/on_page_layout/callbacks_runner.rb +34 -0
  326. data/lib/alchemy/page_layout.rb +23 -24
  327. data/lib/alchemy/paths.rb +32 -0
  328. data/lib/alchemy/permissions.rb +20 -20
  329. data/lib/alchemy/picture_attributes.rb +0 -3
  330. data/lib/alchemy/resource.rb +66 -22
  331. data/lib/alchemy/resources_helper.rb +48 -11
  332. data/lib/alchemy/routing_constraints.rb +4 -5
  333. data/lib/alchemy/seeder.rb +1 -4
  334. data/lib/alchemy/shell.rb +12 -14
  335. data/lib/alchemy/tasks/helpers.rb +5 -7
  336. data/lib/alchemy/test_support/essence_shared_examples.rb +24 -24
  337. data/lib/alchemy/test_support/factories.rb +2 -146
  338. data/lib/alchemy/test_support/factories/attachment_factory.rb +9 -0
  339. data/lib/alchemy/test_support/factories/cell_factory.rb +9 -0
  340. data/lib/alchemy/test_support/factories/content_factory.rb +10 -0
  341. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +21 -0
  342. data/lib/alchemy/test_support/factories/element_factory.rb +21 -0
  343. data/lib/alchemy/test_support/factories/essence_file_factory.rb +8 -0
  344. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +8 -0
  345. data/lib/alchemy/test_support/factories/essence_text_factory.rb +7 -0
  346. data/lib/alchemy/test_support/factories/language_factory.rb +28 -0
  347. data/lib/alchemy/test_support/factories/page_factory.rb +45 -0
  348. data/lib/alchemy/test_support/factories/picture_factory.rb +10 -0
  349. data/lib/alchemy/test_support/factories/site_factory.rb +12 -0
  350. data/lib/alchemy/test_support/integration_helpers.rb +0 -3
  351. data/lib/alchemy/tinymce.rb +24 -35
  352. data/lib/alchemy/touching.rb +5 -6
  353. data/lib/alchemy/upgrader.rb +3 -5
  354. data/lib/alchemy/upgrader/tasks/available_contents_upgrader.rb +155 -0
  355. data/lib/alchemy/upgrader/tasks/nestable_elements_migration.rb +71 -0
  356. data/lib/alchemy/upgrader/tasks/three_point_two_task.rb +31 -0
  357. data/lib/alchemy/upgrader/three_point_three.rb +50 -0
  358. data/lib/alchemy/upgrader/three_point_two.rb +3 -32
  359. data/lib/alchemy/upgrader/three_point_zero.rb +0 -1
  360. data/lib/alchemy/version.rb +1 -1
  361. data/lib/rails/generators/alchemy/base.rb +1 -1
  362. data/lib/rails/generators/alchemy/elements/elements_generator.rb +1 -7
  363. data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +5 -7
  364. data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +6 -8
  365. data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +6 -7
  366. data/lib/rails/generators/alchemy/elements/templates/view.html.erb +4 -4
  367. data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -3
  368. data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -3
  369. data/lib/rails/generators/alchemy/essence/essence_generator.rb +2 -3
  370. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -1
  371. data/lib/rails/generators/alchemy/install/files/alchemy.de.yml +2 -2
  372. data/lib/rails/generators/alchemy/install/files/alchemy.en.yml +2 -2
  373. data/lib/rails/generators/alchemy/install/files/alchemy.es.yml +3 -3
  374. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -1
  375. data/lib/rails/generators/alchemy/install/templates/elements.yml.tt +2 -2
  376. data/lib/rails/generators/alchemy/install/templates/page_layouts.yml.tt +1 -1
  377. data/lib/rails/generators/alchemy/module/module_generator.rb +1 -1
  378. data/lib/rails/templates/alchemy.rb +2 -2
  379. data/lib/tasks/alchemy/convert.rake +4 -8
  380. data/lib/tasks/alchemy/db.rake +2 -3
  381. data/lib/tasks/alchemy/install.rake +3 -4
  382. data/lib/tasks/alchemy/tidy.rake +4 -5
  383. data/lib/tasks/alchemy/upgrade.rake +2 -4
  384. data/spec/controllers/{admin → alchemy/admin}/attachments_controller_spec.rb +26 -44
  385. data/spec/controllers/{admin → alchemy/admin}/base_controller_spec.rb +14 -1
  386. data/spec/controllers/{admin → alchemy/admin}/clipboard_controller_spec.rb +3 -3
  387. data/spec/controllers/{admin → alchemy/admin}/contents_controller_spec.rb +4 -4
  388. data/spec/controllers/{admin → alchemy/admin}/dashboard_controller_spec.rb +11 -6
  389. data/spec/controllers/{admin → alchemy/admin}/elements_controller_spec.rb +54 -31
  390. data/spec/controllers/{admin → alchemy/admin}/essence_files_controller_spec.rb +8 -3
  391. data/spec/controllers/{admin → alchemy/admin}/essence_pictures_controller_spec.rb +3 -3
  392. data/spec/controllers/{admin → alchemy/admin}/languages_controller_spec.rb +13 -1
  393. data/spec/controllers/{admin → alchemy/admin}/layoutpages_controller_spec.rb +0 -6
  394. data/spec/controllers/{admin → alchemy/admin}/pages_controller_spec.rb +103 -35
  395. data/spec/controllers/{admin → alchemy/admin}/pictures_controller_spec.rb +133 -108
  396. data/spec/controllers/alchemy/admin/resources_controller_spec.rb +81 -0
  397. data/spec/controllers/{admin → alchemy/admin}/trash_controller_spec.rb +12 -13
  398. data/spec/controllers/alchemy/api/contents_controller_spec.rb +12 -13
  399. data/spec/controllers/alchemy/api/elements_controller_spec.rb +8 -9
  400. data/spec/controllers/alchemy/api/pages_controller_spec.rb +40 -7
  401. data/spec/controllers/{attachments_controller_spec.rb → alchemy/attachments_controller_spec.rb} +7 -7
  402. data/spec/controllers/alchemy/base_controller_spec.rb +106 -0
  403. data/spec/controllers/{elements_controller_spec.rb → alchemy/elements_controller_spec.rb} +4 -4
  404. data/spec/controllers/{messages_controller_spec.rb → alchemy/messages_controller_spec.rb} +14 -9
  405. data/spec/controllers/alchemy/on_page_layout_mixin_spec.rb +330 -0
  406. data/spec/controllers/{pages_controller_spec.rb → alchemy/pages_controller_spec.rb} +167 -89
  407. data/spec/controllers/{pictures_controller_spec.rb → alchemy/pictures_controller_spec.rb} +42 -20
  408. data/spec/dummy/app/models/dummy_user.rb +4 -0
  409. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_view.html.erb +31 -0
  410. data/spec/dummy/app/views/alchemy/elements/_article_editor.html.erb +6 -10
  411. data/spec/dummy/app/views/alchemy/elements/_article_view.html.erb +9 -24
  412. data/spec/dummy/app/views/alchemy/elements/_bild_editor.html.erb +3 -0
  413. data/spec/dummy/app/views/alchemy/elements/_bild_view.html.erb +5 -0
  414. data/spec/dummy/app/views/alchemy/elements/_contactform_editor.html.erb +6 -0
  415. data/spec/dummy/app/views/alchemy/elements/_contactform_view.html.erb +16 -0
  416. data/spec/dummy/app/views/alchemy/elements/_download_editor.html.erb +3 -0
  417. data/spec/dummy/app/views/alchemy/elements/_download_view.html.erb +5 -0
  418. data/spec/dummy/app/views/alchemy/elements/_erb_element_editor.html.erb +3 -0
  419. data/spec/dummy/app/views/alchemy/elements/_erb_element_view.html.erb +5 -0
  420. data/spec/dummy/app/views/alchemy/elements/_header_editor.html.erb +3 -0
  421. data/spec/dummy/app/views/alchemy/elements/_header_view.html.erb +5 -0
  422. data/spec/dummy/app/views/alchemy/elements/_news_editor.html.erb +5 -0
  423. data/spec/dummy/app/views/alchemy/elements/_search_editor.html.erb +1 -0
  424. data/spec/dummy/app/views/alchemy/elements/_search_view.html.erb +4 -0
  425. data/spec/dummy/app/views/alchemy/elements/_slide_editor.html.erb +3 -0
  426. data/spec/dummy/app/views/alchemy/elements/_slide_view.html.erb +5 -0
  427. data/spec/dummy/app/views/alchemy/elements/_slider_editor.html.erb +2 -0
  428. data/spec/dummy/app/views/alchemy/elements/_slider_view.html.erb +4 -0
  429. data/spec/dummy/app/views/alchemy/elements/_text_editor.html.erb +3 -0
  430. data/spec/dummy/app/views/alchemy/elements/_text_view.html.erb +5 -0
  431. data/spec/dummy/app/views/alchemy/page_layouts/_standard.html.erb +1 -0
  432. data/spec/dummy/config/alchemy/elements.yml +10 -13
  433. data/spec/dummy/config/alchemy/page_layouts.yml +1 -1
  434. data/spec/dummy/config/initializers/alchemy.rb +1 -0
  435. data/spec/dummy/config/locales/kl.yml +2 -0
  436. data/spec/dummy/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +1 -0
  437. data/spec/dummy/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +1 -0
  438. data/spec/dummy/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +1 -0
  439. data/spec/dummy/db/schema.rb +10 -6
  440. data/spec/factories.rb +13 -0
  441. data/spec/features/admin/admin_layout_spec.rb +14 -0
  442. data/spec/features/admin/dashboard_spec.rb +1 -2
  443. data/spec/features/admin/edit_elements_feature_spec.rb +36 -0
  444. data/spec/features/admin/language_tree_feature_spec.rb +7 -8
  445. data/spec/features/admin/languages_features_spec.rb +65 -0
  446. data/spec/features/admin/legacy_page_url_management_spec.rb +3 -3
  447. data/spec/features/admin/link_overlay_spec.rb +16 -17
  448. data/spec/features/admin/locale_select_feature_spec.rb +1 -1
  449. data/spec/features/admin/modules_integration_spec.rb +0 -1
  450. data/spec/features/admin/navigation_feature_spec.rb +11 -2
  451. data/spec/features/admin/page_creation_feature_spec.rb +5 -5
  452. data/spec/features/admin/page_editing_feature_spec.rb +6 -6
  453. data/spec/features/admin/picture_library_integration_spec.rb +3 -3
  454. data/spec/features/admin/resources_integration_spec.rb +7 -12
  455. data/spec/features/admin/site_select_feature_spec.rb +1 -2
  456. data/spec/features/admin/tinymce_feature_spec.rb +0 -1
  457. data/spec/features/page_feature_spec.rb +57 -158
  458. data/spec/features/page_redirects_spec.rb +358 -0
  459. data/spec/features/picture_security_spec.rb +1 -7
  460. data/spec/fixtures/animated.gif +0 -0
  461. data/spec/helpers/{admin → alchemy/admin}/attachments_helper_spec.rb +0 -0
  462. data/spec/helpers/{admin → alchemy/admin}/base_helper_spec.rb +39 -29
  463. data/spec/helpers/{admin → alchemy/admin}/contents_helper_spec.rb +4 -23
  464. data/spec/helpers/{admin → alchemy/admin}/elements_helper_spec.rb +141 -5
  465. data/spec/helpers/{admin → alchemy/admin}/essences_helper_spec.rb +69 -8
  466. data/spec/helpers/{admin → alchemy/admin}/navigation_helper_spec.rb +43 -37
  467. data/spec/helpers/{admin → alchemy/admin}/pages_helper_spec.rb +6 -38
  468. data/spec/helpers/{admin → alchemy/admin}/pictures_helper_spec.rb +0 -1
  469. data/spec/helpers/{admin → alchemy/admin}/tags_helper_spec.rb +1 -3
  470. data/spec/helpers/{base_helper_spec.rb → alchemy/base_helper_spec.rb} +1 -2
  471. data/spec/helpers/{elements_block_helper_spec.rb → alchemy/elements_block_helper_spec.rb} +3 -3
  472. data/spec/helpers/{elements_helper_spec.rb → alchemy/elements_helper_spec.rb} +18 -19
  473. data/spec/helpers/alchemy/essences_helper_spec.rb +85 -0
  474. data/spec/helpers/{pages_helper_spec.rb → alchemy/pages_helper_spec.rb} +125 -39
  475. data/spec/helpers/alchemy/picture_url_helpers_spec.rb +78 -0
  476. data/spec/helpers/{url_helper_spec.rb → alchemy/url_helper_spec.rb} +66 -40
  477. data/spec/libraries/config_spec.rb +2 -3
  478. data/spec/libraries/controller_actions_spec.rb +18 -18
  479. data/spec/libraries/i18n_spec.rb +7 -0
  480. data/spec/libraries/page_layout_spec.rb +13 -7
  481. data/spec/libraries/paths_spec.rb +15 -0
  482. data/spec/libraries/permissions_spec.rb +6 -7
  483. data/spec/libraries/resource_spec.rb +48 -75
  484. data/spec/libraries/resources_helper_spec.rb +55 -6
  485. data/spec/libraries/shell_spec.rb +0 -4
  486. data/spec/libraries/template_tracker_spec.rb +4 -13
  487. data/spec/libraries/tinymce_spec.rb +53 -9
  488. data/spec/mailers/{messages_spec.rb → alchemy/messages_spec.rb} +0 -2
  489. data/spec/models/{attachment_spec.rb → alchemy/attachment_spec.rb} +43 -20
  490. data/spec/models/{cell_spec.rb → alchemy/cell_spec.rb} +2 -3
  491. data/spec/models/{content_spec.rb → alchemy/content_spec.rb} +179 -70
  492. data/spec/models/{element_spec.rb → alchemy/element_spec.rb} +315 -70
  493. data/spec/models/{element_to_page_spec.rb → alchemy/element_to_page_spec.rb} +0 -1
  494. data/spec/models/{essence_boolean_spec.rb → alchemy/essence_boolean_spec.rb} +0 -0
  495. data/spec/models/{essence_date_spec.rb → alchemy/essence_date_spec.rb} +2 -3
  496. data/spec/models/{essence_file_spec.rb → alchemy/essence_file_spec.rb} +2 -5
  497. data/spec/models/{essence_html_spec.rb → alchemy/essence_html_spec.rb} +1 -1
  498. data/spec/models/{essence_link_spec.rb → alchemy/essence_link_spec.rb} +0 -0
  499. data/spec/models/{essence_picture_spec.rb → alchemy/essence_picture_spec.rb} +101 -29
  500. data/spec/models/{essence_richtext_spec.rb → alchemy/essence_richtext_spec.rb} +7 -2
  501. data/spec/models/{essence_select_spec.rb → alchemy/essence_select_spec.rb} +0 -0
  502. data/spec/models/{essence_text_spec.rb → alchemy/essence_text_spec.rb} +4 -8
  503. data/spec/models/alchemy/language_spec.rb +243 -0
  504. data/spec/models/{legacy_page_url_spec.rb → alchemy/legacy_page_url_spec.rb} +1 -1
  505. data/spec/models/{message_spec.rb → alchemy/message_spec.rb} +0 -0
  506. data/spec/models/{page_spec.rb → alchemy/page_spec.rb} +460 -248
  507. data/spec/models/{picture_spec.rb → alchemy/picture_spec.rb} +118 -30
  508. data/spec/models/{site_spec.rb → alchemy/site_spec.rb} +19 -84
  509. data/spec/models/{tag_spec.rb → alchemy/tag_spec.rb} +1 -3
  510. data/spec/models/dummy_model_spec.rb +1 -2
  511. data/spec/requests/alchemy/admin/resources_requests_spec.rb +26 -0
  512. data/spec/requests/alchemy/admin/site_requests_spec.rb +19 -0
  513. data/spec/requests/alchemy/site_requests_spec.rb +18 -0
  514. data/spec/requests/alchemy/sitemap_spec.rb +56 -0
  515. data/spec/routing/api_routing_spec.rb +1 -1
  516. data/spec/routing/routing_spec.rb +121 -15
  517. data/spec/spec_helper.rb +2 -1
  518. data/spec/support/hint_examples.rb +1 -3
  519. data/spec/support/test_tweaks.rb +3 -3
  520. data/spec/support/transformation_examples.rb +6 -7
  521. data/spec/tasks/helpers_spec.rb +2 -4
  522. data/spec/views/admin/pictures/show_spec.rb +43 -0
  523. data/spec/views/essences/essence_boolean_editor_spec.rb +0 -1
  524. data/spec/views/essences/essence_boolean_view_spec.rb +2 -4
  525. data/spec/views/essences/essence_date_view_spec.rb +0 -1
  526. data/spec/views/essences/essence_file_editor_spec.rb +4 -6
  527. data/spec/views/essences/essence_file_view_spec.rb +56 -3
  528. data/spec/views/essences/essence_link_view_spec.rb +1 -1
  529. data/spec/views/essences/essence_picture_editor_spec.rb +80 -0
  530. data/spec/views/essences/essence_picture_view_spec.rb +0 -1
  531. data/spec/views/essences/essence_select_view_spec.rb +0 -1
  532. data/spec/views/essences/essence_text_view_spec.rb +0 -1
  533. data/vendor/assets/javascripts/handlebars.js +4608 -0
  534. data/vendor/assets/javascripts/tinymce/langs/de.js +19 -0
  535. data/vendor/assets/javascripts/tinymce/langs/es.js +19 -0
  536. data/vendor/assets/javascripts/tinymce/langs/fr.js +23 -4
  537. data/vendor/assets/javascripts/tinymce/langs/nl.js +22 -3
  538. data/vendor/assets/javascripts/tinymce/langs/ru.js +22 -3
  539. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +1 -1
  540. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +1 -1
  541. data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +1 -1
  542. data/vendor/assets/javascripts/tinymce/tinymce.min.js +12 -13
  543. metadata +274 -256
  544. data/app/views/alchemy/admin/attachments/create.js.erb +0 -11
  545. data/app/views/alchemy/admin/attachments/new.html.erb +0 -14
  546. data/app/views/alchemy/admin/elements/_element_foot.html.erb +0 -36
  547. data/app/views/alchemy/admin/partials/_upload_form.html.erb +0 -67
  548. data/app/views/alchemy/admin/pictures/info.html.erb +0 -38
  549. data/app/views/alchemy/admin/pictures/new.html.erb +0 -16
  550. data/lib/alchemy/middleware/rescue_old_cookies.rb +0 -27
  551. data/spec/controllers/admin/resources_controller_spec.rb +0 -53
  552. data/spec/controllers/base_controller_spec.rb +0 -51
  553. data/spec/helpers/essences_helper_spec.rb +0 -156
  554. data/spec/helpers/picture_url_helpers_spec.rb +0 -35
  555. data/spec/libraries/on_page_layout_spec.rb +0 -112
  556. data/spec/models/language_spec.rb +0 -123
@@ -18,10 +18,14 @@ module Alchemy
18
18
 
19
19
  before_save :strip_content
20
20
 
21
- private
21
+ def has_tinymce?
22
+ true
23
+ end
24
+
25
+ private
22
26
 
23
27
  def strip_content
24
- self.stripped_body = strip_tags(self.body)
28
+ self.stripped_body = strip_tags(body)
25
29
  end
26
30
 
27
31
  # Stripping HTML Tags and only returns plain text.
@@ -42,6 +46,5 @@ module Alchemy
42
46
  html # already plain text
43
47
  end
44
48
  end
45
-
46
49
  end
47
50
  end
@@ -22,19 +22,23 @@ module Alchemy
22
22
  belongs_to :site
23
23
  has_many :pages
24
24
 
25
- validates_presence_of :name
26
- validates_presence_of :language_code
27
- validates_presence_of :page_layout
28
- validates_presence_of :frontpage_name
29
- validates_uniqueness_of :language_code, scope: [:site_id, :country_code]
30
- validate :presence_of_default_language
31
- validate :publicity_of_default_language
25
+ before_validation :set_locale, if: -> { locale.blank? }
26
+
27
+ validates :name, presence: true
28
+ validates :page_layout, presence: true
29
+ validates :frontpage_name, presence: true
30
+
31
+ validates :language_code,
32
+ presence: true,
33
+ uniqueness: { scope: [:site_id, :country_code] },
34
+ format: { with: /\A[a-z]{2}\z/, if: -> { language_code.present? } }
32
35
 
33
- validates_format_of :language_code, with: /\A[a-z]{2}\z/,
34
- if: -> { language_code.present? }
36
+ validates :country_code,
37
+ format: { with: /\A[a-zA-Z]{2}\z/, if: -> { country_code.present? } }
35
38
 
36
- validates_format_of :country_code, with: /\A[a-z]{2}\z/,
37
- if: -> { country_code.present? }
39
+ validate :presence_of_default_language
40
+ validate :publicity_of_default_language
41
+ validate :presence_of_locale_file, if: -> { language_code.present? }
38
42
 
39
43
  before_save :remove_old_default,
40
44
  if: -> { default_changed? && self != Language.default }
@@ -52,10 +56,9 @@ module Alchemy
52
56
 
53
57
  scope :published, -> { where(public: true) }
54
58
  scope :with_root_page, -> { joins(:pages).where(Page.table_name => {language_root: true}) }
55
- scope :on_site, ->(s) { s.present? ? where(site_id: s) : all }
59
+ scope :on_site, ->(s) { s.present? ? where(site_id: s.id) : all }
56
60
 
57
61
  class << self
58
-
59
62
  # Store the current language in the current thread.
60
63
  def current=(v)
61
64
  RequestStore.store[:alchemy_current_language] = v
@@ -80,9 +83,9 @@ module Alchemy
80
83
 
81
84
  def label(attrib)
82
85
  if attrib.to_sym == :code
83
- self.code
86
+ code
84
87
  else
85
- I18n.t(self.code, default: self.name)
88
+ Alchemy.t(code, default: name)
86
89
  end
87
90
  end
88
91
 
@@ -98,11 +101,35 @@ module Alchemy
98
101
  @layout_root_page ||= Page.layout_root_for(id)
99
102
  end
100
103
 
104
+ # All available locales matching this language
105
+ #
106
+ # Matching either the code (+language_code+ + +country_code+) or the +language_code+
107
+ #
108
+ # @return [Array]
109
+ #
110
+ def matching_locales
111
+ @_matching_locales ||= ::I18n.available_locales.select do |locale|
112
+ locale.to_s.split('-')[0] == language_code
113
+ end
114
+ end
115
+
101
116
  private
102
117
 
118
+ def set_locale
119
+ self.locale = matching_locales.reverse.detect do |locale|
120
+ locale.to_s == code || locale.to_s == language_code
121
+ end
122
+ end
123
+
124
+ def presence_of_locale_file
125
+ if locale.nil?
126
+ errors.add(:locale, :missing_file)
127
+ end
128
+ end
129
+
103
130
  def publicity_of_default_language
104
- if self.default? && !self.public?
105
- errors.add(:public, I18n.t("Default language has to be public"))
131
+ if default? && !public?
132
+ errors.add(:public, Alchemy.t("Default language has to be public"))
106
133
  return false
107
134
  else
108
135
  return true
@@ -110,8 +137,8 @@ module Alchemy
110
137
  end
111
138
 
112
139
  def presence_of_default_language
113
- if Language.default == self && self.default_changed?
114
- errors.add(:default, I18n.t("We need at least one default."))
140
+ if Language.default == self && default_changed?
141
+ errors.add(:default, Alchemy.t("We need at least one default."))
115
142
  return false
116
143
  else
117
144
  return true
@@ -126,7 +153,7 @@ module Alchemy
126
153
  end
127
154
 
128
155
  def set_pages_language
129
- pages.update_all language_code: self.code
156
+ pages.update_all language_code: code
130
157
  end
131
158
 
132
159
  def check_for_default
@@ -138,7 +165,7 @@ module Alchemy
138
165
  end
139
166
 
140
167
  def unpublish_pages
141
- self.pages.update_all(public: false)
168
+ pages.update_all(public: false)
142
169
  end
143
170
  end
144
171
  end
@@ -10,13 +10,10 @@ module Alchemy::Language::Code
10
10
  end
11
11
 
12
12
  module ClassMethods
13
-
14
13
  def find_by_code(code)
15
14
  codes = code.split('-')
16
15
  codes << '' if codes.length == 1
17
- find_by_language_code_and_country_code *codes
16
+ find_by_language_code_and_country_code(*codes)
18
17
  end
19
-
20
18
  end
21
-
22
19
  end
@@ -40,12 +40,12 @@ module Alchemy
40
40
  include Alchemy::Touching
41
41
 
42
42
  DEFAULT_ATTRIBUTES_FOR_COPY = {
43
- :do_not_autogenerate => true,
44
- :do_not_sweep => true,
45
- :visible => false,
46
- :public => false,
47
- :locked => false,
48
- :locked_by => nil
43
+ do_not_autogenerate: true,
44
+ do_not_sweep: true,
45
+ visible: false,
46
+ public: false,
47
+ locked: false,
48
+ locked_by: nil
49
49
  }
50
50
  SKIPPED_ATTRIBUTES_ON_COPY = %w(id updated_at created_at creator_id updater_id lft rgt depth urlname cached_tag_list)
51
51
  PERMITTED_ATTRIBUTES = [
@@ -66,18 +66,18 @@ module Alchemy
66
66
  ]
67
67
 
68
68
  acts_as_taggable
69
- acts_as_nested_set(:dependent => :destroy)
69
+ acts_as_nested_set(dependent: :destroy)
70
70
 
71
71
  stampable stamper_class_name: Alchemy.user_class_name
72
72
 
73
73
  has_many :folded_pages
74
- has_many :legacy_urls, :class_name => 'Alchemy::LegacyPageUrl'
74
+ has_many :legacy_urls, class_name: 'Alchemy::LegacyPageUrl'
75
75
  belongs_to :language
76
76
 
77
- validates_presence_of :language, :on => :create, :unless => :root
78
- validates_presence_of :page_layout, :unless => :systempage?
77
+ validates_presence_of :language, on: :create, unless: :root
78
+ validates_presence_of :page_layout, unless: :systempage?
79
79
  validates_format_of :page_layout, with: /\A[a-z0-9_-]+\z/, unless: -> { systempage? || page_layout.blank? }
80
- validates_presence_of :parent_id, :if => proc { Page.count > 1 }
80
+ validates_presence_of :parent_id, if: proc { Page.count > 1 }
81
81
 
82
82
  attr_accessor :do_not_sweep
83
83
  attr_accessor :do_not_validate_language
@@ -100,7 +100,6 @@ module Alchemy
100
100
  # Class methods
101
101
  #
102
102
  class << self
103
-
104
103
  alias_method :rootpage, :root
105
104
 
106
105
  # Used to store the current page previewed in the edit page template.
@@ -119,7 +118,7 @@ module Alchemy
119
118
  # @param language_id [Fixnum]
120
119
  #
121
120
  def language_root_for(language_id)
122
- self.language_roots.find_by_language_id(language_id)
121
+ language_roots.find_by_language_id(language_id)
123
122
  end
124
123
 
125
124
  # Creates a copy of given source.
@@ -148,7 +147,7 @@ module Alchemy
148
147
  end
149
148
 
150
149
  def layout_root_for(language_id)
151
- where({:parent_id => Page.root.id, :layoutpage => true, :language_id => language_id}).limit(1).first
150
+ where({parent_id: Page.root.id, layoutpage: true, language_id: language_id}).limit(1).first
152
151
  end
153
152
 
154
153
  def find_or_create_layout_root_for(language_id)
@@ -174,7 +173,7 @@ module Alchemy
174
173
  if source.children.any?
175
174
  source.copy_children_to(page)
176
175
  end
177
- return page
176
+ page
178
177
  end
179
178
 
180
179
  def all_from_clipboard(clipboard)
@@ -184,17 +183,18 @@ module Alchemy
184
183
 
185
184
  def all_from_clipboard_for_select(clipboard, language_id, layoutpage = false)
186
185
  return [] if clipboard.blank?
187
- clipboard_pages = self.all_from_clipboard(clipboard)
186
+ clipboard_pages = all_from_clipboard(clipboard)
188
187
  allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage)
189
188
  allowed_page_layout_names = allowed_page_layouts.collect { |p| p['name'] }
190
189
  clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) }
191
190
  end
192
191
 
193
192
  def link_target_options
194
- options = [[I18n.t(:default, scope: 'link_target_options'), '']]
193
+ options = [[Alchemy.t(:default, scope: 'link_target_options'), '']]
195
194
  link_target_options = Config.get(:link_target_options)
196
195
  link_target_options.each do |option|
197
- options << [I18n.t(option, scope: 'link_target_options', default: option.to_s.humanize), option]
196
+ options << [Alchemy.t(option, scope: 'link_target_options',
197
+ default: option.to_s.humanize), option]
198
198
  end
199
199
  options
200
200
  end
@@ -220,7 +220,7 @@ module Alchemy
220
220
  differences.stringify_keys!
221
221
  attributes = source.attributes.merge(differences)
222
222
  attributes.merge!(DEFAULT_ATTRIBUTES_FOR_COPY)
223
- attributes.merge!('name' => new_name_for_copy(differences['name'], source.name))
223
+ attributes['name'] = new_name_for_copy(differences['name'], source.name)
224
224
  attributes.except(*SKIPPED_ATTRIBUTES_ON_COPY)
225
225
  end
226
226
 
@@ -236,9 +236,8 @@ module Alchemy
236
236
  #
237
237
  def new_name_for_copy(custom_name, source_name)
238
238
  return custom_name if custom_name.present?
239
- "#{source_name} (#{I18n.t('Copy')})"
239
+ "#{source_name} (#{Alchemy.t('Copy')})"
240
240
  end
241
-
242
241
  end
243
242
 
244
243
  # Instance methods
@@ -283,13 +282,13 @@ module Alchemy
283
282
  # Locks the page to given user without updating the timestamps
284
283
  #
285
284
  def lock_to!(user)
286
- self.update_columns(locked: true, locked_by: user.id)
285
+ update_columns(locked: true, locked_by: user.id)
287
286
  end
288
287
 
289
288
  # Unlocks the page without updating the timestamps
290
289
  #
291
290
  def unlock!
292
- if self.update_columns(locked: false, locked_by: nil)
291
+ if update_columns(locked: false, locked_by: nil)
293
292
  Page.current_preview = nil
294
293
  end
295
294
  end
@@ -302,7 +301,7 @@ module Alchemy
302
301
 
303
302
  def set_restrictions_to_child_pages
304
303
  descendants.each do |child|
305
- child.update_attributes(:restricted => self.restricted?)
304
+ child.update_attributes(restricted: restricted?)
306
305
  end
307
306
  end
308
307
 
@@ -321,11 +320,11 @@ module Alchemy
321
320
  end
322
321
 
323
322
  def copy_children_to(new_parent)
324
- self.children.each do |child|
323
+ children.each do |child|
325
324
  next if child == new_parent
326
325
  new_child = Page.copy(child, {
327
- :language_id => new_parent.language_id,
328
- :language_code => new_parent.language_code
326
+ language_id: new_parent.language_id,
327
+ language_code: new_parent.language_code
329
328
  })
330
329
  new_child.move_to_child_of(new_parent)
331
330
  child.copy_children_to(new_child) unless child.children.blank?
@@ -339,7 +338,7 @@ module Alchemy
339
338
  # The +published_at+ attribute is used as +cache_key+.
340
339
  #
341
340
  def publish!
342
- update_columns(published_at: Time.now, public: true)
341
+ update_columns(published_at: Time.current, public: true)
343
342
  end
344
343
 
345
344
  # Updates an Alchemy::Page based on a new ordering to be applied to it
@@ -353,9 +352,9 @@ module Alchemy
353
352
  def update_node!(node)
354
353
  hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
355
354
 
356
- if Config.get(:url_nesting) && !self.redirects_to_external? && self.urlname != node.url
357
- LegacyPageUrl.create(page_id: self.id, urlname: self.urlname)
358
- hash.merge!(urlname: node.url)
355
+ if Config.get(:url_nesting) && !redirects_to_external? && urlname != node.url
356
+ LegacyPageUrl.create(page_id: id, urlname: urlname)
357
+ hash[:urlname] = node.url
359
358
  end
360
359
 
361
360
  update_columns(hash)
@@ -388,12 +387,12 @@ module Alchemy
388
387
  end
389
388
 
390
389
  def set_language_from_parent_or_default
391
- self.language = self.parent.language || Language.default
390
+ self.language = parent.language || Language.default
392
391
  set_language_code
393
392
  end
394
393
 
395
394
  def set_language_code
396
- self.language_code = self.language.code
395
+ self.language_code = language.code
397
396
  end
398
397
 
399
398
  # Stores the old urlname in a LegacyPageUrl
@@ -402,8 +401,7 @@ module Alchemy
402
401
  end
403
402
 
404
403
  def update_published_at
405
- self.published_at = Time.now
404
+ self.published_at = Time.current
406
405
  end
407
-
408
406
  end
409
407
  end
@@ -1,15 +1,13 @@
1
1
  module Alchemy
2
2
  module Page::PageCells
3
-
4
3
  extend ActiveSupport::Concern
5
4
 
6
5
  included do
7
- has_many :cells, :dependent => :destroy
8
- after_create :create_cells, :if => :can_have_cells?, :unless => :systempage?
6
+ has_many :cells, dependent: :destroy
7
+ after_create :create_cells, if: :can_have_cells?, unless: :systempage?
9
8
  end
10
9
 
11
10
  module ClassMethods
12
-
13
11
  # Copy page cells
14
12
  #
15
13
  # @param source [Alchemy::Page]
@@ -19,14 +17,13 @@ module Alchemy
19
17
  def copy_cells(source, target)
20
18
  new_cells = []
21
19
  source.cells.each do |cell|
22
- new_cells << Cell.create(:name => cell.name, :page_id => target.id)
20
+ new_cells << Cell.create(name: cell.name, page_id: target.id)
23
21
  end
24
22
  new_cells
25
23
  end
26
-
27
24
  end
28
25
 
29
- # Returns true, if the page's page_layout defines cells.
26
+ # Returns true, if the page's definition defines cells.
30
27
  def can_have_cells?
31
28
  definition['cells'].present?
32
29
  end
@@ -55,7 +52,7 @@ module Alchemy
55
52
 
56
53
  # Returns element names that are not defined in a cell.
57
54
  def element_names_not_in_cell
58
- layout_description['elements'].uniq - element_names_from_cells
55
+ definition['elements'].uniq - element_names_from_cells
59
56
  end
60
57
 
61
58
  private
@@ -63,9 +60,8 @@ module Alchemy
63
60
  # Creates cells that are defined in page's page_layout definition.
64
61
  def create_cells
65
62
  definition['cells'].each do |cellname|
66
- cells.create!(:name => cellname)
63
+ cells.create!(name: cellname)
67
64
  end
68
65
  end
69
-
70
66
  end
71
67
  end
@@ -1,25 +1,39 @@
1
1
  module Alchemy
2
2
  module Page::PageElements
3
-
4
3
  extend ActiveSupport::Concern
5
4
 
6
5
  included do
7
6
  attr_accessor :do_not_autogenerate
8
7
 
9
- has_many :elements, -> { order(:position) }
10
- has_many :contents, :through => :elements
11
- has_and_belongs_to_many :to_be_sweeped_elements, -> { uniq },
8
+ has_many :elements, -> { where(parent_element_id: nil).not_trashed.order(:position) }
9
+ has_many :trashed_elements,
10
+ -> { Element.trashed.order(:position) },
11
+ class_name: 'Alchemy::Element'
12
+ has_many :descendent_elements,
13
+ -> { order(:position).not_trashed },
14
+ class_name: 'Alchemy::Element'
15
+ has_many :contents, through: :elements
16
+ has_many :descendent_contents,
17
+ through: :descendent_elements,
18
+ class_name: 'Alchemy::Content',
19
+ source: :contents
20
+ has_and_belongs_to_many :to_be_swept_elements, -> { uniq },
12
21
  class_name: 'Alchemy::Element',
13
22
  join_table: ElementToPage.table_name
14
23
 
15
- after_create :autogenerate_elements, :unless => proc { systempage? || do_not_autogenerate }
16
- after_update :trash_not_allowed_elements, :if => :page_layout_changed?
17
- after_update :autogenerate_elements, :if => :page_layout_changed?
18
- after_destroy { elements.each { |el| el.destroy unless el.trashed? } }
24
+ after_create :autogenerate_elements, unless: -> { systempage? || do_not_autogenerate }
25
+ after_update :trash_not_allowed_elements!, if: :page_layout_changed?
26
+ after_update :autogenerate_elements, if: :page_layout_changed?
27
+
28
+ after_destroy do
29
+ elements.each do |element|
30
+ next if element.trashed?
31
+ element.destroy
32
+ end
33
+ end
19
34
  end
20
35
 
21
36
  module ClassMethods
22
-
23
37
  # Copy page elements
24
38
  #
25
39
  # @param source [Alchemy::Page]
@@ -28,23 +42,61 @@ module Alchemy
28
42
  #
29
43
  def copy_elements(source, target)
30
44
  new_elements = []
31
- source.elements.not_trashed.each do |element|
32
- # detect cell for element
33
- if element.cell
34
- cell = target.cells.detect { |c| c.name == element.cell.name }
35
- else
36
- cell = nil
45
+ source.elements.not_trashed.each do |source_element|
46
+ cell = nil
47
+ if source_element.cell
48
+ cell = target.cells.find_by(name: source_element.cell.name)
37
49
  end
38
- # if cell is nil also pass nil to element.cell_id
39
- new_element = Element.copy(element, :page_id => target.id, :cell_id => (cell.blank? ? nil : cell.id))
40
- # move element to bottom of the list
50
+ new_element = Element.copy source_element, {
51
+ page_id: target.id,
52
+ cell_id: cell.try(:id)
53
+ }
41
54
  new_element.move_to_bottom
42
55
  new_elements << new_element
43
56
  end
44
57
  new_elements
45
58
  end
59
+ end
46
60
 
61
+ # Finds elements of page.
62
+ #
63
+ # @param [Hash]
64
+ # options hash
65
+ # @param [Boolean] (false)
66
+ # Pass true, if you want to also have not published elements.
67
+ #
68
+ # @option options [Array] only
69
+ # Returns only elements with given names
70
+ # @option options [Array] except
71
+ # Returns all elements except the ones with given names
72
+ # @option options [Fixnum] count
73
+ # Limit the count of returned elements
74
+ # @option options [Fixnum] offset
75
+ # Starts with an offset while returning elements
76
+ # @option options [Boolean] random (false)
77
+ # Return elements randomly shuffled
78
+ # @option options [Alchemy::Cell || String] from_cell
79
+ # Return elements from given cell
80
+ #
81
+ # @return [ActiveRecord::Relation]
82
+ #
83
+ def find_elements(options = {}, show_non_public = false)
84
+ elements = elements_from_cell_or_self(options[:from_cell])
85
+ if options[:only].present?
86
+ elements = elements.named(options[:only])
87
+ elsif options[:except].present?
88
+ elements = elements.excluded(options[:except])
89
+ end
90
+ if options[:reverse_sort] || options[:reverse]
91
+ elements = elements.reverse_order
92
+ end
93
+ elements = elements.offset(options[:offset]).limit(options[:count])
94
+ if options[:random]
95
+ elements = elements.order("RAND()")
96
+ end
97
+ show_non_public ? elements : elements.published
47
98
  end
99
+ alias_method :find_selected_elements, :find_elements
48
100
 
49
101
  # All available element definitions that can actually be placed on current page.
50
102
  #
@@ -66,25 +118,36 @@ module Alchemy
66
118
  # - name: text
67
119
  # type: EssenceRichtext
68
120
  #
69
- def available_element_definitions
70
- @elements_for_layout ||= element_definitions
71
- return [] if @elements_for_layout.blank?
72
- @page_element_names = elements.not_trashed.pluck(:name)
121
+ def available_element_definitions(only_element_named = nil)
122
+ @_element_definitions ||= if only_element_named
123
+ definition = Element.definition_by_name(only_element_named)
124
+ element_definitions_by_name(definition['nestable_elements'])
125
+ else
126
+ element_definitions
127
+ end
128
+
129
+ return [] if @_element_definitions.blank?
130
+
131
+ @_existing_element_names = elements.not_trashed.pluck(:name)
73
132
  delete_unique_element_definitions!
74
133
  delete_outnumbered_element_definitions!
75
- @elements_for_layout
134
+
135
+ @_element_definitions
76
136
  end
77
137
 
78
138
  # All names of elements that can actually be placed on current page.
79
139
  #
80
140
  def available_element_names
81
- available_element_definitions.collect { |e| e['name'] }
141
+ @_available_element_names ||= available_element_definitions.map { |e| e['name'] }
82
142
  end
83
143
 
84
144
  # All element definitions defined for page's page layout
85
145
  #
146
+ # Warning: Since elements can be unique or limited in number,
147
+ # it is more safe to ask for +available_element_definitions+
148
+ #
86
149
  def element_definitions
87
- element_definitions_by_name(element_definition_names)
150
+ @_element_definitions ||= element_definitions_by_name(element_definition_names)
88
151
  end
89
152
 
90
153
  # All names of elements that are defined in the corresponding
@@ -105,18 +168,10 @@ module Alchemy
105
168
  # elements: [teaser]
106
169
  #
107
170
  def element_definition_names
108
- element_names_from_page_definition | element_names_from_cell_definition
109
- end
110
-
111
- def element_names_from_page_definition
112
- definition['elements'] || []
113
- end
114
-
115
- def element_names_from_cell_definition
116
- cell_definitions.map { |d| d['elements'] }.flatten
171
+ element_names_from_definition | element_names_from_cell_definitions
117
172
  end
118
173
 
119
- # Returns Element definitions with given name(s)
174
+ # Element definitions with given name(s)
120
175
  #
121
176
  # @param [Array || String]
122
177
  # one or many Alchemy::Element names. Pass +'all'+ to get all Element definitions
@@ -125,6 +180,7 @@ module Alchemy
125
180
  #
126
181
  def element_definitions_by_name(names)
127
182
  return [] if names.blank?
183
+
128
184
  if names.to_s == "all"
129
185
  Element.definitions
130
186
  else
@@ -132,46 +188,6 @@ module Alchemy
132
188
  end
133
189
  end
134
190
 
135
- # Finds elements of page.
136
- #
137
- # @param [Hash]
138
- # options hash
139
- # @param [Boolean] (false)
140
- # Pass true, if you want to also have not published elements.
141
- #
142
- # @option options [Array] only
143
- # Returns only elements with given names
144
- # @option options [Array] except
145
- # Returns all elements except the ones with given names
146
- # @option options [Fixnum] count
147
- # Limit the count of returned elements
148
- # @option options [Fixnum] offset
149
- # Starts with an offset while returning elements
150
- # @option options [Boolean] random (false)
151
- # Return elements randomly shuffled
152
- # @option options [Alchemy::Cell || String] from_cell
153
- # Return elements from given cell
154
- #
155
- # @return [ActiveRecord::Relation]
156
- #
157
- def find_elements(options = {}, show_non_public = false)
158
- elements = elements_from_cell_or_self(options[:from_cell])
159
- if options[:only].present?
160
- elements = elements.named(options[:only])
161
- elsif options[:except].present?
162
- elements = elements.excluded(options[:except])
163
- end
164
- if options[:reverse_sort] || options[:reverse]
165
- elements = elements.reverse_order
166
- end
167
- elements = elements.offset(options[:offset]).limit(options[:count])
168
- if options[:random]
169
- elements = elements.order("RAND()")
170
- end
171
- show_non_public ? elements : elements.published
172
- end
173
- alias_method :find_selected_elements, :find_elements
174
-
175
191
  # Returns all elements that should be feeded via rss.
176
192
  #
177
193
  # Define feedable elements in your +page_layouts.yml+:
@@ -181,17 +197,30 @@ module Alchemy
181
197
  # feed_elements: [element_name, element_2_name]
182
198
  #
183
199
  def feed_elements
184
- elements.named(definition['feed_elements'])
200
+ elements.available.named(definition['feed_elements'])
185
201
  end
186
202
 
187
- # Returns an array of all EssenceRichtext contents ids
203
+ # Returns an array of all EssenceRichtext contents ids from not folded elements
188
204
  #
189
205
  def richtext_contents_ids
190
- contents.essence_richtexts.pluck("#{Content.table_name}.id")
206
+ descendent_contents
207
+ .where(Element.table_name => {folded: false})
208
+ .select(&:has_tinymce?)
209
+ .collect(&:id)
210
+ end
211
+
212
+ def element_names_from_definition
213
+ definition['elements'] || []
191
214
  end
192
215
 
193
216
  private
194
217
 
218
+ def element_names_from_cell_definitions
219
+ @_element_names_from_cell_definitions ||= cell_definitions.map do |d|
220
+ d['elements']
221
+ end.flatten
222
+ end
223
+
195
224
  # Looks in the page_layout descripion, if there are elements to autogenerate.
196
225
  #
197
226
  # And if so, it generates them.
@@ -199,8 +228,8 @@ module Alchemy
199
228
  # If the page has cells, it looks if there are elements to generate.
200
229
  #
201
230
  def autogenerate_elements
202
- elements_already_on_page = self.elements.available.pluck(:name)
203
- elements = self.layout_description["autogenerate"]
231
+ elements_already_on_page = elements.available.pluck(:name)
232
+ elements = definition["autogenerate"]
204
233
  if elements.present?
205
234
  elements.each do |element|
206
235
  next if elements_already_on_page.include?(element)
@@ -211,37 +240,39 @@ module Alchemy
211
240
 
212
241
  # Returns a hash of attributes for given element name
213
242
  def attributes_for_element_name(element)
214
- if self.has_cells? && (cell_definition = cell_definitions.detect { |c| c['elements'].include?(element) })
215
- cell = self.cells.find_by_name(cell_definition['name'])
216
- if cell
217
- return {:page_id => self.id, :cell_id => cell.id, :name => element}
218
- else
219
- raise "Cell not found for page #{self.inspect}"
220
- end
243
+ element_cell_definition = cell_definitions.detect { |c| c['elements'].include?(element) }
244
+ if has_cells? && element_cell_definition
245
+ cell = cells.find_by!(name: element_cell_definition['name'])
246
+ {page_id: id, cell_id: cell.id, name: element}
221
247
  else
222
- return {:page_id => self.id, :name => element}
248
+ {page_id: id, name: element}
223
249
  end
224
250
  end
225
251
 
226
252
  # Trashes all elements that are not allowed for this page_layout.
227
- def trash_not_allowed_elements
228
- elements.select { |e| !definition['elements'].include?(e.name) }.map(&:trash!)
253
+ def trash_not_allowed_elements!
254
+ not_allowed_elements = elements.where([
255
+ "#{Element.table_name}.name NOT IN (?)",
256
+ element_names_from_definition
257
+ ])
258
+ not_allowed_elements.to_a.map(&:trash!)
229
259
  end
230
260
 
231
- # Deletes unique and already present definitions from @elements_for_layout.
261
+ # Deletes unique and already present definitions from @_element_definitions.
232
262
  #
233
263
  def delete_unique_element_definitions!
234
- @elements_for_layout.delete_if { |element|
235
- element['unique'] && @page_element_names.include?(element['name'])
236
- }
264
+ @_element_definitions.delete_if do |element|
265
+ element['unique'] && @_existing_element_names.include?(element['name'])
266
+ end
237
267
  end
238
268
 
239
- # Deletes limited and outnumbered definitions from @elements_for_layout.
269
+ # Deletes limited and outnumbered definitions from @_element_definitions.
240
270
  #
241
271
  def delete_outnumbered_element_definitions!
242
- @elements_for_layout.delete_if { |element|
243
- element['amount'] && @page_element_names.select { |i| i == element['name'] }.count >= element['amount'].to_i
244
- }
272
+ @_element_definitions.delete_if do |element|
273
+ outnumbered = @_existing_element_names.select { |name| name == element['name'] }
274
+ element['amount'] && outnumbered.count >= element['amount'].to_i
275
+ end
245
276
  end
246
277
 
247
278
  # Returns elements either from given cell or self
@@ -253,7 +284,7 @@ module Alchemy
253
284
  when 'String'
254
285
  cell_elements_by_name(cell)
255
286
  else
256
- self.elements.not_in_cell
287
+ elements.not_in_cell
257
288
  end
258
289
  end
259
290
 
@@ -267,6 +298,5 @@ module Alchemy
267
298
  Element.none
268
299
  end
269
300
  end
270
-
271
301
  end
272
302
  end