alchemy_cms 4.6.7 → 5.0.0.beta1

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 (384) 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 +31 -10
  8. data/CHANGELOG.md +89 -32
  9. data/Gemfile +24 -22
  10. data/README.md +31 -19
  11. data/Rakefile +10 -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/node-select.scss +43 -0
  25. data/app/assets/stylesheets/alchemy/nodes.scss +1 -1
  26. data/app/assets/stylesheets/alchemy/sitemap.scss +5 -1
  27. data/app/assets/stylesheets/alchemy/tables.scss +1 -24
  28. data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +3 -3
  29. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +7 -7
  30. data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
  31. data/app/controllers/alchemy/admin/base_controller.rb +16 -42
  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 +50 -62
  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 +36 -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 +3 -3
  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 +2 -1
  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 +21 -19
  81. data/app/models/alchemy/base_record.rb +2 -5
  82. data/app/models/alchemy/content/factory.rb +24 -31
  83. data/app/models/alchemy/content.rb +33 -38
  84. data/app/models/alchemy/element/definitions.rb +4 -4
  85. data/app/models/alchemy/element/element_contents.rb +9 -6
  86. data/app/models/alchemy/element/element_essences.rb +4 -3
  87. data/app/models/alchemy/element/presenters.rb +3 -2
  88. data/app/models/alchemy/element.rb +46 -54
  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 +4 -4
  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 +17 -16
  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/code.rb +4 -4
  104. data/app/models/alchemy/language.rb +21 -35
  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 +28 -5
  108. data/app/models/alchemy/page/fixed_attributes.rb +3 -2
  109. data/app/models/alchemy/page/page_elements.rb +35 -44
  110. data/app/models/alchemy/page/page_naming.rb +20 -70
  111. data/app/models/alchemy/page/page_natures.rb +7 -34
  112. data/app/models/alchemy/page/page_scopes.rb +23 -29
  113. data/app/models/alchemy/page/url_path.rb +0 -2
  114. data/app/models/alchemy/page.rb +47 -128
  115. data/app/models/alchemy/picture/transformations.rb +9 -7
  116. data/app/models/alchemy/picture/url.rb +5 -5
  117. data/app/models/alchemy/picture.rb +19 -28
  118. data/app/models/alchemy/site/layout.rb +2 -2
  119. data/app/models/alchemy/site.rb +6 -36
  120. data/app/models/concerns/alchemy/touch_elements.rb +24 -0
  121. data/app/serializers/alchemy/content_serializer.rb +0 -3
  122. data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
  123. data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
  124. data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
  125. data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
  126. data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
  127. data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
  128. data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
  129. data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
  130. data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
  131. data/app/serializers/alchemy/node_serializer.rb +2 -0
  132. data/app/serializers/alchemy/page_tree_serializer.rb +9 -13
  133. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
  134. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
  135. data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
  136. data/app/views/alchemy/admin/contents/create.js.erb +1 -3
  137. data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
  138. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  139. data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
  140. data/app/views/alchemy/admin/elements/index.html.erb +3 -3
  141. data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
  142. data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
  143. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
  144. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
  145. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
  146. data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
  147. data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
  148. data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
  149. data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
  150. data/app/views/alchemy/admin/languages/index.html.erb +23 -4
  151. data/app/views/alchemy/admin/languages/new.html.erb +1 -0
  152. data/app/views/alchemy/admin/layoutpages/index.html.erb +3 -3
  153. data/app/views/alchemy/admin/nodes/_form.html.erb +18 -15
  154. data/app/views/alchemy/admin/nodes/_node.html.erb +1 -5
  155. data/app/views/alchemy/admin/nodes/index.html.erb +3 -4
  156. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
  157. data/app/views/alchemy/admin/pages/_form.html.erb +0 -1
  158. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
  159. data/app/views/alchemy/admin/pages/_page.html.erb +11 -19
  160. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
  161. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  162. data/app/views/alchemy/admin/pages/info.html.erb +0 -9
  163. data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
  164. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
  165. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
  166. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  167. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
  168. data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
  169. data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
  170. data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
  171. data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
  172. data/app/views/alchemy/admin/sites/index.html.erb +21 -9
  173. data/app/views/alchemy/admin/sites/new.html.erb +1 -0
  174. data/app/views/alchemy/admin/tags/index.html.erb +2 -2
  175. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
  176. data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
  177. data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
  178. data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
  179. data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
  180. data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
  181. data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
  182. data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
  183. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
  184. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
  185. data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
  186. data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
  187. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
  188. data/app/views/alchemy/pages/show.rss.builder +3 -2
  189. data/app/views/layouts/alchemy/admin.html.erb +1 -0
  190. data/babel.config.js +12 -0
  191. data/bin/rails +5 -4
  192. data/config/alchemy/config.yml +15 -18
  193. data/config/brakeman.ignore +1 -1
  194. data/config/initializers/assets.rb +2 -1
  195. data/config/initializers/dragonfly.rb +2 -1
  196. data/config/initializers/mime_types.rb +1 -0
  197. data/config/initializers/mini_profiler.rb +3 -2
  198. data/config/initializers/simple_form.rb +6 -6
  199. data/config/locales/alchemy.en.yml +23 -8
  200. data/config/routes.rb +25 -24
  201. data/config/spring.rb +3 -2
  202. data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
  203. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
  204. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
  205. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
  206. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
  207. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
  208. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
  209. data/lib/alchemy/admin/locale.rb +3 -1
  210. data/lib/alchemy/admin/preview_url.rb +64 -0
  211. data/lib/alchemy/auth_accessors.rb +8 -7
  212. data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
  213. data/lib/alchemy/config.rb +1 -5
  214. data/lib/alchemy/configuration_methods.rb +3 -1
  215. data/lib/alchemy/controller_actions.rb +6 -5
  216. data/lib/alchemy/deprecation.rb +2 -1
  217. data/lib/alchemy/elements_finder.rb +5 -5
  218. data/lib/alchemy/engine.rb +22 -14
  219. data/lib/alchemy/errors.rb +0 -7
  220. data/lib/alchemy/essence.rb +17 -16
  221. data/lib/alchemy/filetypes.rb +5 -5
  222. data/lib/alchemy/forms/builder.rb +4 -4
  223. data/lib/alchemy/hints.rb +1 -1
  224. data/lib/alchemy/i18n.rb +2 -1
  225. data/lib/alchemy/modules.rb +12 -12
  226. data/lib/alchemy/name_conversions.rb +5 -5
  227. data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
  228. data/lib/alchemy/page_layout.rb +15 -12
  229. data/lib/alchemy/paths.rb +1 -1
  230. data/lib/alchemy/permissions.rb +7 -6
  231. data/lib/alchemy/resource.rb +25 -17
  232. data/lib/alchemy/resources_helper.rb +12 -18
  233. data/lib/alchemy/routing_constraints.rb +1 -1
  234. data/lib/alchemy/seeder.rb +42 -14
  235. data/lib/alchemy/shell.rb +13 -10
  236. data/lib/alchemy/taggable.rb +1 -0
  237. data/lib/alchemy/tasks/tidy.rb +4 -3
  238. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  239. data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
  240. data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
  241. data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
  242. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
  243. data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
  244. data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
  245. data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
  246. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
  247. data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
  248. data/lib/alchemy/test_support/factories/language_factory.rb +16 -14
  249. data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
  250. data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
  251. data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
  252. data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
  253. data/lib/alchemy/test_support/factories.rb +1 -1
  254. data/lib/alchemy/test_support/integration_helpers.rb +1 -0
  255. data/lib/alchemy/test_support/shared_contexts.rb +5 -4
  256. data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
  257. data/lib/alchemy/tinymce.rb +15 -13
  258. data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
  259. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
  260. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
  261. data/lib/alchemy/upgrader.rb +8 -7
  262. data/lib/alchemy/userstamp.rb +1 -1
  263. data/lib/alchemy/version.rb +1 -1
  264. data/lib/alchemy_cms.rb +52 -51
  265. data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
  266. data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
  267. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
  268. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
  269. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
  270. data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
  271. data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
  272. data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
  273. data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
  274. data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
  275. data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
  276. data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
  277. data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
  278. data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
  279. data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
  280. data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
  281. data/lib/generators/alchemy/install/install_generator.rb +110 -0
  282. data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
  283. data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
  284. data/lib/{rails/generators → generators}/alchemy/install/templates/menus.yml.tt +0 -0
  285. data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
  286. data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +2 -2
  287. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
  288. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
  289. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
  290. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
  291. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +1 -1
  292. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +1 -1
  293. data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
  294. data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
  295. data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
  296. data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
  297. data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
  298. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
  299. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
  300. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
  301. data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
  302. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
  303. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
  304. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
  305. data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
  306. data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
  307. data/lib/tasks/alchemy/db.rake +3 -19
  308. data/lib/tasks/alchemy/install.rake +3 -2
  309. data/lib/tasks/alchemy/tidy.rake +9 -8
  310. data/lib/tasks/alchemy/upgrade.rake +18 -120
  311. data/package/admin.js +14 -0
  312. data/package/src/__tests__/i18n.spec.js +70 -0
  313. data/package/src/i18n.js +48 -0
  314. data/package/src/node_tree.js +72 -0
  315. data/package/src/translations.js +32 -0
  316. data/package/src/utils/__tests__/ajax.spec.js +124 -0
  317. data/package/src/utils/__tests__/events.spec.js +38 -0
  318. data/package/src/utils/ajax.js +48 -0
  319. data/package/src/utils/events.js +16 -0
  320. data/package.json +45 -0
  321. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  322. data/vendor/assets/fonts/fa-regular-400.svg +798 -358
  323. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  324. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  325. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  326. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  327. data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
  328. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  329. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  330. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  331. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
  332. data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
  333. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
  334. data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
  335. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
  336. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
  337. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
  338. data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
  339. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
  340. data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
  341. data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
  342. metadata +117 -98
  343. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
  344. data/app/assets/javascripts/alchemy/alchemy.node_tree.js +0 -66
  345. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
  346. data/app/assets/javascripts/alchemy/alchemy.utils.js +0 -45
  347. data/app/helpers/alchemy/essences_helper.rb +0 -119
  348. data/app/models/concerns/alchemy/content_touching.rb +0 -23
  349. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
  350. data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
  351. data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -37
  352. data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
  353. data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
  354. data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
  355. data/app/views/alchemy/navigation/_link.html.erb +0 -19
  356. data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
  357. data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
  358. data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
  359. data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
  360. data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
  361. data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
  362. data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
  363. data/lib/alchemy/error_tracking/airbrake_handler.rb +0 -13
  364. data/lib/alchemy/error_tracking.rb +0 -14
  365. data/lib/alchemy/ssl_protection.rb +0 -34
  366. data/lib/alchemy/tasks/helpers.rb +0 -81
  367. data/lib/alchemy/test_support/controller_requests.rb +0 -93
  368. data/lib/alchemy/upgrader/four_point_four.rb +0 -52
  369. data/lib/alchemy/upgrader/four_point_one.rb +0 -42
  370. data/lib/alchemy/upgrader/four_point_six.rb +0 -50
  371. data/lib/alchemy/upgrader/four_point_two.rb +0 -86
  372. data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -45
  373. data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -166
  374. data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -32
  375. data/lib/alchemy/upgrader/tasks/fixed_element_name_finder.rb +0 -31
  376. data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
  377. data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
  378. data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
  379. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
  380. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
  381. data/lib/tasks/alchemy/convert.rake +0 -98
  382. data/vendor/assets/javascripts/sortable/Sortable.min.js +0 -2
  383. data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
  384. data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -36,7 +36,7 @@ module Alchemy
