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
@@ -4,7 +4,7 @@ module Alchemy::Language::Code
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  def code
7
- [language_code, country_code].select(&:present?).join('-')
7
+ [language_code, country_code].select(&:present?).join("-")
8
8
  end
9
9
 
10
10
  def code=(code)
@@ -13,11 +13,11 @@ module Alchemy::Language::Code
13
13
 
14
14
  module ClassMethods
15
15
  def find_by_code(code)
16
- codes = code.split('-')
17
- codes << '' if codes.length == 1
16
+ codes = code.split("-")
17
+ codes << "" if codes.length == 1
18
18
  on_current_site.find_by(
19
19
  language_code: codes[0],
20
- country_code: codes[1]
20
+ country_code: codes[1],
21
21
  )
22
22
  end
23
23
  end
@@ -13,7 +13,7 @@
13
13
 
14
14
  class Alchemy::LegacyPageUrl < ActiveRecord::Base
15
15
  belongs_to :page,
16
- class_name: 'Alchemy::Page',
16
+ class_name: "Alchemy::Page",
17
17
  required: true
18
18
 
19
19
  validates :urlname,
@@ -22,17 +22,17 @@ module Alchemy
22
22
 
23
23
  attr_accessor :contact_form_id, :ip
24
24
 
25
- config['fields'].each do |field|
25
+ config["fields"].each do |field|
26
26
  attr_accessor field.to_sym
27
27
  end
28
28
 
29
- config['validate_fields'].each do |field|
29
+ config["validate_fields"].each do |field|
30
30
  validates_presence_of field
31
31
 
32
32
  case field.to_sym
33
33
  when /email/
34
34
  validates_format_of field,
35
- with: Alchemy::Config.get('format_matchers')['email'],
35
+ with: Alchemy::Config.get("format_matchers")["email"],
36
36
  if: -> { send(field).present? }
37
37
  when :email_confirmation
38
38
  validates_confirmation_of :email
@@ -4,13 +4,22 @@ module Alchemy
4
4
  class Node < BaseRecord
5
5
  VALID_URL_REGEX = /\A(\/|\D[a-z\+\d\.\-]+:)/
6
6
 
7
- acts_as_nested_set scope: 'language_id', touch: true
7
+ before_destroy :check_if_related_essence_nodes_present
8
+
9
+ acts_as_nested_set scope: "language_id", touch: true
8
10
  stampable stamper_class_name: Alchemy.user_class_name
9
11
 
10
- belongs_to :site, class_name: 'Alchemy::Site'
11
- belongs_to :language, class_name: 'Alchemy::Language'
12
- belongs_to :page, class_name: 'Alchemy::Page', optional: true, inverse_of: :nodes
12
+ belongs_to :language, class_name: "Alchemy::Language"
13
+ belongs_to :page, class_name: "Alchemy::Page", optional: true, inverse_of: :nodes
14
+
15
+ has_one :site, through: :language
16
+
17
+ has_many :essence_nodes, class_name: "Alchemy::EssenceNode", foreign_key: :node_id, inverse_of: :ingredient_association
13
18
 
19
+ before_validation :translate_root_menu_name, if: -> { root? }
20
+ before_validation :set_menu_type_from_root, unless: -> { root? }
21
+
22
+ validates :menu_type, presence: true
14
23
  validates :name, presence: true, if: -> { page.nil? }
15
24
  validates :url, format: { with: VALID_URL_REGEX }, unless: -> { url.nil? }
16
25
 
@@ -25,9 +34,32 @@ module Alchemy
25
34
  class << self
26
35
  # Returns all root nodes for current language
27
36
  def language_root_nodes
28
- raise 'No language found' if Language.current.nil?
37
+ raise "No language found" if Language.current.nil?
38
+
29
39
  roots.where(language_id: Language.current.id)
30
40
  end
41
+
42
+ def available_menu_names
43
+ read_definitions_file
44
+ end
45
+
46
+ private
47
+
48
+ # Reads the element definitions file named +menus.yml+ from +config/alchemy/+ folder.
49
+ #
50
+ def read_definitions_file
51
+ if ::File.exist?(definitions_file_path)
52
+ ::YAML.safe_load(File.read(definitions_file_path)) || []
53
+ else
54
+ raise LoadError, "Could not find menus.yml file! Please run `rails generate alchemy:install`"
55
+ end
56
+ end
57
+
58
+ # Returns the +menus.yml+ file path
59
+ #
60
+ def definitions_file_path
61
+ Rails.root.join "config/alchemy/menus.yml"
62
+ end
31
63
  end
