alchemy_cms 4.4.4 → 5.0.0.beta2

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 (386) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +56 -18
  3. data/.github/workflows/stale.yml +1 -1
  4. data/.gitignore +20 -2
  5. data/.hound.yml +2 -1
  6. data/.prettierrc +6 -0
  7. data/.rubocop.yml +33 -20
  8. data/CHANGELOG.md +121 -0
  9. data/Gemfile +24 -22
  10. data/README.md +31 -19
  11. data/Rakefile +10 -8
  12. data/alchemy_cms.gemspec +7 -5
  13. data/app/assets/javascripts/alchemy/admin.js +1 -2
  14. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +2 -1
  15. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -2
  16. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +5 -5
  17. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +17 -17
  18. data/app/assets/javascripts/alchemy/node_select.js +39 -0
  19. data/app/assets/javascripts/alchemy/templates/index.js +2 -0
  20. data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
  21. data/app/assets/javascripts/alchemy/templates/node_folder.hbs +3 -0
  22. data/app/assets/javascripts/alchemy/templates/page.hbs +1 -1
  23. data/app/assets/stylesheets/alchemy/_mixins.scss +2 -3
  24. data/app/assets/stylesheets/alchemy/_variables.scss +2 -2
  25. data/app/assets/stylesheets/alchemy/admin.scss +3 -2
  26. data/app/assets/stylesheets/alchemy/base.scss +0 -1
  27. data/app/assets/stylesheets/alchemy/elements.scss +1 -1
  28. data/app/assets/stylesheets/alchemy/forms.scss +5 -0
  29. data/app/assets/stylesheets/alchemy/lists.scss +0 -8
  30. data/app/assets/stylesheets/alchemy/node-select.scss +43 -0
  31. data/app/assets/stylesheets/alchemy/nodes.scss +6 -1
  32. data/app/assets/stylesheets/alchemy/sitemap.scss +63 -21
  33. data/app/assets/stylesheets/alchemy/tables.scss +1 -24
  34. data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
  35. data/app/controllers/alchemy/admin/base_controller.rb +13 -33
  36. data/app/controllers/alchemy/admin/clipboard_controller.rb +5 -4
  37. data/app/controllers/alchemy/admin/contents_controller.rb +1 -2
  38. data/app/controllers/alchemy/admin/dashboard_controller.rb +10 -9
  39. data/app/controllers/alchemy/admin/elements_controller.rb +20 -20
  40. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +12 -14
  41. data/app/controllers/alchemy/admin/languages_controller.rb +35 -2
  42. data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -2
  43. data/app/controllers/alchemy/admin/nodes_controller.rb +5 -14
  44. data/app/controllers/alchemy/admin/pages_controller.rb +50 -63
  45. data/app/controllers/alchemy/admin/pictures_controller.rb +16 -16
  46. data/app/controllers/alchemy/admin/resources_controller.rb +21 -13
  47. data/app/controllers/alchemy/admin/sites_controller.rb +18 -0
  48. data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
  49. data/app/controllers/alchemy/admin/tags_controller.rb +5 -3
  50. data/app/controllers/alchemy/admin/trash_controller.rb +6 -6
  51. data/app/controllers/alchemy/api/base_controller.rb +2 -2
  52. data/app/controllers/alchemy/api/contents_controller.rb +4 -4
  53. data/app/controllers/alchemy/api/elements_controller.rb +8 -8
  54. data/app/controllers/alchemy/api/nodes_controller.rb +65 -0
  55. data/app/controllers/alchemy/api/pages_controller.rb +15 -22
  56. data/app/controllers/alchemy/attachments_controller.rb +5 -5
  57. data/app/controllers/alchemy/base_controller.rb +10 -9
  58. data/app/controllers/alchemy/messages_controller.rb +16 -23
  59. data/app/controllers/alchemy/pages_controller.rb +13 -11
  60. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +3 -2
  61. data/app/controllers/concerns/alchemy/admin/current_language.rb +23 -0
  62. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -5
  63. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +4 -4
  64. data/app/controllers/concerns/alchemy/page_redirects.rb +2 -9
  65. data/app/controllers/concerns/alchemy/site_redirects.rb +2 -2
  66. data/app/decorators/alchemy/content_editor.rb +55 -0
  67. data/app/decorators/alchemy/element_editor.rb +39 -0
  68. data/app/helpers/alchemy/admin/attachments_helper.rb +6 -6
  69. data/app/helpers/alchemy/admin/base_helper.rb +36 -35
  70. data/app/helpers/alchemy/admin/contents_helper.rb +3 -3
  71. data/app/helpers/alchemy/admin/elements_helper.rb +3 -88
  72. data/app/helpers/alchemy/admin/essences_helper.rb +8 -117
  73. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  74. data/app/helpers/alchemy/admin/navigation_helper.rb +24 -23
  75. data/app/helpers/alchemy/admin/pages_helper.rb +12 -12
  76. data/app/helpers/alchemy/admin/pictures_helper.rb +4 -6
  77. data/app/helpers/alchemy/admin/tags_helper.rb +8 -7
  78. data/app/helpers/alchemy/base_helper.rb +13 -8
  79. data/app/helpers/alchemy/elements_block_helper.rb +2 -31
  80. data/app/helpers/alchemy/elements_helper.rb +12 -58
  81. data/app/helpers/alchemy/pages_helper.rb +24 -174
  82. data/app/helpers/alchemy/url_helper.rb +2 -1
  83. data/app/mailers/alchemy/base_mailer.rb +1 -1
  84. data/app/mailers/alchemy/messages_mailer.rb +1 -1
  85. data/app/models/alchemy/attachment.rb +20 -18
  86. data/app/models/alchemy/base_record.rb +2 -5
  87. data/app/models/alchemy/content.rb +33 -52
  88. data/app/models/alchemy/content/factory.rb +24 -31
  89. data/app/models/alchemy/element.rb +45 -53
  90. data/app/models/alchemy/element/definitions.rb +4 -4
  91. data/app/models/alchemy/element/element_contents.rb +9 -6
  92. data/app/models/alchemy/element/element_essences.rb +4 -3
  93. data/app/models/alchemy/element/presenters.rb +3 -2
  94. data/app/models/alchemy/element_to_page.rb +1 -1
  95. data/app/models/alchemy/essence_boolean.rb +1 -3
  96. data/app/models/alchemy/essence_date.rb +2 -3
  97. data/app/models/alchemy/essence_file.rb +4 -4
  98. data/app/models/alchemy/essence_html.rb +1 -3
  99. data/app/models/alchemy/essence_link.rb +1 -3
  100. data/app/models/alchemy/essence_node.rb +18 -0
  101. data/app/models/alchemy/essence_page.rb +3 -16
  102. data/app/models/alchemy/essence_picture.rb +17 -16
  103. data/app/models/alchemy/essence_picture_view.rb +7 -6
  104. data/app/models/alchemy/essence_richtext.rb +1 -3
  105. data/app/models/alchemy/essence_select.rb +1 -3
  106. data/app/models/alchemy/essence_text.rb +0 -2
  107. data/app/models/alchemy/folded_page.rb +1 -0
  108. data/app/models/alchemy/language.rb +21 -35
  109. data/app/models/alchemy/language/code.rb +4 -4
  110. data/app/models/alchemy/legacy_page_url.rb +1 -1
  111. data/app/models/alchemy/message.rb +3 -3
  112. data/app/models/alchemy/node.rb +55 -9
  113. data/app/models/alchemy/page.rb +53 -123
  114. data/app/models/alchemy/page/fixed_attributes.rb +3 -2
  115. data/app/models/alchemy/page/page_elements.rb +35 -44
  116. data/app/models/alchemy/page/page_naming.rb +20 -70
  117. data/app/models/alchemy/page/page_natures.rb +7 -34
  118. data/app/models/alchemy/page/page_scopes.rb +23 -29
  119. data/app/models/alchemy/page/url_path.rb +64 -0
  120. data/app/models/alchemy/picture.rb +40 -30
  121. data/app/models/alchemy/picture/preprocessor.rb +26 -0
  122. data/app/models/alchemy/picture/transformations.rb +9 -7
  123. data/app/models/alchemy/picture/url.rb +5 -5
  124. data/app/models/alchemy/site.rb +6 -36
  125. data/app/models/alchemy/site/layout.rb +2 -2
  126. data/app/models/concerns/alchemy/touch_elements.rb +24 -0
  127. data/app/serializers/alchemy/content_serializer.rb +0 -3
  128. data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
  129. data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
  130. data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
  131. data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
  132. data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
  133. data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
  134. data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
  135. data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
  136. data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
  137. data/app/serializers/alchemy/node_serializer.rb +14 -0
  138. data/app/serializers/alchemy/page_serializer.rb +2 -1
  139. data/app/serializers/alchemy/page_tree_serializer.rb +11 -14
  140. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
  141. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
  142. data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
  143. data/app/views/alchemy/admin/contents/create.js.erb +1 -3
  144. data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
  145. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  146. data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
  147. data/app/views/alchemy/admin/elements/index.html.erb +3 -3
  148. data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
  149. data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
  150. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
  151. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
  152. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
  153. data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
  154. data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
  155. data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
  156. data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
  157. data/app/views/alchemy/admin/languages/index.html.erb +23 -4
  158. data/app/views/alchemy/admin/languages/new.html.erb +1 -0
  159. data/app/views/alchemy/admin/layoutpages/index.html.erb +6 -2
  160. data/app/views/alchemy/admin/nodes/_form.html.erb +23 -15
  161. data/app/views/alchemy/admin/nodes/_node.html.erb +5 -19
  162. data/app/views/alchemy/admin/nodes/index.html.erb +3 -18
  163. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
  164. data/app/views/alchemy/admin/pages/_form.html.erb +1 -2
  165. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
  166. data/app/views/alchemy/admin/pages/_page.html.erb +14 -25
  167. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
  168. data/app/views/alchemy/admin/pages/_sitemap.html.erb +6 -0
  169. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  170. data/app/views/alchemy/admin/pages/info.html.erb +0 -9
  171. data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
  172. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
  173. data/app/views/alchemy/admin/partials/_routes.html.erb +8 -0
  174. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
  175. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  176. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
  177. data/app/views/alchemy/admin/pictures/index.html.erb +18 -3
  178. data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
  179. data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
  180. data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
  181. data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
  182. data/app/views/alchemy/admin/sites/index.html.erb +21 -9
  183. data/app/views/alchemy/admin/sites/new.html.erb +1 -0
  184. data/app/views/alchemy/admin/tags/index.html.erb +2 -2
  185. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
  186. data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
  187. data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
  188. data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
  189. data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
  190. data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
  191. data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
  192. data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
  193. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
  194. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
  195. data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
  196. data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
  197. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
  198. data/app/views/alchemy/pages/show.rss.builder +3 -2
  199. data/app/views/layouts/alchemy/admin.html.erb +1 -0
  200. data/babel.config.js +12 -0
  201. data/bin/rails +5 -4
  202. data/config/alchemy/config.yml +23 -22
  203. data/config/brakeman.ignore +1 -1
  204. data/config/initializers/assets.rb +2 -1
  205. data/config/initializers/dragonfly.rb +2 -1
  206. data/config/initializers/mime_types.rb +1 -0
  207. data/config/initializers/mini_profiler.rb +3 -2
  208. data/config/initializers/simple_form.rb +6 -6
  209. data/config/locales/alchemy.en.yml +37 -14
  210. data/config/routes.rb +32 -28
  211. data/config/spring.rb +3 -2
  212. data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
  213. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
  214. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
  215. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
  216. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
  217. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
  218. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
  219. data/lib/alchemy/admin/locale.rb +3 -1
  220. data/lib/alchemy/admin/preview_url.rb +85 -0
  221. data/lib/alchemy/auth_accessors.rb +8 -7
  222. data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
  223. data/lib/alchemy/config.rb +26 -2
  224. data/lib/alchemy/configuration_methods.rb +3 -1
  225. data/lib/alchemy/controller_actions.rb +6 -5
  226. data/lib/alchemy/deprecation.rb +2 -1
  227. data/lib/alchemy/elements_finder.rb +5 -5
  228. data/lib/alchemy/engine.rb +23 -8
  229. data/lib/alchemy/errors.rb +0 -7
  230. data/lib/alchemy/essence.rb +17 -16
  231. data/lib/alchemy/filetypes.rb +5 -5
  232. data/lib/alchemy/forms/builder.rb +4 -4
  233. data/lib/alchemy/hints.rb +1 -1
  234. data/lib/alchemy/i18n.rb +2 -1
  235. data/lib/alchemy/modules.rb +12 -12
  236. data/lib/alchemy/name_conversions.rb +5 -5
  237. data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
  238. data/lib/alchemy/page_layout.rb +15 -12
  239. data/lib/alchemy/paths.rb +1 -1
  240. data/lib/alchemy/permissions.rb +7 -6
  241. data/lib/alchemy/resource.rb +23 -13
  242. data/lib/alchemy/resources_helper.rb +12 -18
  243. data/lib/alchemy/routing_constraints.rb +1 -1
  244. data/lib/alchemy/seeder.rb +42 -14
  245. data/lib/alchemy/shell.rb +13 -10
  246. data/lib/alchemy/taggable.rb +1 -0
  247. data/lib/alchemy/tasks/tidy.rb +4 -3
  248. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  249. data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
  250. data/lib/alchemy/test_support/factories.rb +1 -1
  251. data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
  252. data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
  253. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
  254. data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
  255. data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
  256. data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
  257. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
  258. data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
  259. data/lib/alchemy/test_support/factories/language_factory.rb +21 -14
  260. data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
  261. data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
  262. data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
  263. data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
  264. data/lib/alchemy/test_support/integration_helpers.rb +1 -0
  265. data/lib/alchemy/test_support/shared_contexts.rb +5 -4
  266. data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
  267. data/lib/alchemy/tinymce.rb +15 -13
  268. data/lib/alchemy/upgrader.rb +8 -7
  269. data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
  270. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
  271. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
  272. data/lib/alchemy/version.rb +1 -1
  273. data/lib/alchemy_cms.rb +52 -50
  274. data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
  275. data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
  276. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
  277. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
  278. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
  279. data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
  280. data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
  281. data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
  282. data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
  283. data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
  284. data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
  285. data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
  286. data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
  287. data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
  288. data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
  289. data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
  290. data/lib/generators/alchemy/install/install_generator.rb +110 -0
  291. data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
  292. data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
  293. data/lib/generators/alchemy/install/templates/menus.yml.tt +8 -0
  294. data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
  295. data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +5 -5
  296. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
  297. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
  298. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
  299. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
  300. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +2 -2
  301. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +2 -2
  302. data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
  303. data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
  304. data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
  305. data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
  306. data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
  307. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
  308. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
  309. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
  310. data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
  311. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
  312. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
  313. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
  314. data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
  315. data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
  316. data/lib/tasks/alchemy/db.rake +3 -19
  317. data/lib/tasks/alchemy/install.rake +3 -2
  318. data/lib/tasks/alchemy/tidy.rake +9 -8
  319. data/lib/tasks/alchemy/upgrade.rake +28 -105
  320. data/package.json +45 -0
  321. data/package/admin.js +14 -0
  322. data/package/src/__tests__/i18n.spec.js +70 -0
  323. data/package/src/i18n.js +48 -0
  324. data/package/src/node_tree.js +72 -0
  325. data/package/src/translations.js +32 -0
  326. data/package/src/utils/__tests__/ajax.spec.js +124 -0
  327. data/package/src/utils/__tests__/events.spec.js +38 -0
  328. data/package/src/utils/ajax.js +48 -0
  329. data/package/src/utils/events.js +16 -0
  330. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  331. data/vendor/assets/fonts/fa-regular-400.svg +798 -358
  332. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  333. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  334. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  335. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  336. data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
  337. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  338. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  339. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  340. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
  341. data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
  342. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
  343. data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
  344. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
  345. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
  346. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
  347. data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
  348. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
  349. data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
  350. data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
  351. metadata +131 -83
  352. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
  353. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
  354. data/app/helpers/alchemy/essences_helper.rb +0 -119
  355. data/app/models/concerns/alchemy/content_touching.rb +0 -23
  356. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
  357. data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
  358. data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -33
  359. data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
  360. data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
  361. data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
  362. data/app/views/alchemy/navigation/_link.html.erb +0 -19
  363. data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
  364. data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
  365. data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
  366. data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
  367. data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
  368. data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
  369. data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
  370. data/lib/alchemy/ssl_protection.rb +0 -32
  371. data/lib/alchemy/tasks/helpers.rb +0 -81
  372. data/lib/alchemy/test_support/controller_requests.rb +0 -93
  373. data/lib/alchemy/upgrader/four_point_four.rb +0 -52
  374. data/lib/alchemy/upgrader/four_point_one.rb +0 -42
  375. data/lib/alchemy/upgrader/four_point_two.rb +0 -85
  376. data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -43
  377. data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -148
  378. data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -28
  379. data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
  380. data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
  381. data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
  382. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
  383. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
  384. data/lib/tasks/alchemy/convert.rake +0 -95
  385. data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
  386. data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -3,13 +3,12 @@