36
36
  module GuestUser
37
37
  def alchemy_guest_user_rules
38
38
  can([:show, :download], Alchemy::Attachment) { |a| !a.restricted? }
39
- can :see, Alchemy::Page, restricted: false, visible: true
39
+ can :see, Alchemy::Page, restricted: false
40
40
 
41
41
  can :read, Alchemy::Content, Alchemy::Content.available.not_restricted do |c|
42
42
  c.public? && !c.restricted? && !c.trashed?
@@ -64,7 +64,7 @@ module Alchemy
64
64
 
65
65
  # Resources
66
66
  can [:show, :download], Alchemy::Attachment
67
- can :see, Alchemy::Page, restricted: true, visible: true
67
+ can :see, Alchemy::Page, restricted: true
68
68
 
69
69
  can :read, Alchemy::Content, Alchemy::Content.available do |c|
70
70
  c.public? && !c.trashed?
@@ -99,7 +99,7 @@ module Alchemy
99
99
  :alchemy_admin_pages,
100
100
  :alchemy_admin_pictures,
101
101
  :alchemy_admin_tags,
102
- :alchemy_admin_users
102
+ :alchemy_admin_users,
103
103
  ]
104
104
 
105
105
  # Controller actions
@@ -137,7 +137,7 @@ module Alchemy
137
137
  # Navigation