32
64
 
33
65
  # Returns the url
@@ -35,15 +67,29 @@ module Alchemy
35
67
  # Either the value is stored in the database, aka. an external url.
36
68
  # Or, if attached, the values comes from a page.
37
69
  def url
38
- page && "/#{page.urlname}" || read_attribute(:url).presence
70
+ page&.url_path || read_attribute(:url).presence
39
71
  end
40
72
 
41
73
  def to_partial_path
42
- "#{view_folder_name}/wrapper"
74
+ "alchemy/menus/#{menu_type}/node"
75
+ end
76
+
77
+ private
78
+
79
+ def check_if_related_essence_nodes_present
80
+ dependent_essence_nodes = self_and_descendants.flat_map(&:essence_nodes)
81
+ if dependent_essence_nodes.any?
82
+ errors.add(:base, :essence_nodes_present, page_names: dependent_essence_nodes.map(&:page).map(&:name).to_sentence)
83
+ throw(:abort)
84
+ end
85
+ end
86
+
87
+ def translate_root_menu_name
88
+ self.name ||= Alchemy.t(menu_type, scope: :menu_names)
43
89
  end
44
90
 
45
- def view_folder_name
46
- "alchemy/menus/#{name.parameterize.underscore}"
91
+ def set_menu_type_from_root
92
+ self.menu_type = root.menu_type
47
93
  end
48
94
  end
49
95
  end
@@ -17,7 +17,6 @@
17
17
  # rgt :integer
18
18
  # parent_id :integer
19
19
  # depth :integer
20
- # visible :boolean default(FALSE)
21
20
  # locked_by :integer
22
21
  # restricted :boolean default(FALSE)
23
22
  # robot_index :boolean default(TRUE)
@@ -44,11 +43,10 @@ module Alchemy
44
43
 
45
44
  DEFAULT_ATTRIBUTES_FOR_COPY = {
46
45
  autogenerate_elements: false,
47
- visible: false,
48
46
  public_on: nil,
49
47
  public_until: nil,
50
48
  locked_at: nil,
51
- locked_by: nil
49
+ locked_by: nil,
52
50
  }
53
51
 
54
52
  SKIPPED_ATTRIBUTES_ON_COPY = %w(
@@ -78,16 +76,15 @@ module Alchemy
78
76
  :tag_list,
79
77
  :title,
80
78
  :urlname,
81
- :visible,
82
79
  :layoutpage,
83
- :menu_id
80
+ :menu_id,
84
81
  ]
85
82
 
86
- acts_as_nested_set(dependent: :destroy)
83
+ acts_as_nested_set(dependent: :destroy, scope: [:layoutpage, :language_id])
87
84
 
88
85
  stampable stamper_class_name: Alchemy.user_class_name
89
86
 
90
- belongs_to :language, optional: true
87
+ belongs_to :language
91
88
 
92
89
  belongs_to :creator,
93
90
  primary_key: Alchemy.user_class_primary_key,
@@ -110,43 +107,33 @@ module Alchemy
110
107
  has_one :site, through: :language
111
108
  has_many :site_languages, through: :site, source: :languages
112
109
  has_many :folded_pages
113
- has_many :legacy_urls, class_name: 'Alchemy::LegacyPageUrl'
114
- has_many :nodes, class_name: 'Alchemy::Node', inverse_of: :page
110
+ has_many :legacy_urls, class_name: "Alchemy::LegacyPageUrl"
111
+ has_many :nodes, class_name: "Alchemy::Node", inverse_of: :page
115
112
 
116
- validates_presence_of :language, on: :create, unless: :root
117
- validates_presence_of :page_layout, unless: :systempage?
118
- validates_format_of :page_layout, with: /\A[a-z0-9_-]+\z/, unless: -> { systempage? || page_layout.blank? }
119
- validates_presence_of :parent_id, if: proc { Page.count > 1 }
113
+ before_validation :set_language,
114
+ if: -> { language.nil? }
115
+
116
+ validates_presence_of :page_layout
117
+ validates_format_of :page_layout, with: /\A[a-z0-9_-]+\z/, unless: -> { page_layout.blank? }
118
+ validates_presence_of :parent, unless: -> { layoutpage? || language_root? }
120
119
 