3
3
  module Alchemy
4
4
  module Admin
5
5
  class ContentsController < Alchemy::Admin::BaseController
6
- helper 'alchemy/admin/essences'
6
+ helper "alchemy/admin/essences"
7
7
 
8
8
  authorize_resource class: Alchemy::Content
9
9
 
10
10
  def create
11
11
  @content = Content.create(content_params)
12
- @html_options = params[:html_options] || {}
13
12
  end
14
13
 
15
14
  private
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'net/http'
4
- require 'alchemy/version'
3
+ require "net/http"
4
+ require "alchemy/version"
5
5
 
6
6
  module Alchemy
7
7
  module Admin
@@ -28,9 +28,9 @@ module Alchemy
28
28
  def update_check
29
29
  @alchemy_version = Alchemy.version
30
30
  if @alchemy_version < latest_alchemy_version
31
- render plain: 'true'
31
+ render plain: "true"
32
32
  else
33
- render plain: 'false'
33
+ render plain: "false"
34
34
  end
35
35
  rescue UpdateServiceUnavailable => e
36
36
  render plain: e, status: 503
@@ -41,7 +41,8 @@ module Alchemy
41
41
  # Returns latest alchemy version.
42
42
  def latest_alchemy_version
43
43
  versions = get_alchemy_versions
