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
@@ -0,0 +1,34 @@
1
+ module Alchemy
2
+ module OnPageLayout
3
+ # Runs OnPageLayout callbacks
4
+ #
5
+ # Included in +Alchemy::PagesController+ and +Alchemy::Admin::PagesController+
6
+ #
7
+ # @see OnPageLayout in order to learn how to define +on_page_layout+ callbacks.
8
+ #
9
+ module CallbacksRunner
10
+ private
11
+
12
+ def run_on_page_layout_callbacks?
13
+ OnPageLayout.callbacks.present?
14
+ end
15
+
16
+ def run_on_page_layout_callbacks
17
+ OnPageLayout.callbacks.each do |page_layout, callbacks|
18
+ next unless call_page_layout_callback_for?(page_layout)
19
+ callbacks.each do |callback|
20
+ if callback.respond_to?(:call)
21
+ instance_eval(&callback)
22
+ else
23
+ send(callback)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def call_page_layout_callback_for?(page_layout)
30
+ page_layout.to_sym == :all || @page.page_layout.to_sym == page_layout.to_sym
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,22 +1,21 @@
1
1
  module Alchemy
2
2
  class PageLayout
3
3
  class << self
4
-
5
4
  # Returns all page layouts.
6
5
  #
7
6
  # They are defined in +config/alchemy/page_layout.yml+ file.
8
7
  #
9
8
  def all
10
- @definitions ||= read_layouts_file
9
+ @definitions ||= read_definitions_file
11
10
  end
12
11
 
13
- # Add additional page layout definitions to collection.
12
+ # Add additional page definitions to collection.
14
13
  #
15
14
  # Useful for extending the page layouts from an Alchemy module.
16
15
  #
17
16
  # === Usage Example
18
17
  #
19
- # Call +Alchemy::PageLayout.add(your_layout_definition)+ in your engine.rb file.
18
+ # Call +Alchemy::PageLayout.add(your_definition)+ in your engine.rb file.
20
19
  #
21
20
  # @param [Array || Hash]
22
21
  # You can pass a single layout definition as Hash, or a collection of page layouts as Array.
@@ -32,31 +31,32 @@ module Alchemy
32
31
  end
33
32
  end
34
33
 
35
- # Returns one page layout description by given name.
34
+ # Returns one page definition by given name.
36
35
  #
37
36
  def get(name)
38
37
  return {} if name.blank?
39
- all.detect { |a| a['name'].downcase == name.downcase }
38
+ all.detect { |a| a['name'].casecmp(name) == 0 }
40
39
  end
41
40
 
42
41
  def get_all_by_attributes(attributes)
43
42
  return [] if attributes.blank?
44
- if attributes.class.name == 'Hash'
43
+
44
+ if attributes.is_a? Hash
45
45
  layouts = []
46
46
  attributes.stringify_keys.each do |key, value|
47
- result = all.select { |a| a[key].to_s.downcase == value.to_s.downcase if a.has_key?(key) }
47
+ result = all.select { |l| l.key?(key) && l[key].to_s.casecmp(value.to_s) == 0 }
48
48
  layouts += result unless result.empty?
49
49
  end
50
- return layouts
50
+ layouts
51
51
  else
52
- return []
52
+ []
53
53
  end
54
54
  end
55
55
 
56
56
  # Returns page layouts ready for Rails' select form helper.
57
57
  #
58
58
  def layouts_for_select(language_id, only_layoutpages = false)
59
- @map_array = [[I18n.t('Please choose'), '']]
59
+ @map_array = [[Alchemy.t('Please choose'), '']]
60
60
  mapped_layouts_for_select(selectable_layouts(language_id, only_layoutpages))
61
61
  end
62
62
 
@@ -83,22 +83,22 @@ module Alchemy
83
83
  #
84
84
  def selectable_layouts(language_id, only_layoutpages = false)
85
85
  @language_id = language_id
86
- all.select { |layout|
86
+ all.select do |layout|
87
87
  if only_layoutpages
88
88
  layout['layoutpage'] && layout_available?(layout)
89
89
  else
90
90
  !layout['layoutpage'] && layout_available?(layout)
91
91
  end
92
- }
92
+ end
93
93
  end
94
94
 
