alchemy_cms 4.6.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +33 -1
  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 +30 -9
  8. data/CHANGELOG.md +102 -1
  9. data/Gemfile +24 -22
  10. data/README.md +32 -20
  11. data/Rakefile +11 -8
  12. data/alchemy_cms.gemspec +6 -5
  13. data/app/assets/javascripts/alchemy/admin.js +1 -5
  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.page_sorter.js +17 -17
  17. data/app/assets/javascripts/alchemy/node_select.js +39 -0
  18. data/app/assets/javascripts/alchemy/templates/index.js +1 -0
  19. data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
  20. data/app/assets/stylesheets/alchemy/admin.scss +3 -2
  21. data/app/assets/stylesheets/alchemy/base.scss +0 -1
  22. data/app/assets/stylesheets/alchemy/elements.scss +1 -1
  23. data/app/assets/stylesheets/alchemy/forms.scss +5 -0
  24. data/app/assets/stylesheets/alchemy/navigation.scss +1 -0
  25. data/app/assets/stylesheets/alchemy/node-select.scss +43 -0
  26. data/app/assets/stylesheets/alchemy/nodes.scss +1 -1
  27. data/app/assets/stylesheets/alchemy/sitemap.scss +5 -1
  28. data/app/assets/stylesheets/alchemy/tables.scss +1 -24
  29. data/app/assets/stylesheets/alchemy/tags.scss +2 -2
  30. data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
  31. data/app/controllers/alchemy/admin/base_controller.rb +13 -33
  32. data/app/controllers/alchemy/admin/clipboard_controller.rb +5 -4
  33. data/app/controllers/alchemy/admin/contents_controller.rb +1 -2
  34. data/app/controllers/alchemy/admin/dashboard_controller.rb +10 -9
  35. data/app/controllers/alchemy/admin/elements_controller.rb +20 -20
  36. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +12 -14
  37. data/app/controllers/alchemy/admin/languages_controller.rb +35 -2
  38. data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -2
  39. data/app/controllers/alchemy/admin/nodes_controller.rb +5 -4
  40. data/app/controllers/alchemy/admin/pages_controller.rb +51 -63
  41. data/app/controllers/alchemy/admin/pictures_controller.rb +16 -16
  42. data/app/controllers/alchemy/admin/resources_controller.rb +21 -13
  43. data/app/controllers/alchemy/admin/sites_controller.rb +18 -0
  44. data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
  45. data/app/controllers/alchemy/admin/tags_controller.rb +5 -3
  46. data/app/controllers/alchemy/admin/trash_controller.rb +6 -6
  47. data/app/controllers/alchemy/api/base_controller.rb +2 -2
  48. data/app/controllers/alchemy/api/contents_controller.rb +4 -4
  49. data/app/controllers/alchemy/api/elements_controller.rb +8 -8
  50. data/app/controllers/alchemy/api/nodes_controller.rb +37 -1
  51. data/app/controllers/alchemy/api/pages_controller.rb +14 -23
  52. data/app/controllers/alchemy/attachments_controller.rb +5 -5
  53. data/app/controllers/alchemy/base_controller.rb +10 -9
  54. data/app/controllers/alchemy/messages_controller.rb +16 -23
  55. data/app/controllers/alchemy/pages_controller.rb +13 -11
  56. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +3 -2
  57. data/app/controllers/concerns/alchemy/admin/current_language.rb +23 -0
  58. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -5
  59. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +4 -4
  60. data/app/controllers/concerns/alchemy/page_redirects.rb +2 -9
  61. data/app/controllers/concerns/alchemy/site_redirects.rb +2 -2
  62. data/app/decorators/alchemy/element_editor.rb +39 -0
  63. data/app/helpers/alchemy/admin/attachments_helper.rb +6 -6
  64. data/app/helpers/alchemy/admin/base_helper.rb +38 -35
  65. data/app/helpers/alchemy/admin/contents_helper.rb +3 -3
  66. data/app/helpers/alchemy/admin/elements_helper.rb +3 -88
  67. data/app/helpers/alchemy/admin/essences_helper.rb +8 -117
  68. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  69. data/app/helpers/alchemy/admin/navigation_helper.rb +24 -23
  70. data/app/helpers/alchemy/admin/pages_helper.rb +4 -4
  71. data/app/helpers/alchemy/admin/pictures_helper.rb +4 -6
  72. data/app/helpers/alchemy/admin/tags_helper.rb +8 -7
  73. data/app/helpers/alchemy/base_helper.rb +13 -8
  74. data/app/helpers/alchemy/elements_block_helper.rb +2 -31
  75. data/app/helpers/alchemy/elements_helper.rb +12 -58
  76. data/app/helpers/alchemy/pages_helper.rb +24 -174
  77. data/app/helpers/alchemy/url_helper.rb +4 -3
  78. data/app/mailers/alchemy/base_mailer.rb +1 -1
  79. data/app/mailers/alchemy/messages_mailer.rb +1 -1
  80. data/app/models/alchemy/attachment.rb +24 -19
  81. data/app/models/alchemy/base_record.rb +2 -5
  82. data/app/models/alchemy/content.rb +33 -38
  83. data/app/models/alchemy/content/factory.rb +24 -31
  84. data/app/models/alchemy/element.rb +45 -53
  85. data/app/models/alchemy/element/definitions.rb +4 -4
  86. data/app/models/alchemy/element/element_contents.rb +9 -6
  87. data/app/models/alchemy/element/element_essences.rb +4 -3
  88. data/app/models/alchemy/element/presenters.rb +3 -2
  89. data/app/models/alchemy/element_to_page.rb +1 -1
  90. data/app/models/alchemy/essence_boolean.rb +1 -3
  91. data/app/models/alchemy/essence_date.rb +2 -3
  92. data/app/models/alchemy/essence_file.rb +5 -5
  93. data/app/models/alchemy/essence_html.rb +1 -3
  94. data/app/models/alchemy/essence_link.rb +1 -3
  95. data/app/models/alchemy/essence_node.rb +18 -0
  96. data/app/models/alchemy/essence_page.rb +3 -16
  97. data/app/models/alchemy/essence_picture.rb +18 -17
  98. data/app/models/alchemy/essence_picture_view.rb +7 -6
  99. data/app/models/alchemy/essence_richtext.rb +1 -3
  100. data/app/models/alchemy/essence_select.rb +1 -3
  101. data/app/models/alchemy/essence_text.rb +0 -2
  102. data/app/models/alchemy/folded_page.rb +1 -0
  103. data/app/models/alchemy/language.rb +21 -35
  104. data/app/models/alchemy/language/code.rb +4 -4
  105. data/app/models/alchemy/legacy_page_url.rb +1 -1
  106. data/app/models/alchemy/message.rb +3 -3
  107. data/app/models/alchemy/node.rb +27 -4
  108. data/app/models/alchemy/page.rb +46 -127
  109. data/app/models/alchemy/page/fixed_attributes.rb +3 -2
  110. data/app/models/alchemy/page/page_elements.rb +35 -44
  111. data/app/models/alchemy/page/page_naming.rb +20 -70
  112. data/app/models/alchemy/page/page_natures.rb +7 -34
  113. data/app/models/alchemy/page/page_scopes.rb +23 -29
  114. data/app/models/alchemy/page/url_path.rb +0 -2
  115. data/app/models/alchemy/picture.rb +40 -30
  116. data/app/models/alchemy/picture/preprocessor.rb +26 -0
  117. data/app/models/alchemy/picture/transformations.rb +9 -7
  118. data/app/models/alchemy/picture/url.rb +9 -7
  119. data/app/models/alchemy/site.rb +6 -36
  120. data/app/models/alchemy/site/layout.rb +2 -2
  121. data/app/models/concerns/alchemy/touch_elements.rb +24 -0
  122. data/app/serializers/alchemy/content_serializer.rb +0 -3
  123. data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
  124. data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
  125. data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
  126. data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
  127. data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
  128. data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
  129. data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
  130. data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
  131. data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
  132. data/app/serializers/alchemy/node_serializer.rb +2 -0
  133. data/app/serializers/alchemy/page_tree_serializer.rb +9 -13
  134. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
  135. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
  136. data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
  137. data/app/views/alchemy/admin/contents/create.js.erb +1 -3
  138. data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
  139. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  140. data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
  141. data/app/views/alchemy/admin/elements/index.html.erb +3 -3
  142. data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
  143. data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
  144. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
  145. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
  146. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
  147. data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
  148. data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
  149. data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
  150. data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
  151. data/app/views/alchemy/admin/languages/index.html.erb +23 -4
  152. data/app/views/alchemy/admin/languages/new.html.erb +1 -0
  153. data/app/views/alchemy/admin/layoutpages/index.html.erb +3 -3
  154. data/app/views/alchemy/admin/nodes/_form.html.erb +18 -15
  155. data/app/views/alchemy/admin/nodes/_node.html.erb +1 -5
  156. data/app/views/alchemy/admin/nodes/index.html.erb +3 -4
  157. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
  158. data/app/views/alchemy/admin/pages/_form.html.erb +0 -1
  159. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
  160. data/app/views/alchemy/admin/pages/_page.html.erb +11 -19
  161. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
  162. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  163. data/app/views/alchemy/admin/pages/info.html.erb +0 -9
  164. data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
  165. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
  166. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
  167. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  168. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
  169. data/app/views/alchemy/admin/pictures/index.html.erb +18 -3
  170. data/app/views/alchemy/admin/pictures/show.html.erb +1 -1
  171. data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
  172. data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
  173. data/app/views/alchemy/admin/resources/index.html.erb +21 -22
  174. data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
  175. data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
  176. data/app/views/alchemy/admin/sites/index.html.erb +21 -9
  177. data/app/views/alchemy/admin/sites/new.html.erb +1 -0
  178. data/app/views/alchemy/admin/tags/index.html.erb +2 -2
  179. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
  180. data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
  181. data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
  182. data/app/views/alchemy/essences/_essence_file_view.html.erb +1 -1
  183. data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
  184. data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
  185. data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
  186. data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
  187. data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
  188. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
  189. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
  190. data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
  191. data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
  192. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
  193. data/app/views/alchemy/pages/show.rss.builder +3 -2
  194. data/app/views/layouts/alchemy/admin.html.erb +1 -0
  195. data/babel.config.js +12 -0
  196. data/bin/rails +5 -4
  197. data/config/alchemy/config.yml +23 -16
  198. data/config/brakeman.ignore +1 -1
  199. data/config/initializers/assets.rb +2 -1
  200. data/config/initializers/dragonfly.rb +2 -1
  201. data/config/initializers/mime_types.rb +1 -0
  202. data/config/initializers/mini_profiler.rb +3 -2
  203. data/config/initializers/simple_form.rb +6 -6
  204. data/config/locales/alchemy.en.yml +23 -8
  205. data/config/routes.rb +25 -24
  206. data/config/spring.rb +3 -2
  207. data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
  208. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
  209. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
  210. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
  211. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
  212. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
  213. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
  214. data/lib/alchemy/admin/locale.rb +3 -1
  215. data/lib/alchemy/admin/preview_url.rb +85 -0
  216. data/lib/alchemy/auth_accessors.rb +8 -7
  217. data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
  218. data/lib/alchemy/config.rb +3 -5
  219. data/lib/alchemy/configuration_methods.rb +3 -1
  220. data/lib/alchemy/controller_actions.rb +6 -5
  221. data/lib/alchemy/deprecation.rb +2 -1
  222. data/lib/alchemy/elements_finder.rb +5 -5
  223. data/lib/alchemy/engine.rb +23 -8
  224. data/lib/alchemy/errors.rb +0 -7
  225. data/lib/alchemy/essence.rb +17 -16
  226. data/lib/alchemy/filetypes.rb +5 -5
  227. data/lib/alchemy/forms/builder.rb +4 -4
  228. data/lib/alchemy/hints.rb +1 -1
  229. data/lib/alchemy/i18n.rb +2 -1
  230. data/lib/alchemy/install/tasks.rb +41 -0
  231. data/lib/alchemy/modules.rb +12 -12
  232. data/lib/alchemy/name_conversions.rb +5 -5
  233. data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
  234. data/lib/alchemy/page_layout.rb +15 -12
  235. data/lib/alchemy/paths.rb +1 -1
  236. data/lib/alchemy/permissions.rb +7 -6
  237. data/lib/alchemy/resource.rb +25 -15
  238. data/lib/alchemy/resources_helper.rb +12 -18
  239. data/lib/alchemy/routing_constraints.rb +1 -1
  240. data/lib/alchemy/seeder.rb +42 -14
  241. data/lib/alchemy/shell.rb +13 -10
  242. data/lib/alchemy/taggable.rb +1 -0
  243. data/lib/alchemy/tasks/tidy.rb +4 -3
  244. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  245. data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
  246. data/lib/alchemy/test_support/factories.rb +1 -1
  247. data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
  248. data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
  249. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
  250. data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
  251. data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
  252. data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
  253. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
  254. data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
  255. data/lib/alchemy/test_support/factories/language_factory.rb +21 -14
  256. data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
  257. data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
  258. data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
  259. data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
  260. data/lib/alchemy/test_support/integration_helpers.rb +1 -0
  261. data/lib/alchemy/test_support/shared_contexts.rb +5 -4
  262. data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
  263. data/lib/alchemy/tinymce.rb +15 -13
  264. data/lib/alchemy/upgrader.rb +8 -7
  265. data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
  266. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
  267. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
  268. data/lib/alchemy/version.rb +1 -1
  269. data/lib/alchemy_cms.rb +52 -50
  270. data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
  271. data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
  272. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
  273. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
  274. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
  275. data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
  276. data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
  277. data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
  278. data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
  279. data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
  280. data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
  281. data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
  282. data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
  283. data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
  284. data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
  285. data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
  286. data/lib/generators/alchemy/install/install_generator.rb +169 -0
  287. data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
  288. data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
  289. data/lib/{rails/generators → generators}/alchemy/install/templates/menus.yml.tt +0 -0
  290. data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
  291. data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +2 -2
  292. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
  293. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
  294. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
  295. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
  296. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +1 -1
  297. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +1 -1
  298. data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
  299. data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
  300. data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
  301. data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
  302. data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
  303. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
  304. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
  305. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
  306. data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
  307. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
  308. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
  309. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
  310. data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
  311. data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
  312. data/lib/tasks/alchemy/db.rake +3 -19
  313. data/lib/tasks/alchemy/install.rake +5 -48
  314. data/lib/tasks/alchemy/tidy.rake +9 -8
  315. data/lib/tasks/alchemy/upgrade.rake +18 -116
  316. data/package.json +45 -0
  317. data/package/admin.js +14 -0
  318. data/package/src/__tests__/i18n.spec.js +70 -0
  319. data/package/src/i18n.js +48 -0
  320. data/package/src/node_tree.js +72 -0
  321. data/package/src/translations.js +32 -0
  322. data/package/src/utils/__tests__/ajax.spec.js +124 -0
  323. data/package/src/utils/__tests__/events.spec.js +38 -0
  324. data/package/src/utils/ajax.js +48 -0
  325. data/package/src/utils/events.js +16 -0
  326. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  327. data/vendor/assets/fonts/fa-regular-400.svg +798 -358
  328. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  329. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  330. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  331. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  332. data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
  333. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  334. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  335. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  336. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
  337. data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
  338. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
  339. data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
  340. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
  341. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
  342. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
  343. data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
  344. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
  345. data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
  346. data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
  347. metadata +112 -88
  348. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
  349. data/app/assets/javascripts/alchemy/alchemy.node_tree.js +0 -66
  350. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
  351. data/app/assets/javascripts/alchemy/alchemy.utils.js +0 -45
  352. data/app/helpers/alchemy/essences_helper.rb +0 -119
  353. data/app/models/concerns/alchemy/content_touching.rb +0 -23
  354. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
  355. data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
  356. data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -37
  357. data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
  358. data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
  359. data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
  360. data/app/views/alchemy/navigation/_link.html.erb +0 -19
  361. data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
  362. data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
  363. data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
  364. data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
  365. data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
  366. data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
  367. data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
  368. data/lib/alchemy/ssl_protection.rb +0 -34
  369. data/lib/alchemy/tasks/helpers.rb +0 -81
  370. data/lib/alchemy/test_support/controller_requests.rb +0 -93
  371. data/lib/alchemy/upgrader/four_point_four.rb +0 -52
  372. data/lib/alchemy/upgrader/four_point_one.rb +0 -42
  373. data/lib/alchemy/upgrader/four_point_six.rb +0 -50
  374. data/lib/alchemy/upgrader/four_point_two.rb +0 -85
  375. data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -43
  376. data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -148
  377. data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -28
  378. data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
  379. data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
  380. data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
  381. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
  382. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
  383. data/lib/tasks/alchemy/convert.rake +0 -97
  384. data/vendor/assets/javascripts/sortable/Sortable.min.js +0 -2
  385. data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
  386. data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -3,15 +3,16 @@
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
 