44
- return '' if versions.blank?
44
+ return "" if versions.blank?
45
+
45
46
  # reject any non release version
46
47
  versions.reject! { |v| v =~ /[a-z]/ }
47
48
  versions.max
@@ -53,14 +54,14 @@ module Alchemy
53
54
  response = query_rubygems
54
55
  if response.code == "200"
55
56
  alchemy_versions = JSON.parse(response.body)
56
- alchemy_versions.collect { |h| h['number'] }.sort
57
+ alchemy_versions.collect { |h| h["number"] }.sort
57
58
  else
58
59
  # rubygems.org not available?
59
60
  # then we try github
60
61
  response = query_github
61
62
  if response.code == "200"
62
63
  alchemy_tags = JSON.parse(response.body)
63
- alchemy_tags.collect { |h| h['name'] }.sort
64
+ alchemy_tags.collect { |h| h["name"].tr("v", "") }.sort
64
65
  else
65
66
  # no luck at all?
66
67
  raise UpdateServiceUnavailable
@@ -70,12 +71,12 @@ module Alchemy
70
71
 
71
72
  # Query the RubyGems API for Alchemy versions.
72
73
  def query_rubygems
73
- make_api_request('https://rubygems.org/api/v1/versions/alchemy_cms.json')
74
+ make_api_request("https://rubygems.org/api/v1/versions/alchemy_cms.json")
74
75
  end