95
95
  # Returns all names of elements defined in given page layout.
96
96
  #
97
97
  def element_names_for(page_layout)
98
- if layout_description = get(page_layout)
99
- layout_description.fetch('elements', [])
98
+ if definition = get(page_layout)
99
+ definition.fetch('elements', [])
100
100
  else
101
- Rails.logger.warn "\n+++ Warning: No Layout Description for #{page_layout} found! in page_layouts.yml\n"
101
+ Rails.logger.warn "\n+++ Warning: No layout definition for #{page_layout} found! in page_layouts.yml\n"
102
102
  return []
103
103
  end
104
104
  end
@@ -107,19 +107,19 @@ module Alchemy
107
107
  #
108
108
  # === Translation example
109
109
  #
110
- # de:
110
+ # en:
111
111
  # alchemy:
112
112
  # page_layout_names:
113
- # products_overview: Produktübersicht
113
+ # products_overview: Products Overview
114
114
  #
115
115
  # @param [String]
116
116
  # The layout name
117
117
  #
118
118
  def human_layout_name(layout)
119
- I18n.t(layout, scope: 'page_layout_names', default: layout.to_s.humanize)
119
+ Alchemy.t(layout, scope: 'page_layout_names', default: layout.to_s.humanize)
120
120
  end
121
121
 
122
- private
122
+ private
123
123
 
124
124
  # Returns true if the given layout is unique and not already taken or it should be hidden.
125
125
  #
@@ -150,13 +150,13 @@ module Alchemy
150
150
  # page_layouts: [default_intro]
151
151
  #
152
152
  def available_on_site?(layout)
153
- Site.current.layout_definition.blank? || Site.current.layout_definition.fetch('page_layouts', []).include?(layout['name'])
153
+ Site.current.definition.blank? || Site.current.definition.fetch('page_layouts', []).include?(layout['name'])
154
154
  end
155
155
 
156
156
  # Reads the layout definitions from +config/alchemy/page_layouts.yml+.
157
157
  #
158
- def read_layouts_file
159
- if File.exists?(layouts_file_path)
158
+ def read_definitions_file
159
+ if File.exist?(layouts_file_path)
160
160
  YAML.load(ERB.new(File.read(layouts_file_path)).result) || []
161
161
  else
162
162
  raise LoadError, "Could not find page_layouts.yml file! Please run `rails generate alchemy:scaffold`"
@@ -177,7 +177,6 @@ module Alchemy
177
177
  end
178
178
  @map_array
179
179
  end
180
-
181
180
  end
182
181
  end
183
182
  end
@@ -0,0 +1,32 @@
1
+ # Provides admin interface routing configuration accessors.
2
+ #
3
+ # Alchemy has some defaults for admin path and admin constraints:
4
+ #
5
+ # +Alchemy.admin_path defaults to +'/admin'+
6
+ # +Alchemy.admin_constraints defaults to +{}+
7
+ #
8
+ # Anyway, you can tell Alchemy about your routing configuration:
9
+ #
10
+ # 1. The path to the admin panel - @see: Alchemy.admin_path
11
+ # 2. The constraints for the admin panel (like subdomain) - @see: Alchemy.admin_constraints
12
+ #
13
+ # A word of caution: you need to know what you are doing if you set admin_path to ''. This can cause
14
+ # routing name clashes, e.g. a page named 'dashboard' will clash with the Alchemy dashboard.
15
+ #
16
+ # == Example
17
+ #
18
+ # If you do not wish to use the default admin interface routing ('example.com/admin/')
19
+ # and prefer e.g. 'hidden.example.com/backend/', those are the settings you need:
20
+ #
21
+ # # config/initializers/alchemy.rb
22
+ # Alchemy.admin_path = '/backend'
23
+ # Alchemy.admin_constraints = {subdomain: 'hidden'}
24
+ #
25
+ module Alchemy
26
+ mattr_accessor :admin_path, :admin_constraints
27
+
28
+ # Defaults
29
+ #
30
+ @@admin_path = '/admin'
31
+ @@admin_constraints = {}
32
+ end
@@ -1,5 +1,4 @@
1
1
  module Alchemy
2
-
3
2
  # ## Alchemy's permissions