@@ -19,7 +20,7 @@ module Alchemy
19
20
 
20
21
  def resource_params
21
22
  params.require(:node).permit(
22
- :site_id,
23
+ :menu_type,
23
24
  :parent_id,
24
25
  :language_id,
25
26
  :page_id,
@@ -27,7 +28,7 @@ module Alchemy
27
28
  :url,
28
29
  :title,
29
30
  :nofollow,
30
- :external
31
+ :external,
31
32
  )
32
33
  end
33
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
@@ -140,7 +138,7 @@ module Alchemy
140
138
 
141
139
  def link
142
140
  @attachments = Attachment.all.collect { |f|
143
- [f.name, download_attachment_path(id: f.id, name: f.urlname)]
141
+ [f.name, download_attachment_path(id: f.id, name: f.slug)]
144
142
  }
145
143
  end
146
144
 
@@ -171,7 +169,7 @@ module Alchemy
171
169
  redirect_to show_page_url(
172
170
  urlname: @page.urlname,
173
171
  locale: prefix_locale? ? @page.language_code : nil,
174
- host: @page.site.host == "*" ? request.host : @page.site.host
172
+ host: @page.site.host == "*" ? request.host : @page.site.host,
175
173
  )
176
174
  end
177
175
 
@@ -212,24 +210,22 @@ module Alchemy
212
210
  end