75
76
 
76
77
  # Query the GitHub API for Alchemy tags.
77
78
  def query_github
78
- make_api_request('https://api.github.com/repos/AlchemyCMS/alchemy_cms/tags')
79
+ make_api_request("https://api.github.com/repos/AlchemyCMS/alchemy_cms/tags")
79
80
  end
80
81
 
81
82
  # Make a HTTP API request for given request url.
@@ -17,7 +17,7 @@ module Alchemy
17
17
  @parent_element = Element.find_by(id: params[:parent_element_id])
18
18
  @elements = @page.available_elements_within_current_scope(@parent_element)
19
19
  @element = @page.elements.build
20
- @clipboard = get_clipboard('elements')
20
+ @clipboard = get_clipboard("elements")
21
21
  @clipboard_items = Element.all_from_clipboard_for_page(@clipboard, @page)
22
22
  end
23
23
 
@@ -30,7 +30,7 @@ module Alchemy
30
30
  else
31
31
  @element = Element.create(create_element_params)
32
32
  end
33
- if @page.definition['insert_elements_at'] == 'top'
33
+ if @page.definition["insert_elements_at"] == "top"
34
34
  @insert_at_top = true
35
35
  @element.move_to_top
36
36
  end
@@ -40,7 +40,7 @@ module Alchemy
40
40
  else
41
41
  @element.page = @page
42
42
  @elements = @page.available_element_definitions
43
- @clipboard = get_clipboard('elements')
43
+ @clipboard = get_clipboard("elements")
44
44
  @clipboard_items = Element.all_from_clipboard_for_page(@clipboard, @page)
45
45
  render :new
46
46
  end
@@ -56,7 +56,7 @@ module Alchemy
56
56
  @element_validated = @element.update(element_params)
57
57
  else
58
58
  @element_validated = false
59
- @notice = Alchemy.t('Validation failed')
59
+ @notice = Alchemy.t("Validation failed")
60
60
  @error_message = "<h2>#{@notice}</h2><p>#{Alchemy.t(:content_validations_headline)}</p>".html_safe
61
61
  end
62
62
  end
@@ -81,7 +81,7 @@ module Alchemy
81
81
  Element.where(id: element_id).update_all(
82
82
  page_id: params[:page_id],
83
83
  parent_element_id: params[:parent_element_id],
84
- position: idx + 1
84
+ position: idx + 1,
85
85
  )