138
138
  can :index, [
139
139
  :alchemy_admin_languages,
140
- :alchemy_admin_users
140
+ :alchemy_admin_users,
141
141
  ]
142
142
 
143
143
  # Controller actions
@@ -150,7 +150,7 @@ module Alchemy
150
150
  :flush,
151
151
  :order,
152
152
  :sort,
153
- :switch_language
153
+ :switch_language,
154
154
  ], Alchemy::Page
155
155
 
156
156
  # Resources which may be locked via template permissions
@@ -164,7 +164,7 @@ module Alchemy
164
164
  can([
165
165
  :create,
166
166
  :destroy,
167
- :publish
167
+ :publish,
168
168
  ], Alchemy::Page) { |p| p.editable_by?(@user) }
169
169
 
170
170
  can :manage, Alchemy::Picture
@@ -200,6 +200,7 @@ module Alchemy
200
200
 
201
201
  def user_role_rules
202
202
  return alchemy_guest_user_rules if @user.alchemy_roles.blank?
203
+
203
204
  @user.alchemy_roles.each do |role|
204
205
  exec_role_rules(role)
205
206
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support'
4
- require 'active_support/core_ext'
5
- require 'active_support/inflector'
3
+ require "active_support"
4
+ require "active_support/core_ext"
5
+ require "active_support/inflector"
6
6
 