213
211
 
214
212
  def flush
215
- Language.current.pages.flushables.update_all(published_at: Time.current)
213
+ @current_language.pages.flushables.update_all(published_at: Time.current)
216
214
  # We need to ensure, that also all layoutpages get the +published_at+ timestamp set,
217
215
  # but not set to public true, because the cache_key for an element is +published_at+
218
216
  # and we don't want the layout pages to be present in +Page.published+ scope.
219
- Language.current.pages.flushable_layoutpages.update_all(published_at: Time.current)
217
+ @current_language.pages.flushable_layoutpages.update_all(published_at: Time.current)
220
218
  respond_to { |format| format.js }
221
219
  end
222
220
 
223
221
  private
224
222
 
225
223
  def copy_of_language_root
226
- page_copy = Page.copy(
224
+ Page.copy(
227
225
  language_root_to_copy_from,
228
226
  language_id: params[:languages][:new_lang_id],
229
- language_code: Language.current.code
227
+ language_code: @current_language.code,
230
228
  )
231
- page_copy.move_to_child_of Page.root
232
- page_copy
233
229
  end
234
230
 
235
231
  def language_root_to_copy_from
@@ -259,14 +255,14 @@ module Alchemy
259
255
  def visit_nodes(nodes, my_left, parent, depth, tree, url, restricted)
260
256
  nodes.each do |item|
261
257
  my_right = my_left + 1
262
- my_restricted = item['restricted'] || restricted
258
+ my_restricted = item["restricted"] || restricted
263
259
  urls = process_url(url, item)
264
260
 
265
- if item['children']
266
- 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)
267
263
  end