86
86
  end
87
87
  @parent_element.try!(:touch)
@@ -100,20 +100,20 @@ module Alchemy
100
100
  [
101
101
  {
102
102
  contents: {
103
- essence: :ingredient_association
104
- }
103
+ essence: :ingredient_association,
104
+ },
105
105
  },
106
106
  :tags,
107
107
  {
108
108
  all_nested_elements: [
109
109
  {
110
110
  contents: {
111
- essence: :ingredient_association
112
- }
111
+ essence: :ingredient_association,
112
+ },
113
113
  },
114
- :tags
115
- ]
116
- }
114
+ :tags,
115
+ ],
116
+ },
117
117
  ]
118
118
  end
119
119
 
@@ -123,20 +123,20 @@ module Alchemy
123
123
 
124
124
  def element_from_clipboard
125
125
  @element_from_clipboard ||= begin
126
- @clipboard = get_clipboard('elements')
127
- @clipboard.detect { |item| item['id'].to_i == params[:paste_from_clipboard].to_i }
128
- end
126
+ @clipboard = get_clipboard("elements")
127
+ @clipboard.detect { |item| item["id"].to_i == params[:paste_from_clipboard].to_i }
128
+ end
129
129
  end
130
130
 
131
131
  def paste_element_from_clipboard
132
- @source_element = Element.find(element_from_clipboard['id'])
132
+ @source_element = Element.find(element_from_clipboard["id"])
133
133
  element = Element.copy(@source_element, {
134
134
  parent_element_id: create_element_params[:parent_element_id],
135
- page_id: @page.id}
136
- )
137
- if element_from_clipboard['action'] == 'cut'
135
+ page_id: @page.id,
136
+ })
137
+ if element_from_clipboard["action"] == "cut"
138
138
  @cut_element_id = @source_element.id
139
- @clipboard.delete_if { |item| item['id'] == @source_element.id.to_s }
139
+ @clipboard.delete_if { |item| item["id"] == @source_element.id.to_s }
140
140
  @source_element.destroy
141
141
  end
142
142
  element
@@ -9,9 +9,9 @@ module Alchemy
9
9
  before_action :load_essence_picture, only: [:edit, :crop, :update]
10
10
  before_action :load_content, only: [:edit, :update, :assign]
11
11
 
12
- helper 'alchemy/admin/contents'
13
- helper 'alchemy/admin/essences'
14
- helper 'alchemy/url'
12
+ helper "alchemy/admin/contents"
13
+ helper "alchemy/admin/essences"
14
+ helper "alchemy/url"
15
15
 
16
16
  def edit
17
17
  end
@@ -19,10 +19,8 @@ module Alchemy
19
19
  def crop
20
20
  if @picture = @essence_picture.picture
21
21
  @content = @essence_picture.content
22
- options_from_params[:format] ||= (configuration(:image_store_format) || 'png')
23
-
24
22
  @min_size = sizes_from_essence_or_params
25
- @ratio = ratio_from_size_or_params
23
+ @ratio = ratio_from_size_or_settings
26
24
  infer_width_or_height_from_ratio
27
25
 
28
26
  @default_box = @essence_picture.default_mask(@min_size)
@@ -70,26 +68,26 @@ module Alchemy
70
68
 
71
69
  # Gets the minimum size of the image to be rendered.
72
70
  #
73
- # The +render_size+ attribute has preference over the +size+ parameter.
71
+ # The +render_size+ attribute has preference over the contents +size+ setting.
74
72
  #
75
73
  def sizes_from_essence_or_params
76
74
  if @essence_picture.render_size?
77
75
  @essence_picture.sizes_from_string(@essence_picture.render_size)
78
- elsif options_from_params[:size]
79
- @essence_picture.sizes_from_string(options_from_params[:size])
76
+ elsif @essence_picture.content.settings[:size]
77
+ @essence_picture.sizes_from_string(@essence_picture.content.settings[:size])
80
78
  else
81
79
  { width: 0, height: 0 }
82
80
  end
83
81
  end
84
82
 
85
- # Infers the aspect ratio from size or parameters. If you don't want a fixed
83
+ # Infers the aspect ratio from size or contents settings. If you don't want a fixed
86
84
  # aspect ratio, don't specify a size or only width or height.
87
85
  #
88
- def ratio_from_size_or_params
89
- if @min_size.value?(0) && options_from_params[:fixed_ratio].to_s =~ FLOAT_REGEX
90
- options_from_params[:fixed_ratio].to_f
86
+ def ratio_from_size_or_settings
87
+ if @min_size.value?(0) && @essence_picture.content.settings[:fixed_ratio].to_s =~ FLOAT_REGEX
88
+ @essence_picture.content.settings[:fixed_ratio].to_f
91
89
  elsif !@min_size[:width].zero? && !@min_size[:height].zero?
92
- @min_size[:width].to_f / @min_size[:height].to_f
90
+ @min_size[:width].to_f / @min_size[:height]
93
91
  else
94
92
  false
95
93
  end
@@ -3,21 +3,54 @@
3
3
  module Alchemy
4
4
  module Admin
5
5
  class LanguagesController < ResourcesController
6
+ before_action :load_current_site, only: %i[index new]
7
+
6
8
  def index
7
- @query = Language.on_current_site.ransack(search_filter_params[:q])
9
+ @query = Language.on_site(@current_site).ransack(search_filter_params[:q])
10
+ @query.sorts = default_sort_order if @query.sorts.empty?
8
11
  @languages = @query.result.page(params[:page] || 1).per(items_per_page)
9
12
  end
10
13
 
11
14
  def new