121
120
  before_save :set_language_code,
122
- if: -> { language.present? },
123
- unless: :systempage?
121
+ if: -> { language.present? }
124
122
 
125
123
  before_save :set_restrictions_to_child_pages,
126
- if: :restricted_changed?,
127
- unless: :systempage?
124
+ if: :restricted_changed?
128
125
 
129
126
  before_save :inherit_restricted_status,
130
- if: -> { parent && parent.restricted? },
131
- unless: :systempage?
127
+ if: -> { parent && parent.restricted? }
132
128
 
133
129
  before_save :set_published_at,
134
- if: -> { public_on.present? && published_at.nil? },
135
- unless: :systempage?
130
+ if: -> { public_on.present? && published_at.nil? }
136
131
 
137
132
  before_save :set_fixed_attributes,
138
133
  if: -> { fixed_attributes.any? }
139
134
 
140
- before_create :set_language_from_parent_or_default,
141
- if: -> { language_id.blank? },
142
- unless: :systempage?
143
-
144
135
  after_update :create_legacy_url,
145
- if: :should_create_legacy_url?,
146
- unless: -> { definition['redirects_to_external'] }
147
-
148
- after_update :attach_to_menu!,
149
- if: :should_attach_to_menu?
136
+ if: :saved_change_to_urlname?
150
137
 
151
138
  after_update -> { nodes.update_all(updated_at: Time.current) }
152
139
 
@@ -159,22 +146,9 @@ module Alchemy
159
146
  # site_name accessor
160
147
  delegate :name, to: :site, prefix: true, allow_nil: true
161
148
 
162
- attr_accessor :menu_id
163
-
164
149
  # Class methods
165
150
  #
166
151
  class << self
167
- # The root page of the page tree
168
- #
169
- # Internal use only. You wouldn't use this page ever.
170
- #
171
- # Automatically created when accessed the first time.
172
- #
173
- def root
174
- super || create!(name: 'Root')
175
- end
176
- alias_method :rootpage, :root
177
-
178
152
  # Used to store the current page previewed in the edit page template.
179
153
  #
180
154
  def current_preview=(page)
@@ -218,29 +192,12 @@ module Alchemy
218
192
  end
219
193
  end
220
194
 
221
- def layout_root_for(language_id)
222
- where({parent_id: Page.root.id, layoutpage: true, language_id: language_id}).limit(1).first
223
- end
224
-
225
- def find_or_create_layout_root_for(language_id)
226
- layoutroot = layout_root_for(language_id)
227
- return layoutroot if layoutroot
228
- language = Language.find(language_id)
229
- Page.create!(
230
- name: "Layoutroot for #{language.name}",
231
- layoutpage: true,
232
- language: language,
233
- autogenerate_elements: false,
234
- parent_id: Page.root.id
235
- )
236
- end
237
-
238
195
  def copy_and_paste(source, new_parent, new_name)
239
196
  page = copy(source, {
240
197
  parent_id: new_parent.id,
241
198
  language: new_parent.language,
242
199
  name: new_name,
243
- title: new_name
200
+ title: new_name,
244
201
  })
245
202
  if source.children.any?
246
203
  source.copy_children_to(page)
@@ -250,34 +207,29 @@ module Alchemy
250
207
 
251
208
  def all_from_clipboard(clipboard)
252
209
  return [] if clipboard.blank?
253
- where(id: clipboard.collect { |p| p['id'] })
210
+
211
+ where(id: clipboard.collect { |p| p["id"] })
254
212
  end
255
213
 
256
214
  def all_from_clipboard_for_select(clipboard, language_id, layoutpage = false)
257
215
  return [] if clipboard.blank?
216
+
258
217
  clipboard_pages = all_from_clipboard(clipboard)
259
218
  allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage)
260
- allowed_page_layout_names = allowed_page_layouts.collect { |p| p['name'] }
219
+ allowed_page_layout_names = allowed_page_layouts.collect { |p| p["name"] }
261
220
  clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) }
262
221
  end
263
222
 
264
223
  def link_target_options