4
3
  #
5
4
  # These are CanCan abilities, but to prevent any naming collusions we named it permissions.
@@ -21,7 +20,6 @@ module Alchemy
21
20
  # # your own rules
22
21
  # end
23
22
  # end
24
- #
25
23
  # end
26
24
  #
27
25
  class Permissions
@@ -36,17 +34,20 @@ module Alchemy
36
34
  module GuestUser
37
35
  def alchemy_guest_user_rules
38
36
  can([:show, :download], Alchemy::Attachment) { |a| !a.restricted? }
39
- can :read, Alchemy::Content, Alchemy::Content.available.not_restricted do |c|
37
+ can :see, Alchemy::Page, restricted: false, visible: true
38
+ can(:display, Alchemy::Picture) { |p| !p.restricted? }
39
+
40
+ can :read, Alchemy::Content, Alchemy::Content.available.not_restricted do |c|
40
41
  c.public? && !c.restricted? && !c.trashed?
41
42
  end
42
- can :read, Alchemy::Element, Alchemy::Element.available.not_restricted do |e|
43
+
44
+ can :read, Alchemy::Element, Alchemy::Element.available.not_restricted do |e|
43
45
  e.public? && !e.restricted? && !e.trashed?
44
46
  end
45
- can :read, Alchemy::Page, Alchemy::Page.published.not_restricted do |p|
47
+
48
+ can :read, Alchemy::Page, Alchemy::Page.published.not_restricted do |p|
46
49
  p.public? && !p.restricted?
47
50
  end
48
- can :see, Alchemy::Page, restricted: false, visible: true
49
- can(:display, Alchemy::Picture) { |p| !p.restricted? }
50
51
  end
51
52
  end
52
53
 
@@ -62,18 +63,17 @@ module Alchemy
62
63
 
63
64
  # Resources
64
65
  can [:show, :download], Alchemy::Attachment
65
- can :read, Alchemy::Content, Alchemy::Content.available do |c|
66
+ can :read, Alchemy::Page, Alchemy::Page.published, &:public?
67
+ can :see, Alchemy::Page, restricted: true, visible: true
68
+ can :display, Alchemy::Picture
69
+
70
+ can :read, Alchemy::Content, Alchemy::Content.available do |c|
66
71
  c.public? && !c.trashed?
67
72
  end
68
- can :read, Alchemy::Element, Alchemy::Element.available do |e|
73
+
74
+ can :read, Alchemy::Element, Alchemy::Element.available do |e|
69
75
  e.public? && !e.trashed?
70
76
  end
71
- can :read, Alchemy::Page, Alchemy::Page.published do |p|
72
- p.public?
73
- end
74
- can :see, Alchemy::Page, restricted: true, visible: true
75
- can :display, Alchemy::Picture
76
- can [:read, :update], Alchemy.user_class, id: @user.id
77
77
  end
78
78
  end
79
79
 
@@ -104,6 +104,7 @@ module Alchemy
104
104
  can :manage, :alchemy_admin_clipboard
105
105
  can :index, :trash
106
106
  can :edit, :alchemy_admin_layoutpages
107
+ can :tree, :alchemy_admin_pages
107
108
 
108
109
  # Resources
109
110
  can [:read, :download], Alchemy::Attachment
@@ -113,7 +114,7 @@ module Alchemy
113
114
  can :manage, Alchemy::EssencePicture
114
115
  can :manage, Alchemy::LegacyPageUrl
115
116
  can :edit_content, Alchemy::Page
116
- can [:read, :info], Alchemy::Picture
117
+ can :read, Alchemy::Picture
117
118
  can [:read, :autocomplete], Alchemy::Tag
118
119
  end
119
120
  end
@@ -135,7 +136,7 @@ module Alchemy
135
136
  ]
136
137
 
137
138
  # Controller actions
138
- can :clear, :trash
139
+ can :clear, :trash
139
140
 
140
141
  # Resources
141
142
  can [
@@ -149,10 +150,11 @@ module Alchemy
149
150
  :sort,
150
151
  :switch_language
151
152
  ], Alchemy::Page
153
+
152
154
  can :manage, Alchemy::Picture
153
155
  can :manage, Alchemy::Attachment