268
264
 
269
- 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)
270
266
  my_left = my_right + 1
271
267
  end
272
268
 
@@ -295,24 +291,14 @@ module Alchemy
295
291
  # This function will add a node's own slug into their ancestor's path
296
292
  # in order to create the full URL of a node
297
293
  #
298
- # NOTE: external and invisible pages are not part of the full path of their children
299
- #
300
294
  # @param [String]
301
295
  # The node's ancestors path
302
296
  # @param [Hash]
303
297
  # A children node
304
298
  #
305
299
  def process_url(ancestors_path, item)
306
- default_urlname = (ancestors_path.blank? ? "" : "#{ancestors_path}/") + item['slug'].to_s
307
-
308
- pair = {my_urlname: default_urlname, children_path: default_urlname}
309
-
310
- if item['external'] == true || item['visible'] == false
311
- # children ignore an ancestor in their path if external or invisible
312
- pair[:children_path] = ancestors_path
313
- end
314
-
315
- pair
300
+ default_urlname = (ancestors_path.blank? ? "" : "#{ancestors_path}/") + item["slug"].to_s
301
+ { my_urlname: default_urlname, children_path: default_urlname }
316
302
  end
317
303
 
318
304
  def load_page
@@ -320,19 +306,19 @@ module Alchemy
320
306
  end