265
- options = [[Alchemy.t(:default, scope: 'link_target_options'), '']]
224
+ options = [[Alchemy.t(:default, scope: "link_target_options"), ""]]
266
225
  link_target_options = Config.get(:link_target_options)
267
226
  link_target_options.each do |option|
268
- options << [Alchemy.t(option, scope: 'link_target_options',
269
- default: option.to_s.humanize), option]
227
+ options << [Alchemy.t(option, scope: "link_target_options",
228
+ default: option.to_s.humanize), option]
270
229
  end
271
230
  options
272
231
  end
273
232
 
274
- # Returns an array of all pages in the same branch from current.
275
- # I.e. used to find the active page in navigation.
276
- def ancestors_for(current)
277
- return [] if current.nil?
278
- current.self_and_ancestors.contentpages
279
- end
280
-
281
233
  private
282
234
 
283
235
  # Aggregates the attributes from given source for copy of page.
@@ -292,7 +244,7 @@ module Alchemy
292
244
  differences.stringify_keys!
293
245
  attributes = source.attributes.merge(differences)
294
246
  attributes.merge!(DEFAULT_ATTRIBUTES_FOR_COPY)
295
- attributes['name'] = new_name_for_copy(differences['name'], source.name)
247
+ attributes["name"] = new_name_for_copy(differences["name"], source.name)
296
248
  attributes.except(*SKIPPED_ATTRIBUTES_ON_COPY)
297
249
  end
298
250
 
@@ -308,7 +260,8 @@ module Alchemy
308
260
  #
309
261
  def new_name_for_copy(custom_name, source_name)
310
262
  return custom_name if custom_name.present?
311
- "#{source_name} (#{Alchemy.t('Copy')})"
263
+
264
+ "#{source_name} (#{Alchemy.t("Copy")})"
312
265
  end
313
266
  end
314
267
 
@@ -336,17 +289,18 @@ module Alchemy
336
289
  # Use this for your custom element loading logic.
337
290
  #
338
291
  # @return [ActiveRecord::Relation]
339
- def find_elements(options = {}, show_non_public = false)
340
- if show_non_public
341
- Alchemy::Deprecation.warn "Passing true as second argument to page#find_elements to include" \
342
- " invisible elements has been removed. Please implement your own ElementsFinder" \
343
- " and pass it with options[:finder]."
344
- end
345
-
292
+ def find_elements(options = {})
346
293
  finder = options[:finder] || Alchemy::ElementsFinder.new(options)
347
294
  finder.elements(page: self)
348
295
  end
349
296
 
297
+ # = The url_path for this page
298
+ #
299
+ # @see Alchemy::Page::UrlPath#call
300
+ def url_path
301
+ Alchemy::Page::UrlPath.new(self).call
302
+ end
303
+
350
304
  # The page's view partial is dependent from its page layout
351
305
  #
352
306
  # == Define page layouts
@@ -373,9 +327,10 @@ module Alchemy
373
327
  # only public pages (true), skip public pages (false)
374
328
  #
375
329
  def previous(options = {})
376
- pages = self_and_siblings.where('lft < ?', lft)
330
+ pages = self_and_siblings.where("lft < ?", lft)
377
331
  select_page(pages, options.merge(order: :desc))
378
332
  end
333
+
379
334
  alias_method :previous_page, :previous
380
335
 
381
336
  # Returns the next page on the same level or nil.
@@ -386,9 +341,10 @@ module Alchemy
386
341
  # only public pages (true), skip public pages (false)
387
342
  #
388
343
  def next(options = {})
389
- pages = self_and_siblings.where('lft > ?', lft)
344
+ pages = self_and_siblings.where("lft > ?", lft)
390
345
  select_page(pages, options.merge(order: :asc))
391
346
  end
347
+
392
348
  alias_method :next_page, :next
393
349
 
394
350
  # Locks the page to given user
@@ -434,9 +390,10 @@ module Alchemy
434
390
  def copy_children_to(new_parent)
435
391
  children.each do |child|
436
392
  next if child == new_parent
393
+
437
394
  new_child = Page.copy(child, {
438
395
  language_id: new_parent.language_id,
439
- language_code: new_parent.language_code
396
+ language_code: new_parent.language_code,
440
397
  })
441
398
  new_child.move_to_child_of(new_parent)
442
399
  child.copy_children_to(new_child) unless child.children.blank?