154
- can :read, Alchemy.user_class
155
156
  can :manage, Alchemy::Tag
157
+ can :index, Alchemy::Language
156
158
  end
157
159
  end
158
160
 
@@ -173,7 +175,6 @@ module Alchemy
173
175
  can [:info, :update_check], :alchemy_admin_dashboard
174
176
 
175
177
  # Resources
176
- can :manage, Alchemy.user_class
177
178
  can :manage, Alchemy::Language
178
179
  can :manage, Alchemy::Site
179
180
  end
@@ -216,6 +217,5 @@ module Alchemy
216
217
  include AuthorUser
217
218
  include EditorUser
218
219
  include AdminUser
219
-
220
220
  end
221
221
  end
@@ -2,11 +2,9 @@ module Alchemy
2
2
  # Provides methods to secure your picture attributes against DOS attacks.
3
3
  #
4
4
  class PictureAttributes
5
-
6
5
  SECURE_ATTRIBUTES = %w(id size crop crop_from crop_size quality upsample).freeze
7
6
 
8
7
  class << self
9
-
10
8
  # Secures given attributes
11
9
  #
12
10
  # @param attributes [Hash]
@@ -23,7 +21,6 @@ module Alchemy
23
21
  def joined_attributes(attributes)
24
22
  attributes.stringify_keys.values_at(*SECURE_ATTRIBUTES, Rails.configuration.secret_token).join('-')
25
23
  end
26
-
27
24
  end
28
25
  end
29
26
  end
@@ -1,5 +1,6 @@
1
- require 'active_support/inflector'
1
+ require 'active_support'
2
2
  require 'active_support/core_ext'
3
+ require 'active_support/inflector'
3
4
 
4
5
  module Alchemy
5
6
  # = Alchemy::Resource
@@ -84,20 +85,18 @@ module Alchemy
84
85
  # resource = Resource.new('/admin/tags', {"engine_name"=>"alchemy"}, ActsAsTaggableOn::Tag)
85
86
  #
86
87
  class Resource
87
- attr_accessor :skipped_attributes, :restricted_attributes, :resource_relations, :model_associations
88
+ attr_accessor :resource_relations, :model_associations
88
89
  attr_reader :model
89
90
 
90
91
  DEFAULT_SKIPPED_ATTRIBUTES = %w(id updated_at created_at creator_id updater_id)
91
92
  DEFAULT_SKIPPED_ASSOCIATIONS = %w(creator updater)
92
93
 
93
- def initialize(controller_path, module_definition=nil, custom_model=nil)
94
+ def initialize(controller_path, module_definition = nil, custom_model = nil)
94
95
  @controller_path = controller_path
95
96
  @module_definition = module_definition
96
- @model = (custom_model or guess_model_from_controller_path)
97
- self.skipped_attributes = model.respond_to?(:skipped_alchemy_resource_attributes) ? model.skipped_alchemy_resource_attributes : DEFAULT_SKIPPED_ATTRIBUTES
98
- self.restricted_attributes = model.respond_to?(:restricted_alchemy_resource_attributes) ? model.restricted_alchemy_resource_attributes : []
97
+ @model = (custom_model || guess_model_from_controller_path)
99
98
  if model.respond_to?(:alchemy_resource_relations)
100
- if not model.respond_to?(:reflect_on_all_associations)
99
+ if !model.respond_to?(:reflect_on_all_associations)
101
100
  raise MissingActiveRecordAssociation
102
101
  end
103
102
  store_model_associations
@@ -140,19 +139,18 @@ module Alchemy
140
139
  end
141
140
 
142
141
  def attributes
143
- @_attributes ||= self.model.columns.collect do |col|
144
- unless self.skipped_attributes.include?(col.name)
145
- {
146
- name: col.name,
147
- type: resource_column_type(col),
148
- relation: resource_relation(col.name)
149
- }.delete_if { |k, v| v.nil? }
150
- end
142
+ @_attributes ||= model.columns.collect do |col|
143
+ next if skipped_attributes.include?(col.name)
144
+ {
145
+ name: col.name,
146
+ type: resource_column_type(col),
147
+ relation: resource_relation(col.name)
148
+ }.delete_if { |_k, v| v.nil? }
151
149
  end.compact