321
307
 
322
308
  def pages_from_raw_request
323
- request.raw_post.split('&').map do |i|
324
- parts = i.split('=')
309
+ request.raw_post.split("&").map do |i|
310
+ parts = i.split("=")
325
311
  {
326
- parts[0].gsub(/[^0-9]/, '') => parts[1]
312
+ parts[0].gsub(/[^0-9]/, "") => parts[1],
327
313
  }
328
314
  end
329
315
  end
330
316
 
331
317
  def redirect_path_after_create_page
332
- if @page.definition['redirects_to_external'] || !@page.editable_by?(current_alchemy_user)
333
- admin_pages_path
334
- else
318
+ if @page.editable_by?(current_alchemy_user)
335
319
  params[:redirect_to] || edit_admin_page_path(@page)
320
+ else
321
+ admin_pages_path
336
322
  end
337
323
  end
338
324
 
@@ -351,30 +337,32 @@ module Alchemy
351
337
  def page_is_locked?
352
338
  return false if !@page.locker.try(:logged_in?)
353
339
  return false if !current_alchemy_user.respond_to?(:id)
340
+
354
341
  @page.locked? && @page.locker.id != current_alchemy_user.id
355
342
  end
356
343
 
357
344
  def page_needs_lock?
358
345
  return true unless @page.locker