7
7
  module Alchemy
8
8
  # = Alchemy::Resource
@@ -101,8 +101,8 @@ module Alchemy
101
101
  attr_accessor :resource_relations, :model_associations
102
102
  attr_reader :model
103
103
 
104
- DEFAULT_SKIPPED_ATTRIBUTES = %w(id updated_at created_at creator_id updater_id)
105
- DEFAULT_SKIPPED_ASSOCIATIONS = %w(creator updater)
104
+ DEFAULT_SKIPPED_ATTRIBUTES = %w(id created_at creator_id)
105
+ DEFAULT_SKIPPED_ASSOCIATIONS = %w(creator)
106
106
  SEARCHABLE_COLUMN_TYPES = [:string, :text]
107
107
 
108
108
  def initialize(controller_path, module_definition = nil, custom_model = nil)
@@ -113,13 +113,14 @@ module Alchemy
113
113
  if !model.respond_to?(:reflect_on_all_associations)
114
114
  raise MissingActiveRecordAssociation
115
115
  end
116
+
116
117
  store_model_associations
117
118
  map_relations
118
119
  end
119
120
  end
120
121
 
121
122
  def resource_array
122
- @_resource_array ||= controller_path_array.reject { |el| el == 'admin' }
123
+ @_resource_array ||= controller_path_array.reject { |el| el == "admin" }
123
124
  end
124
125
 
125
126
  def resources_name
@@ -131,9 +132,7 @@ module Alchemy
131
132
  end
132
133
 
133
134
  def namespaced_resource_name
134
- @_namespaced_resource_name ||= begin
135
- namespaced_resources_name.to_s.singularize
136
- end.to_sym # Rails >= 6.0.3.7 needs symbols in polymorphic routes
135
+ @_namespaced_resource_name ||= namespaced_resources_name.singularize
137
136
  end
138
137
 
139
138
  def namespaced_resources_name
@@ -141,19 +140,20 @@ module Alchemy
141
140
  resource_name_array = resource_array.dup
142
141
  resource_name_array.delete(engine_name) if in_engine?
143
142
  resource_name_array.join("_")
144
- end.to_sym # Rails >= 6.0.3.7 needs symbols in polymorphic routes
143
+ end
145
144
  end
146
145
 
147
146
  def namespace_for_scope
148
147
  namespace_array = namespace_diff
149
148
  namespace_array.delete(engine_name) if in_engine?
150
- namespace_array.map(&:to_sym) # Rails >= 6.0.3.7 needs symbols in polymorphic routes
149
+ namespace_array
151
150
  end
152
151
 
153
152
  # Returns an array of underscored association names
154
153
  #
155
154
  def model_association_names
156
155
  return unless model_associations
156
+
157
157
  model_associations.map do |assoc|
158
158
  assoc.name.to_sym
159
159
  end
@@ -162,14 +162,22 @@ module Alchemy
162
162
  def attributes
163
163
  @_attributes ||= model.columns.collect do |col|
164
164
  next if skipped_attributes.include?(col.name)