12
15
  @language = Language.new(
13
- page_layout: Config.get(:default_language)['page_layout']
16
+ site: @current_site,
17
+ page_layout: Config.get(:default_language)["page_layout"],
14
18
  )
15
19
  end
16
20
 
21
+ def create
22
+ @language = Alchemy::Language.new(resource_params)
23
+ if @language.save
24
+ flash[:notice] = Alchemy.t("Language successfully created")
25
+ redirect_to alchemy.admin_pages_path(language_id: @language)
26
+ else
27
+ render :new
28
+ end
29
+ end
30
+
31
+ def destroy
32
+ if @language.destroy
33
+ flash[:notice] = Alchemy.t("Language successfully removed")
34
+ else
35
+ flash[:warning] = @language.errors.full_messages.to_sentence
36
+ end
37
+ do_redirect_to alchemy.admin_languages_path
38
+ end
39
+
17
40
  def switch
18
41
  set_alchemy_language(params[:language_id])
19
42
  do_redirect_to request.referer || alchemy.admin_dashboard_path
20
43
  end
44
+
45
+ private
46
+
47
+ def load_current_site
48
+ @current_site = Alchemy::Site.current
49
+ if @current_site.nil?
50
+ flash[:warning] = Alchemy.t("Please create a site first.")
51
+ redirect_to admin_sites_path
52
+ end
53
+ end
21
54
  end
22
55
  end
23
56
  end
@@ -4,16 +4,19 @@ module Alchemy
4
4
  module Admin
5
5
  class LayoutpagesController < Alchemy::Admin::BaseController
6
6
  authorize_resource class: :alchemy_admin_layoutpages
7
+
8
+ include Alchemy::Admin::CurrentLanguage
9
+
7
10
  helper Alchemy::Admin::PagesHelper
8
11
 
9
12
  def index
10
- @layout_root = Page.find_or_create_layout_root_for(Language.current.id)
13
+ @layout_pages = Page.layoutpages.where(language: @current_language)
11
14
  @languages = Language.on_current_site
12
15
  end
13
16
 
14
17
  def edit
15
18
  @page = Page.find(params[:id])
16
- @page_layouts = PageLayout.layouts_with_own_for_select(@page.page_layout, Language.current.id, true)
19
+ @page_layouts = PageLayout.layouts_with_own_for_select(@page.page_layout, @current_language.id, true)
17
20
  end
18
21
  end
19
22
  end
@@ -3,33 +3,24 @@
3
3
  module Alchemy
4
4
  module Admin
5
5
  class NodesController < Admin::ResourcesController
6
+ include Alchemy::Admin::CurrentLanguage
7
+
6
8
  def index
7
9
  @root_nodes = Node.language_root_nodes
8
10
  end
9
11
 
10
12
  def new
11
13
  @node = Node.new(
12
- site: Alchemy::Site.current,
13
14
  parent_id: params[:parent_id],
14
- language: Language.current
15
+ language: @current_language,
15
16
  )
16
17
  end
17
18
 
18
- def toggle
19
- node = Node.find(params[:id])
20
- node.update(folded: !node.folded)
21
- if node.folded?
22
- head :ok
23
- else
24
- render partial: 'node', collection: node.children.includes(:page, :children)
25
- end
26
- end
27
-
28
19
  private
29
20
 
30
21
  def resource_params
31
22
  params.require(:node).permit(
32
- :site_id,
23
+ :menu_type,
33
24
  :parent_id,
34
25
  :language_id,
35
26
  :page_id,
@@ -37,7 +28,7 @@ module Alchemy
37
28
  :url,
38
29
  :title,
39
30
  :nofollow,
40
- :external
31
+ :external,
41
32
  )
42
33
  end
43
34
  end
@@ -5,29 +5,31 @@ module Alchemy
5
5
  class PagesController < Alchemy::Admin::BaseController
6
6
  include OnPageLayout::CallbacksRunner
7
7
 
8
- helper 'alchemy/pages'
8
+ helper "alchemy/pages"
9
+
10
+ before_action :load_page, except: [:index, :flush, :new, :order, :create, :copy_language_tree, :link, :sort]
11
+
12
+ authorize_resource class: Alchemy::Page, except: [:index, :tree]
13
+
14
+ before_action only: [:index, :tree, :flush, :new, :order, :create, :copy_language_tree] do
15
+ authorize! :index, :alchemy_admin_pages
16
+ end
17
+
18
+ include Alchemy::Admin::CurrentLanguage
9
19
 
10
20
  before_action :set_translation,
11
21
  except: [:show]
12
22
 
13
- before_action :load_page,
14
- only: [:show, :info, :unlock, :visit, :publish, :configure, :edit, :update, :destroy, :fold,
15
- :tree]
16
-
17
23
  before_action :set_root_page,
18
24
  only: [:index, :show, :sort, :order]
19
25
 
20
- authorize_resource class: Alchemy::Page, except: [:index, :tree]
21
-
22
26
  before_action :run_on_page_layout_callbacks,
23
27
  if: :run_on_page_layout_callbacks?,
24
28
  only: [:show]
25
29
 
26
30
  def index
27
- authorize! :index, :alchemy_admin_pages
28
-
29
31
  if !@page_root
30
- @language = Language.current
32
+ @language = @current_language
31
33
  @languages_with_page_tree = Language.on_current_site.with_root_page
32
34
  @page_layouts = PageLayout.layouts_for_select(@language.id)
33
35
  end
@@ -36,8 +38,6 @@ module Alchemy
36
38
  # Returns all pages as a tree from the root given by the id parameter
37
39
  #
38
40
  def tree