346
+
359
347
  @page.locker.try!(:id) != current_alchemy_user.try!(:id)
360
348
  end
361
349
 
362
350
  def paste_from_clipboard
363
351
  if params[:paste_from_clipboard]
364
352
  source = Page.find(params[:paste_from_clipboard])
365
- parent = Page.find_by(id: params[:page][:parent_id]) || Page.root
353
+ parent = Page.find_by(id: params[:page][:parent_id])
366
354
  Page.copy_and_paste(source, parent, params[:page][:name])
367
355
  end
368
356
  end
369
357
 
370
358
  def set_root_page
371
- @page_root = Language.current_root_page
359
+ @page_root = @current_language.root_page
372
360
  end
373
361
 
374
362
  def serialized_page_tree
375
363
  PageTreeSerializer.new(@page, ability: current_ability,
376
364
  user: current_alchemy_user,
377
- full: params[:full] == 'true')
365
+ full: params[:full] == "true")
378
366
  end
379
367
  end
380
368
  end
@@ -6,7 +6,7 @@ module Alchemy
6
6
  include UploaderResponses
7
7
  include ArchiveOverlay
8
8
 
9
- helper 'alchemy/admin/tags'
9
+ helper "alchemy/admin/tags"
10
10
 
11
11
  before_action :load_resource,