165
+
165
166
  {
166
167
  name: col.name,
167
168
  type: resource_column_type(col),
168
- relation: resource_relation(col.name)
169
+ relation: resource_relation(col.name),
169
170
  }.delete_if { |_k, v| v.nil? }
170
171
  end.compact
171
172
  end
172
173
 
174
+ def sorted_attributes
175
+ @_sorted_attributes ||= attributes.
176
+ sort_by { |attr| attr[:name] == "name" ? 0 : 1 }.
177
+ sort_by! { |attr| attr[:type] == :boolean ? 1 : 0 }.
178
+ sort_by! { |attr| attr[:name] == "updated_at" ? 1 : 0 }
179
+ end
180
+
173
181
  def editable_attributes
174
182
  attributes.reject { |h| restricted_attributes.map(&:to_s).include?(h[:name].to_s) }
175
183
  end
@@ -199,7 +207,7 @@ module Alchemy
199
207
  end
200
208
 
201
209
  def engine_name
202
- @module_definition && @module_definition['engine_name']
210
+ @module_definition && @module_definition["engine_name"]
203
211
  end
204
212
 
205
213
  # Returns a help text for resource's form
@@ -256,16 +264,16 @@ module Alchemy
256
264
  def searchable_relation_attribute(attribute)
257
265
  {
258
266
  name: "#{attribute[:relation][:model_association].name}_#{attribute[:relation][:attr_method]}",
259
- type: attribute[:relation][:attr_type]
267
+ type: attribute[:relation][:attr_type],
260
268
  }
261
269
  end
262
270
 
263
271
  def guess_model_from_controller_path
264
- resource_array.join('/').classify.constantize
272
+ resource_array.join("/").classify.constantize
265
273
  end
266
274
 
267
275
  def controller_path_array
268
- @controller_path.split('/')
276
+ @controller_path.split("/")
269
277
  end
270
278
 
271
279
  def namespace_diff
@@ -288,7 +296,7 @@ module Alchemy
288
296
  def map_relations
289
297
  self.resource_relations = {}
290
298
  model.alchemy_resource_relations.each do |name, options|
291
- name = name.to_s.gsub(/_id$/, '') # ensure that we don't have an id
299
+ name = name.to_s.gsub(/_id$/, "") # ensure that we don't have an id
292
300
  association = association_from_relation_name(name)
293
301
  foreign_key = association.options[:foreign_key] || "#{association.name}_id".to_sym
294
302
  resource_relations[foreign_key] = options.merge(model_association: association, name: name)
@@ -104,30 +104,24 @@ module Alchemy
104
104
  options = {hint: resource_handler.help_text_for(attribute)}
105
105
  input_type = attribute[:type].to_s
106
106
  case input_type
107
- when 'boolean'
107
+ when "boolean"
108
108
  options
109
- when 'date', 'time', 'datetime'
109
+ when "date", "time", "datetime"
110
110
  date = resource_instance_variable.send(attribute[:name]) || Time.current
111
111
  options.merge(
112
- as: 'string',
112
+ as: "string",
113
113
  input_html: {
114
- 'data-datepicker-type' => input_type,
115
- value: date ? date.iso8601 : nil
116
- }
114
+ "data-datepicker-type" => input_type,
115
+ value: date ? date.iso8601 : nil,
116
+ },
117
117
  )
118
- when 'text'
119
- options.merge(as: 'text', input_html: {rows: 4})
118
+ when "text"
119
+ options.merge(as: "text", input_html: {rows: 4})
120
120
  else
121
- options.merge(as: 'string')
121
+ options.merge(as: "string")
122
122
  end
123
123
  end
124
124
 
125
- # Renders the human model name with a count as h1 header
126
- def resources_header
127
- Alchemy::Deprecation.warn "resources_header is deprecated. Render 'alchemy/admin/resources/table_header' partial instead."
128
- render 'alchemy/admin/resources/table_header'
129
- end
130
-
131
125
  # Returns true if the resource contains any relations
132
126
  def contains_relations?
133
127
  resource_handler.resource_relations.present?
@@ -171,7 +165,7 @@ module Alchemy
171
165
  def render_resources
172
166
  render partial: resource_name, collection: resources_instance_variable
173
167
  rescue ActionView::MissingTemplate
174
- render partial: 'resource', collection: resources_instance_variable
168
+ render partial: "resource", collection: resources_instance_variable
175
169
  end
176
170
 
177
171
  def resource_has_tags