152
150
  end
153
151
 
154
152
  def editable_attributes
155
- attributes.reject { |h| self.restricted_attributes.map(&:to_s).include?(h[:name].to_s) }
153
+ attributes.reject { |h| restricted_attributes.map(&:to_s).include?(h[:name].to_s) }
156
154
  end
157
155
 
158
156
  # Returns all columns that are searchable
@@ -160,15 +158,23 @@ module Alchemy
160
158
  # For now it only uses string type columns
161
159
  #
162
160
  def searchable_attributes
163
- self.attributes.select { |a| a[:type].to_sym == :string }
161
+ attributes.select { |a| string_attribute?(a) } + searchable_relation_attributes?(attributes)
162
+ end
163
+
164
+ # Search field input name
165
+ #
166
+ # Joins all searchable attributes into a Ransack compatible search query
167
+ #
168
+ def search_field_name
169
+ searchable_attributes.collect { |a| a[:name] }.join("_or_") + "_cont"
164
170
  end
165
171
 
166
172
  def in_engine?
167
- not self.engine_name.nil?
173
+ !engine_name.nil?
168
174
  end
169
175
 
170
176
  def engine_name
171
- @module_definition and @module_definition['engine_name']
177
+ @module_definition && @module_definition['engine_name']
172
178
  end
173
179
 
174
180
  # Returns a help text for resource's form
@@ -182,13 +188,52 @@ module Alchemy
182
188
  # attribute_name: This is the fancy help text
183
189
  #
184
190
  def help_text_for(attribute)
185
- ::I18n.translate!(attribute[:name], :scope => [:alchemy, :resource_help_texts, resource_name])
191
+ ::I18n.translate!(attribute[:name], scope: [:alchemy, :resource_help_texts, resource_name])
186
192
  rescue ::I18n::MissingTranslationData
187
193
  false
188
194
  end
189
195
 
196
+ # Return attributes that should be viewable but not editable.
197
+ #
198
+ def restricted_attributes
199
+ if model.respond_to?(:restricted_alchemy_resource_attributes)
200
+ model.restricted_alchemy_resource_attributes
201
+ else
202
+ []
203
+ end
204
+ end
205
+
206
+ # Return attributes that should neither be viewable nor editable.
207
+ #
208
+ def skipped_attributes
209
+ if model.respond_to?(:skipped_alchemy_resource_attributes)
210
+ model.skipped_alchemy_resource_attributes
211
+ else
212
+ DEFAULT_SKIPPED_ATTRIBUTES
213
+ end
214
+ end
215
+
190
216
  private
191
217
 
218
+ def string_attribute?(a)
219
+ a[:type].to_sym == :string && !a.key?(:relation)
220
+ end
221
+
222
+ def string_attribute_on_relation?(a)
223
+ a.key?(:relation) && a[:relation][:attr_type].to_sym == :string
224
+ end
225
+
226
+ def searchable_relation_attributes?(attrs)
227
+ attrs.select { |a| string_attribute_on_relation?(a) }.map { |a| searchable_relation_attribute(a) }
228
+ end
229
+
230
+ def searchable_relation_attribute(a)
231
+ {
232
+ name: "#{a[:relation][:model_association].name}_#{a[:relation][:attr_method]}",
233
+ type: a[:relation][:attr_type]
234
+ }
235
+ end
236
+
192
237
  def guess_model_from_controller_path
193
238
  resource_array.join('/').classify.constantize
194
239
  end
@@ -220,7 +265,7 @@ module Alchemy
220
265
  name = name.to_s.gsub(/_id$/, '') # ensure that we don't have an id
221
266
  association = association_from_relation_name(name)
222
267
  foreign_key = association.options[:foreign_key] || "#{association.name}_id".to_sym
223
- self.resource_relations[foreign_key] = options.merge(:model_association => association, :name => name)
268
+ resource_relations[foreign_key] = options.merge(model_association: association, name: name)
224
269
  end
225
270
  end
226
271
 
@@ -233,6 +278,5 @@ module Alchemy
233
278
  def association_from_relation_name(name)
234
279
  model_associations.detect { |a| a.name == name.to_sym }
235
280
  end
236
-
237
281
  end
238
282
  end