12
12
  only: [:show, :edit, :update, :destroy, :info]
@@ -14,12 +14,12 @@ module Alchemy
14
14
  authorize_resource class: Alchemy::Picture
15
15
 
16
16
  def index
17
- @size = params[:size].present? ? params[:size] : 'medium'
17
+ @size = params[:size].present? ? params[:size] : "medium"
18
18
  @query = Picture.ransack(search_filter_params[:q])
19
19
  @pictures = Picture.search_by(
20
20
  search_filter_params,
21
21
  @query,
22
- items_per_page
22
+ items_per_page,
23
23
  )
24
24
 
25
25
  if in_overlay?
@@ -31,7 +31,7 @@ module Alchemy
31
31
  @previous = @picture.previous(params)
32
32
  @next = @picture.next(params)
33
33
  @assignments = @picture.essence_pictures.joins(content: {element: :page})
34
- render action: 'show'
34
+ render action: "show"
35
35
  end
36
36
 
37
37
  def create
@@ -46,19 +46,19 @@ module Alchemy
46
46
 
47
47
  def edit_multiple
48
48
  @pictures = Picture.where(id: params[:picture_ids])
49
- @tags = @pictures.collect(&:tag_list).flatten.uniq.join(', ')
49
+ @tags = @pictures.collect(&:tag_list).flatten.uniq.join(", ")
50
50
  end
51
51
 
52
52
  def update
53
53
  if @picture.update(picture_params)
54
54
  @message = {
55
55
  body: Alchemy.t(:picture_updated_successfully, name: @picture.name),
56
- type: 'notice'
56
+ type: "notice",
57
57
  }
58
58
  else
59
59
  @message = {
60
60
  body: Alchemy.t(:picture_update_failed),
61
- type: 'error'
61
+ type: "error",
62
62
  }
63
63
  end
64
64
  render :update
@@ -89,7 +89,7 @@ module Alchemy
89
89
  if not_deletable.any?
90
90
  flash[:warn] = Alchemy.t(
91
91
  "These pictures could not be deleted, because they were in use",
92
- names: not_deletable.to_sentence
92
+ names: not_deletable.to_sentence,
93
93
  )
94
94
  else
95
95
  flash[:notice] = Alchemy.t("Pictures deleted successfully", names: names.to_sentence)
@@ -116,15 +116,15 @@ module Alchemy
116
116
  def items_per_page
117
117
  if in_overlay?
118
118
  case params[:size]
119
- when 'small' then 25
120
- when 'large' then 4
119
+ when "small" then 25
120
+ when "large" then 4
121
121
  else
122
122
  9
123
123
  end
124
124
  else
125
125
  cookies[:alchemy_pictures_per_page] = params[:per_page] ||
126
- cookies[:alchemy_pictures_per_page] ||
127
- pictures_per_page_for_size(params[:size])
126
+ cookies[:alchemy_pictures_per_page] ||
127
+ pictures_per_page_for_size(params[:size])
128
128
  end
129
129
  end
130
130
 
@@ -137,8 +137,8 @@ module Alchemy
137
137
 
138
138
  def pictures_per_page_for_size(size)
139
139
  case size
140
- when 'small' then 60
141
- when 'large' then 12
140
+ when "small" then 60
141
+ when "large" then 12
142
142
  else
143
143
  20
144
144
  end
@@ -154,8 +154,8 @@ module Alchemy
154
154
  :size,
155
155
  :element_id,
156
156
  :swap,
157
- :content_id
158
- ]
157
+ :content_id,
158
+ ],
159
159
  )
160
160
  end