39
- authorize! :tree, :alchemy_admin_pages
40
-
41
41
  render json: serialized_page_tree
42
42
  end
43
43
 
@@ -48,7 +48,7 @@ module Alchemy
48
48
  Page.current_preview = @page
49
49
  # Setting the locale to pages language, so the page content has it's correct translations.
50
50
  ::I18n.locale = @page.language.locale
51
- render(layout: Alchemy::Config.get(:admin_page_preview_layout) || 'application')
51
+ render(layout: Alchemy::Config.get(:admin_page_preview_layout) || "application")
52
52
  end
53
53
 
54
54
  def info
@@ -56,10 +56,10 @@ module Alchemy
56
56
  end
57
57
 
58
58
  def new
59
- @page = Page.new(layoutpage: params[:layoutpage] == 'true', parent_id: params[:parent_id])
60
- @page_layouts = PageLayout.layouts_for_select(Language.current.id, @page.layoutpage?)
61
- @clipboard = get_clipboard('pages')
62
- @clipboard_items = Page.all_from_clipboard_for_select(@clipboard, Language.current.id, @page.layoutpage?)
59
+ @page ||= Page.new(layoutpage: params[:layoutpage] == "true", parent_id: params[:parent_id])
60
+ @page_layouts = PageLayout.layouts_for_select(@current_language.id, @page.layoutpage?)
61
+ @clipboard = get_clipboard("pages")
62
+ @clipboard_items = Page.all_from_clipboard_for_select(@clipboard, @current_language.id, @page.layoutpage?)
63
63
  end
64
64
 
65
65
  def create
@@ -68,9 +68,7 @@ module Alchemy
68
68
  flash[:notice] = Alchemy.t("Page created", name: @page.name)
69
69
  do_redirect_to(redirect_path_after_create_page)
70
70
  else
71
- @page_layouts = PageLayout.layouts_for_select(Language.current.id, @page.layoutpage?)
72
- @clipboard = get_clipboard('pages')
73
- @clipboard_items = Page.all_from_clipboard_for_select(@clipboard, Language.current.id, @page.layoutpage?)
71
+ new
74
72
  render :new
75
73
  end
76
74
  end
@@ -82,18 +80,18 @@ module Alchemy
82
80
  def edit
83
81
  # fetching page via before filter
84
82
  if page_is_locked?
85
- flash[:warning] = Alchemy.t('This page is locked', name: @page.locker_name)
83
+ flash[:warning] = Alchemy.t("This page is locked", name: @page.locker_name)
86
84
  redirect_to admin_pages_path
87
85
  elsif page_needs_lock?
88
86
  @page.lock_to!(current_alchemy_user)
89
87
  end
88
+ @preview_url = Alchemy::Admin::PREVIEW_URL.url_for(@page)
90
89
  @layoutpage = @page.layoutpage?
91
90
  end
92
91
 
93
92
  # Set page configuration like page names, meta tags and states.
94
93
  def configure
95
- @page_layouts = PageLayout.layouts_with_own_for_select(@page.page_layout, Language.current.id, @page.layoutpage?)
96
- render @page.definition['redirects_to_external'] ? 'configure_external' : 'configure'
94
+ @page_layouts = PageLayout.layouts_with_own_for_select(@page.page_layout, @current_language.id, @page.layoutpage?)
97
95
  end
98
96
 
99
97
  # Updates page
@@ -105,7 +103,7 @@ module Alchemy
105
103
  @old_page_layout = @page.page_layout
106
104
  if @page.update(page_params)
107
105
  @notice = Alchemy.t("Page saved", name: @page.name)
108
- @while_page_edit = request.referer.include?('edit')
106
+ @while_page_edit = request.referer.include?("edit")
109
107
 
110
108
  unless @while_page_edit
111
109
  @tree = serialized_page_tree
@@ -121,17 +119,17 @@ module Alchemy
121
119
  flash[:notice] = Alchemy.t("Page deleted", name: @page.name)
122
120
 
123
121
  # Remove page from clipboard
124
- clipboard = get_clipboard('pages')
125
- clipboard.delete_if { |item| item['id'] == @page.id.to_s }
122
+ clipboard = get_clipboard("pages")
123
+ clipboard.delete_if { |item| item["id"] == @page.id.to_s }
126
124
  end
127
125
 
128
126
  respond_to do |format|
129
127
  format.js do
130
128
  @redirect_url = if @page.layoutpage?
131
- alchemy.admin_layoutpages_path
132
- else
133
- alchemy.admin_pages_path
134
- end
129
+ alchemy.admin_layoutpages_path
130
+ else
131
+ alchemy.admin_pages_path
132
+ end
135
133
 
136
134
  render :redirect
137
135
  end
@@ -142,7 +140,6 @@ module Alchemy
142
140
  @attachments = Attachment.all.collect { |f|
143
141
  [f.name, download_attachment_path(id: f.id, name: f.urlname)]
144
142
  }
145
- @url_prefix = prefix_locale? ? "#{Language.current.code}/" : ""
146
143
  end
147
144
 
148
145
  def fold
@@ -172,7 +169,7 @@ module Alchemy
172
169
  redirect_to show_page_url(
173
170
  urlname: @page.urlname,
174
171
  locale: prefix_locale? ? @page.language_code : nil,
175
- host: @page.site.host == "*" ? request.host : @page.site.host
172
+ host: @page.site.host == "*" ? request.host : @page.site.host,
176
173
  )
177
174
  end
178
175
 
@@ -213,24 +210,22 @@ module Alchemy
213
210
  end
214
211
 
215
212
  def flush