@@ -185,8 +179,8 @@ module Alchemy
185
179
  def resource_filter_select
186
180
  resource_model.alchemy_resource_filters.map do |filter_scope|
187
181
  [
188
- Alchemy.t(filter_scope.to_sym, scope: ['resources', resource_name, 'filters']),
189
- filter_scope
182
+ Alchemy.t(filter_scope.to_sym, scope: ["resources", resource_name, "filters"]),
183
+ filter_scope,
190
184
  ]
191
185
  end
192
186
  end
@@ -34,7 +34,7 @@ module Alchemy
34
34
  def no_rails_route?
35
35
  return true if !%w(development test).include?(Rails.env)
36
36
 
37
- (@params['urlname'] =~ /\Arails\//).nil?
37
+ (@params["urlname"] =~ /\Arails\//).nil?
38
38
  end
39
39
  end
40
40
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "alchemy/shell"
2
3
 
3
4
  module Alchemy
@@ -23,11 +24,14 @@ module Alchemy
23
24
 
24
25
  def try_seed_pages
25
26
  return unless page_seeds_file.file?
27
+
26
28
  if Alchemy::Page.exists?
27
29
  desc "Seeding Alchemy pages"
28
30
  log "There are already pages present in your database. " \
29
31
  "Please use `rake db:reset' if you want to rebuild your database.", :skip
30
32
  else
33
+ create_default_site! unless Alchemy::Site.default
34
+ create_default_language! unless Alchemy::Language.default
31
35
  seed_pages if contentpages.present?
32
36
  seed_layoutpages if layoutpages.present?
33
37
  end
@@ -41,9 +45,8 @@ module Alchemy
41
45
 
42
46
  contentpages.each do |page|
43
47
  create_page(page, {
44
- parent: Alchemy::Page.root,
45
48
  language: Alchemy::Language.default,
46
- language_root: true
49
+ language_root: true,
47
50
  })
48
51
  end
49
52
  end
@@ -51,12 +54,8 @@ module Alchemy
51
54
  def seed_layoutpages
52
55
  desc "Seeding Alchemy layout pages from #{page_seeds_file}"
53
56
  language = Alchemy::Language.default
54
- layout_root = Alchemy::Page.find_or_create_layout_root_for(language.id)
55
57
  layoutpages.each do |page|
56
- create_page(page, {
57
- parent: layout_root,
58
- language: language
59
- })
58
+ create_page(page, { language: language })
60
59
  end
61
60
  end
62
61
 
@@ -66,7 +65,7 @@ module Alchemy
66
65
  if Alchemy.user_class.exists?
67
66
  log "There are already users present in your database. " \
68
67
  "Please use `rake db:reset' if you want to rebuild your database.", :skip
69
- return false
68
+ false
70
69
  else
71
70
  users = YAML.load_file(user_seeds_file)
72
71
  users.each do |draft|
@@ -79,7 +78,7 @@ module Alchemy
79
78
  private
80
79
 
81
80
  def page_seeds_file
82
- @_page_seeds_file ||= Rails.root.join('db', 'seeds', 'alchemy', 'pages.yml')
81
+ @_page_seeds_file ||= Rails.root.join("db", "seeds", "alchemy", "pages.yml")
83
82
  end
84
83
 
85
84
  def page_yml
@@ -87,23 +86,52 @@ module Alchemy
87
86
  end
88
87
 
89
88
  def contentpages
90
- page_yml.reject { |p| p['layoutpage'] }
89
+ page_yml.reject { |p| p["layoutpage"] }
91
90
  end
92
91
 
93
92
  def layoutpages
94
- page_yml.select { |p| p['layoutpage'] }
93
+ page_yml.select { |p| p["layoutpage"] }
95
94
  end
96
95
 
97
96
  def user_seeds_file
98
- @_user_seeds_file ||= Rails.root.join('db', 'seeds', 'alchemy', 'users.yml')
97
+ @_user_seeds_file ||= Rails.root.join("db", "seeds", "alchemy", "users.yml")
99
98
  end
100
99
 
101
100
  def create_page(draft, attributes = {})
102
- children = draft.delete('children') || []
101
+ children = draft.delete("children") || []
103
102
  page = Alchemy::Page.create!(draft.merge(attributes))
104
103
  log "Created page: #{page.name}"
105
104
  children.each do |child|
106
- create_page(child, parent: page)
105
+ create_page(child, parent: page, language: page.language)
106
+ end
107
+ end
108
+
109
+ # If no languages are present, create a default language based
110
+ # on the host app's Alchemy configuration.
111
+ def create_default_language!
112
+ default_language = Alchemy::Config.get(:default_language)
113
+ if default_language
114
+ Alchemy::Language.create!(
115
+ name: default_language["name"],
116
+ language_code: default_language["code"],
117
+ locale: default_language["code"],
118
+ frontpage_name: default_language["frontpage_name"],
119
+ page_layout: default_language["page_layout"],
120
+ public: true,
121
+ default: true,
122
+ site: Alchemy::Site.default,
123
+ )
124
+ else
125
+ raise DefaultLanguageNotFoundError
126
+ end
127
+ end
128
+
129
+ def create_default_site!
130
+ default_site = Alchemy::Config.get(:default_site)
131
+ if default_site
132
+ Alchemy::Site.create!(name: default_site["name"], host: default_site["host"])
133
+ else
134
+ raise DefaultSiteNotFoundError
107
135
  end
108
136
  end
109
137
  end
data/lib/alchemy/shell.rb CHANGED
@@ -1,10 +1,18 @@
1
- require 'thor/shell/color'
1
+ # frozen_string_literal: true
2
+ require "thor/shell/color"
2
3
 
3
4
  module Alchemy
4
5
  # Provides methods for collecting sentences and displaying them
5
6
  # in a list on the shell / log
6
7
  #
7
8
  module Shell
9
+ COLORS = {
10
+ clear: Thor::Shell::Color::CLEAR,
11
+ green: Thor::Shell::Color::GREEN,
12
+ red: Thor::Shell::Color::RED,
13
+ yellow: Thor::Shell::Color::YELLOW,
14
+ }.freeze
15
+
8
16
  def self.silence!
9
17
  @silenced = true
10
18
  end
@@ -20,11 +28,11 @@ module Alchemy
20
28
  def desc(message)
21
29
  unless Alchemy::Shell.silenced?
22
30
  puts "\n#{message}"
23
- puts "#{'-' * message.length}\n"
31
+ puts "#{"-" * message.length}\n"
24
32
  end
25
33
  end
26
34
 
27
- def todo(todo, title = '')
35
+ def todo(todo, title = "")
28
36
  add_todo [title, todo]
29
37
  end
30
38
 
@@ -56,7 +64,7 @@ module Alchemy
56
64
  todos.each_with_index do |todo, i|
57
65
  title = "\n#{i + 1}. #{todo[0]}"
58
66
  log title, :message
59
- puts '=' * title.length
67
+ puts "=" * title.length
60
68
  puts ""
61
69
  log todo[1], :message
62
70
  end
@@ -96,12 +104,7 @@ module Alchemy
96
104
  # @return [String]
97
105
  #
98
106
  def color(name)
99
- color_const = name.to_s.upcase
100
- if Thor::Shell::Color.const_defined?(color_const)
101
- "Thor::Shell::Color::#{color_const}".constantize
102
- else
103
- ""
104
- end
107
+ COLORS[name]
105
108
  end
106
109
  end
107
110
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
3
  # ActsAsTaggableOn to Gutentag interface compatibility module
3
4
  # Include this module to add tagging support to your model.
@@ -1,4 +1,5 @@
1
- require 'alchemy/shell'
1
+ # frozen_string_literal: true
2
+ require "alchemy/shell"
2
3
 
3
4
  module Alchemy
4
5
  class Tidy
@@ -52,7 +53,7 @@ module Alchemy
52
53
  end
53
54
  if orphaned_elements.any?
54
55
  log "Found #{orphaned_elements.size} orphaned elements"
55
- destroy_orphaned_records(orphaned_elements, 'element')
56
+ destroy_orphaned_records(orphaned_elements, "element")
56
57
  else
57
58
  log "No orphaned elements found", :skip
58
59
  end
@@ -71,7 +72,7 @@ module Alchemy
71
72
  end
72
73
  if orphaned_contents.any?
73
74
  log "Found #{orphaned_contents.size} orphaned contents"
74
- destroy_orphaned_records(orphaned_contents, 'content')
75
+ destroy_orphaned_records(orphaned_contents, "content")
75
76
  else
76
77
  log "No orphaned contents found", :skip
77
78
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
3
  module TestSupport
3
4
  # Allows you to stub the Alchemy configuration in your specs