161
161
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'csv'
4
- require 'alchemy/resource'
5
- require 'alchemy/resources_helper'
3
+ require "csv"
4
+ require "alchemy/resource"
5
+ require "alchemy/resources_helper"
6
6
 
7
7
  module Alchemy
8
8
  module Admin
@@ -22,6 +22,7 @@ module Alchemy
22
22
 
23
23
  def index
24
24
  @query = resource_handler.model.ransack(search_filter_params[:q])
25
+ @query.sorts = default_sort_order if @query.sorts.empty?
25
26
  items = @query.result
26
27
 
27
28
  if contains_relations?
@@ -52,7 +53,7 @@ module Alchemy
52
53
  end
53
54
 
54
55
  def show
55
- render action: 'edit'
56
+ render action: "edit"
56
57
  end
57
58
 
58
59
  def edit; end
@@ -63,7 +64,7 @@ module Alchemy
63
64
  render_errors_or_redirect(
64
65
  resource_instance_variable,
65
66
  resources_path(resource_instance_variable.class, search_filter_params),
66
- flash_notice_for_resource_action
67
+ flash_notice_for_resource_action,
67
68
  )
68
69
  end
69
70
 
@@ -72,14 +73,17 @@ module Alchemy
72
73
  render_errors_or_redirect(
73
74
  resource_instance_variable,
74
75
  resources_path(resource_instance_variable.class, search_filter_params),
75
- flash_notice_for_resource_action
76
+ flash_notice_for_resource_action,
76
77
  )
77
78
  end
78
79
 
79
80
  def destroy
80
81
  resource_instance_variable.destroy
82
+ if resource_instance_variable.errors.any?
83
+ flash[:error] = resource_instance_variable.errors.full_messages.join(", ")
84
+ end
81
85
  flash_notice_for_resource_action
82
- do_redirect_to resource_url_proxy.url_for(search_filter_params.merge(action: 'index'))
86
+ do_redirect_to resource_url_proxy.url_for(search_filter_params.merge(action: "index"))
83
87
  end
84
88
 
85
89
  def resource_handler
@@ -92,6 +96,7 @@ module Alchemy
92
96
  # The key should look like "Modelname successfully created|updated|destroyed."
93
97
  def flash_notice_for_resource_action(action = params[:action])
94
98
  return if resource_instance_variable.errors.any?
99
+
95
100
  case action.to_sym
96
101
  when :create
97
102
  verb = "created"
@@ -104,11 +109,11 @@ module Alchemy
104
109
  end
105
110
 
106
111
  def is_alchemy_module?
107
- !alchemy_module.nil? && !alchemy_module['engine_name'].nil?
112
+ !alchemy_module.nil? && !alchemy_module["engine_name"].nil?
108
113
  end
109
114
 
110
115
  def alchemy_module
111
- @alchemy_module ||= module_definition_for(controller: params[:controller], action: 'index')
116
+ @alchemy_module ||= module_definition_for(controller: params[:controller], action: "index")
112
117
  end
113
118
 
114
119
  def load_resource
@@ -143,16 +148,14 @@ module Alchemy
143
148
 
144
149
  def common_search_filter_includes
145
150
  [
146
- # contrary to Rails' documentation passing an empty hash to permit all keys does not work
147
- {options: options_from_params.keys},
148
151
  {q: [
149
152
  resource_handler.search_field_name,
150
- :s
153
+ :s,
151
154
  ]},
152
155
  :tagged_with,
153
156
  :filter,
154
157
  :page,
155
- :per_page
158
+ :per_page,
156
159
  ].freeze
157
160
  end
158
161
 
@@ -164,6 +167,11 @@ module Alchemy
164
167
  per_page = Alchemy::Config.get(:items_per_page)
165
168
  [per_page, per_page * 2, per_page * 4]
166
169
  end
170
+
171
+ def default_sort_order
172
+ name = resource_handler.attributes.detect { |attr| attr[:name] == "name" }
173
+ name ? "name asc" : "#{resource_handler.attributes.first[:name]} asc"
174
+ end
167
175
  end
168
176
  end
169
177
  end