216
- Language.current.pages.flushables.update_all(published_at: Time.current)
213
+ @current_language.pages.flushables.update_all(published_at: Time.current)
217
214
  # We need to ensure, that also all layoutpages get the +published_at+ timestamp set,
218
215
  # but not set to public true, because the cache_key for an element is +published_at+
219
216
  # and we don't want the layout pages to be present in +Page.published+ scope.
220
- Language.current.pages.flushable_layoutpages.update_all(published_at: Time.current)
217
+ @current_language.pages.flushable_layoutpages.update_all(published_at: Time.current)
221
218
  respond_to { |format| format.js }
222
219
  end
223
220
 
224
221
  private
225
222
 
226
223
  def copy_of_language_root
227
- page_copy = Page.copy(
224
+ Page.copy(
228
225
  language_root_to_copy_from,
229
226
  language_id: params[:languages][:new_lang_id],
230
- language_code: Language.current.code
227
+ language_code: @current_language.code,
231
228
  )
232
- page_copy.move_to_child_of Page.root
233
- page_copy
234
229
  end
235
230
 
236
231
  def language_root_to_copy_from
@@ -260,14 +255,14 @@ module Alchemy
260
255
  def visit_nodes(nodes, my_left, parent, depth, tree, url, restricted)
261
256
  nodes.each do |item|
262
257
  my_right = my_left + 1
263
- my_restricted = item['restricted'] || restricted
258
+ my_restricted = item["restricted"] || restricted
264
259
  urls = process_url(url, item)
265
260
 
266
- if item['children']
267
- my_right, tree = visit_nodes(item['children'], my_left + 1, item['id'], depth + 1, tree, urls[:children_path], my_restricted)
261
+ if item["children"]
262
+ my_right, tree = visit_nodes(item["children"], my_left + 1, item["id"], depth + 1, tree, urls[:children_path], my_restricted)
268
263
  end
269
264
 
270
- tree[item['id']] = TreeNode.new(my_left, my_right, parent, depth, urls[:my_urlname], my_restricted)
265
+ tree[item["id"]] = TreeNode.new(my_left, my_right, parent, depth, urls[:my_urlname], my_restricted)
271
266
  my_left = my_right + 1
272
267
  end
273
268
 
@@ -296,24 +291,14 @@ module Alchemy
296
291
  # This function will add a node's own slug into their ancestor's path
297
292
  # in order to create the full URL of a node
298
293
  #
299
- # NOTE: external and invisible pages are not part of the full path of their children
300
- #
301
294
  # @param [String]
302
295
  # The node's ancestors path
303
296
  # @param [Hash]
304
297
  # A children node
305
298
  #
306
299
  def process_url(ancestors_path, item)
307
- default_urlname = (ancestors_path.blank? ? "" : "#{ancestors_path}/") + item['slug'].to_s
308
-
309
- pair = {my_urlname: default_urlname, children_path: default_urlname}
310
-
311
- if item['external'] == true || item['visible'] == false
312
- # children ignore an ancestor in their path if external or invisible
313
- pair[:children_path] = ancestors_path
314
- end
315
-
316
- pair
300
+ default_urlname = (ancestors_path.blank? ? "" : "#{ancestors_path}/") + item["slug"].to_s
301
+ { my_urlname: default_urlname, children_path: default_urlname }
317
302
  end
318
303
 
319
304
  def load_page
@@ -321,19 +306,19 @@ module Alchemy
321
306
  end
322
307
 
323
308
  def pages_from_raw_request
324
- request.raw_post.split('&').map do |i|
325
- parts = i.split('=')
309
+ request.raw_post.split("&").map do |i|
310
+ parts = i.split("=")
326
311
  {
327
- parts[0].gsub(/[^0-9]/, '') => parts[1]
312
+ parts[0].gsub(/[^0-9]/, "") => parts[1],
328
313
  }
329
314
  end
330
315
  end
331
316
 
332
317
  def redirect_path_after_create_page
333
- if @page.definition['redirects_to_external'] || !@page.editable_by?(current_alchemy_user)
334
- admin_pages_path
335
- else
318
+ if @page.editable_by?(current_alchemy_user)
336
319
  params[:redirect_to] || edit_admin_page_path(@page)
320
+ else
321
+ admin_pages_path
337
322
  end
338
323
  end
339
324
 
@@ -352,30 +337,32 @@ module Alchemy
352
337
  def page_is_locked?
353
338
  return false if !@page.locker.try(:logged_in?)
354
339
  return false if !current_alchemy_user.respond_to?(:id)
340
+
355
341
  @page.locked? && @page.locker.id != current_alchemy_user.id
356
342
  end
357
343
 
358
344
  def page_needs_lock?
359
345
  return true unless @page.locker
346
+
360
347
  @page.locker.try!(:id) != current_alchemy_user.try!(:id)
361
348
  end
362
349
 
363
350
  def paste_from_clipboard
364
351
  if params[:paste_from_clipboard]
365
352
  source = Page.find(params[:paste_from_clipboard])
366
- parent = Page.find_by(id: params[:page][:parent_id]) || Page.root
353
+ parent = Page.find_by(id: params[:page][:parent_id])
367
354
  Page.copy_and_paste(source, parent, params[:page][:name])
368
355
  end
369
356
  end
370
357
 
371
358
  def set_root_page
372
- @page_root = Language.current_root_page
359
+ @page_root = @current_language.root_page
373
360
  end
374
361
 
375
362
  def serialized_page_tree
376
363
  PageTreeSerializer.new(@page, ability: current_ability,
377
364
  user: current_alchemy_user,
378
- full: params[:full] == 'true')
365
+ full: params[:full] == "true")
379
366
  end
380
367
  end
381
368
  end