@@ -455,22 +412,22 @@ module Alchemy
455
412
  update_columns(
456
413
  published_at: current_time,
457
414
  public_on: already_public_for?(current_time) ? public_on : current_time,
458
- public_until: still_public_for?(current_time) ? public_until : nil
415
+ public_until: still_public_for?(current_time) ? public_until : nil,
459
416
  )
460
417
  end
461
418
 
462
419
  # Updates an Alchemy::Page based on a new ordering to be applied to it
463
420
  #
464
421
  # Note: Page's urls should not be updated (and a legacy URL created) if nesting is OFF
465
- # or if a page is external or if the URL is the same
422
+ # or if the URL is the same
466
423
  #
467
424
  # @param [TreeNode]
468
425
  # A tree node with new lft, rgt, depth, url, parent_id and restricted indexes to be updated
469
426
  #
470
427
  def update_node!(node)
471
- hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
428
+ hash = { lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted }
472
429
 
473
- if Config.get(:url_nesting) && !definition['redirects_to_external'] && urlname != node.url
430
+ if urlname != node.url
474
431
  LegacyPageUrl.create(page_id: id, urlname: urlname)
475
432
  hash[:urlname] = node.url
476
433
  end
@@ -495,6 +452,7 @@ module Alchemy
495
452
  #
496
453
  def editable_by?(user)
497
454
  return true unless has_limited_editors?
455
+
498
456
  (editor_roles & user.alchemy_roles).any?
499
457
  end
500
458
 
@@ -520,7 +478,7 @@ module Alchemy
520
478
  # does not respond to +#name+ it returns +'unknown'+
521
479
  #
522
480
  def creator_name
523
- creator.try(:name) || Alchemy.t('unknown')
481
+ creator.try(:name) || Alchemy.t("unknown")
524
482
  end
525
483
 
526
484
  # Returns the name of the last updater of this page.
@@ -529,7 +487,7 @@ module Alchemy
529
487
  # does not respond to +#name+ it returns +'unknown'+
530
488
  #
531
489
  def updater_name
532
- updater.try(:name) || Alchemy.t('unknown')
490
+ updater.try(:name) || Alchemy.t("unknown")
533
491
  end
534
492
 
535
493
  # Returns the name of the user currently editing this page.
@@ -538,7 +496,7 @@ module Alchemy
538
496
  # does not respond to +#name+ it returns +'unknown'+
539
497
  #
540
498
  def locker_name
541
- locker.try(:name) || Alchemy.t('unknown')
499
+ locker.try(:name) || Alchemy.t("unknown")
542
500
  end
543
501
 
544
502
  # Menus (aka. root nodes) this page is attached to
@@ -562,8 +520,8 @@ module Alchemy
562
520
  .limit(1).first
563
521
  end
564
522
 
565
- def set_language_from_parent_or_default
566
- self.language = parent.language || Language.default
523
+ def set_language
524
+ self.language = parent&.language || Language.current
567
525
  set_language_code
568
526
  end
569
527
 
@@ -571,41 +529,13 @@ module Alchemy
571
529
  self.language_code = language.code
572
530
  end
573
531
 
574
- def should_create_legacy_url?
575
- if active_record_5_1?
576
- saved_change_to_urlname?
577
- else
578
- urlname_changed?
579
- end
580
- end
581
-
582
532
  # Stores the old urlname in a LegacyPageUrl
583
533
  def create_legacy_url
584
- if active_record_5_1?
585
- former_urlname = urlname_before_last_save
586
- else
587
- former_urlname = urlname_was
588
- end
589
- legacy_urls.find_or_create_by(urlname: former_urlname)
534
+ legacy_urls.find_or_create_by(urlname: urlname_before_last_save)
590
535
  end
591
536
 
592
537
  def set_published_at
593
538
  self.published_at = Time.current
594
539
  end
595
-
596
- def attach_to_menu!
597
- current_site_id = Alchemy::Site.current.id
598
- node = Alchemy::Node.find_by!(id: menu_id, site_id: current_site_id)
599
- node.children.create!(
600
- site_id: current_site_id,
601
- language_id: language_id,
602
- page_id: id,
603
- name: name
604
- )
605
- end
606
-
607
- def should_attach_to_menu?
608
- menu_id.present? && nodes.none?
609
- end
610
540
  end
611
541
  end