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
@@ -1,36 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
4
- require 'alchemy/test_support/factories/language_factory'
3
+ require "factory_bot"
4
+ require "alchemy/test_support/factories/language_factory"
5
5
 
6
6
  FactoryBot.define do
7
- factory :alchemy_page, class: 'Alchemy::Page' do
8
- language { Alchemy::Language.default || FactoryBot.create(:alchemy_language) }
7
+ factory :alchemy_page, class: "Alchemy::Page" do
8
+ language do
9
+ @cached_attributes[:parent]&.language ||
10
+ Alchemy::Language.default ||
11
+ FactoryBot.create(:alchemy_language)
12
+ end
9
13
  sequence(:name) { |n| "A Page #{n}" }
10
14
  page_layout { "standard" }
11
15
 
12
- parent_id do
13
- (Alchemy::Page.find_by(language_root: true) ||
14
- FactoryBot.create(:alchemy_page, :language_root)).id
16
+ parent do
17
+ Alchemy::Page.find_by(language_root: true, language: language) ||
18
+ FactoryBot.create(:alchemy_page, :language_root, language: language)
15
19
  end
16
20
 
17
21
  # This speeds up creating of pages dramatically.
18
22
  # Pass autogenerate_elements: true to generate elements
19
23
  autogenerate_elements { false }
20
24
 
21
- trait :root do
22
- name { 'Root' }
23
- language { nil }
24
- parent_id { nil }
25
- page_layout { nil }
26
- end
27
-
28
25
  trait :language_root do
29
- name { 'Startseite' }
30
- page_layout { language.page_layout }
26
+ name { language&.frontpage_name || "Intro" }
27
+ page_layout { language&.page_layout || "index" }
31
28
  language_root { true }
32
29
  public_on { Time.current }
33
- parent_id { Alchemy::Page.root.id }
30
+ parent { nil }
34
31
  end
35
32
 
36
33
  trait :public do
@@ -38,17 +35,8 @@ FactoryBot.define do
38
35
  public_on { Time.current }
39
36
  end
40
37
 
41
- trait :system do
42
- name { "Systempage" }
43
- parent_id { Alchemy::Page.root.id }
44
- language_root { false }
45
- page_layout { nil }
46
- language { nil }
47
- end
48
-
49
38
  trait :layoutpage do
50
- name { "Footer" }
51
- parent_id { Alchemy::Page.find_or_create_layout_root_for(Alchemy::Language.current.id).id }
39
+ parent { nil }
52
40
  layoutpage { true }
53
41
  page_layout { "footer" }
54
42
  end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
3
+ require "factory_bot"
4
4
 
5
5
  FactoryBot.define do
6
- factory :alchemy_picture, class: 'Alchemy::Picture' do
6
+ factory :alchemy_picture, class: "Alchemy::Picture" do
7
7
  image_file do
8
- File.new(Alchemy::Engine.root.join('lib', 'alchemy', 'test_support', 'fixtures', 'image.png'))
8
+ File.new(Alchemy::Engine.root.join("lib", "alchemy", "test_support", "fixtures", "image.png"))
9
9
  end
10
- name { 'image' }
11
- image_file_name { 'image.png' }
10
+ name { "image" }
11
+ image_file_name { "image.png" }
12
12
  upload_hash { Time.current.hash }
13
13
  end
14
14
  end
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
3
+ require "factory_bot"
4
4
 
5
5
  FactoryBot.define do
6
- factory :alchemy_site, class: 'Alchemy::Site' do
7
- name { 'A Site' }
8
- host { 'domain.com' }
6
+ factory :alchemy_site, class: "Alchemy::Site" do
7
+ name { "A Site" }
8
+ host { "domain.com" }
9
9
 
10
10
  trait :default do
11
11
  public { true }
12
- name { Alchemy::Config.get(:default_site)['name'] }
13
- host { Alchemy::Config.get(:default_site)['host'] }
12
+
13
+ name { Alchemy::Config.get(:default_site)["name"] }
14
+ host { Alchemy::Config.get(:default_site)["host"] }
14
15
  end
15
16
 
16
17
  trait :public do
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Dir["#{File.dirname(__FILE__)}/factories/*.rb"].each do |file|
3
+ Dir["#{File.dirname(__FILE__)}/factories/*.rb"].sort.each do |file|
4
4
  require file
5
5
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
3
  module TestSupport
3
4
  # Helpers for integration specs
@@ -1,14 +1,15 @@
1
- RSpec.shared_context 'with invalid file' do
1
+ # frozen_string_literal: true
2
+ RSpec.shared_context "with invalid file" do
2
3
  let(:invalid_file) do
3
4
  fixture_file_upload(
4
- File.expand_path('../../../spec/fixtures/users.yml', __dir__),
5
- 'text/x-yaml'
5
+ File.expand_path("../../../spec/fixtures/users.yml", __dir__),
6
+ "text/x-yaml",
6
7
  )
7
8
  end
8
9
 
9
10
  before do
10
11
  allow(Alchemy::Attachment).to receive(:allowed_filetypes) do
11
- ['png']
12
+ ["png"]
12
13
  end
13
14
  end
14
15
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  RSpec.shared_examples_for "having a json uploader error message" do
2
3
  it "renders json response with error message" do
3
4
  subject
4
- expect(response.media_type).to eq('application/json')
5
+ expect(response.media_type).to eq("application/json")
5
6
  expect(response.status).to eq(422)
6
7
  json = JSON.parse(response.body)
7
- expect(json).to have_key('growl_message')
8
- expect(json).to have_key('files')
8
+ expect(json).to have_key("growl_message")
9
+ expect(json).to have_key("files")
9
10
  end
10
11
  end
@@ -6,23 +6,23 @@ module Alchemy
6
6
 
7
7
  @@plugins = %w(alchemy_link anchor autoresize charmap code directionality fullscreen hr link lists paste tabfocus table)
8
8
  @@init = {
9
- skin: 'alchemy',
10
- width: 'auto',
9
+ skin: "alchemy",
10
+ width: "auto",
11
11
  resize: true,
12
- autoresize_min_height: '105',
13
- autoresize_max_height: '480',
12
+ autoresize_min_height: "105",
13
+ autoresize_max_height: "480",
14
14
  menubar: false,
15
15
  statusbar: true,
16
16
  toolbar: [
17
- 'bold italic underline | strikethrough subscript superscript | numlist bullist indent outdent | removeformat | fullscreen',
18
- 'pastetext charmap hr | undo redo | alchemy_link unlink anchor | code'
17
+ "bold italic underline | strikethrough subscript superscript | numlist bullist indent outdent | removeformat | fullscreen",
18
+ "pastetext charmap hr | undo redo | alchemy_link unlink anchor | code",
19
19
  ],
20
20
  fix_list_elements: true,
21
21
  convert_urls: false,
22
- entity_encoding: 'raw',
22
+ entity_encoding: "raw",
23
23
  paste_as_text: true,
24
- element_format: 'html',
25
- branding: false
24
+ element_format: "html",
25
+ branding: false,
26
26
  }
27
27
 
28
28
  class << self
@@ -42,12 +42,14 @@ module Alchemy
42
42
 
43
43
  def content_definitions_from_elements(definitions)
44
44
  definitions.collect do |el|
45
- next if el['contents'].blank?
46
- contents = el['contents'].select do |c|
47
- c['settings'] && c['settings']['tinymce'].is_a?(Hash)
45
+ next if el["contents"].blank?
46
+
47
+ contents = el["contents"].select do |c|
48
+ c["settings"] && c["settings"]["tinymce"].is_a?(Hash)
48
49
  end
49
50
  next if contents.blank?
50
- contents.map { |c| c.merge('element' => el['name']) }
51
+
52
+ contents.map { |c| c.merge("element" => el["name"]) }
51
53
  end.flatten.compact
52
54
  end
53
55
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tasks/harden_gutentag_migrations"
4
+
5
+ module Alchemy
6
+ class Upgrader::FivePointZero < Upgrader
7
+ class << self
8
+ def install_gutentag_migrations
9
+ desc "Install Gutentag migrations"
10
+ Rake::Task["gutentag:install:migrations"].invoke
11
+ Alchemy::Upgrader::Tasks::HardenGutentagMigrations.new.patch_migrations
12
+ Rake::Task["db:migrate"].invoke
13
+ end
14
+
15
+ def remove_layout_roots
16
+ desc "Remove layout root pages"
17
+ layout_roots = Alchemy::Page.where(layoutpage: true).where("name LIKE 'Layoutroot for%'")
18
+ if layout_roots.size.positive?
19
+ log "Removing #{layout_roots.size} layout root pages."
20
+ layout_roots.delete_all
21
+ Alchemy::Page.where(layoutpage: true).update_all(parent_id: nil)
22
+ log "Done.", :success
23
+ else
24
+ log "No layout root pages found.", :skip
25
+ end
26
+ end
27
+
28
+ def remove_root_page
29
+ desc "Remove root page"
30
+ root_page = Alchemy::Page.find_by(parent_id: nil, name: "Root")
31
+ if root_page
32
+ Alchemy::Page.where(parent_id: root_page.id).update_all(parent_id: nil)
33
+ root_page.delete
34
+ log "Done.", :success
35
+ else
36
+ log "Root page not found.", :skip
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'alchemy/upgrader'
3
+ require "alchemy/upgrader"
4
4
 
5
5
  module Alchemy::Upgrader::Tasks
6
6
  class ElementViewsUpdater < Thor
@@ -11,14 +11,14 @@ module Alchemy::Upgrader::Tasks
11
11
  puts "-- Removing '_view' suffix from element views"
12
12
 
13
13
  Dir.glob("#{elements_view_folder}/*_view.*").each do |file|
14
- FileUtils.mv(file, file.to_s.sub(/_view/, ''))
14
+ FileUtils.mv(file, file.to_s.sub(/_view/, ""))
15
15
  end
16
16
  end
17
17
 
18
18
  def update_local_variable
19
19
  puts "-- Updating element views local variable to element name"
20
20
 
21
- Alchemy::Element.definitions.map { |e| e['name'] }.each do |name|
21
+ Alchemy::Element.definitions.map { |e| e["name"] }.each do |name|
22
22
  view = Dir.glob("#{elements_view_folder}/_#{name}.*").last
23
23
  gsub_file(view, /\b#{name}_view\b/, name)
24
24
  end
@@ -28,7 +28,7 @@ module Alchemy::Upgrader::Tasks
28
28
  private
29
29
 
30
30
  def elements_view_folder
31
- Rails.root.join('app', 'views', 'alchemy', 'elements')
31
+ Rails.root.join("app", "views", "alchemy", "elements")
32
32
  end
33
33
  end
34
34
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module Alchemy::Upgrader::Tasks
6
+ class HardenGutentagMigrations < Thor
7
+ include Thor::Actions
8
+
9
+ no_tasks do
10
+ def patch_migrations
11
+ sentinel = /def up/
12
+
13
+ migration_file = Dir.glob("db/migrate/*_gutentag_tables.gutentag.rb").first
14
+ if migration_file
15
+ inject_into_file migration_file,
16
+ "\n # inserted by Alchemy CMS upgrader\n return if table_exists?(:gutentag_taggings)\n",
17
+ { after: sentinel, verbose: true }
18
+ end
19
+
20
+ migration_file = Dir.glob("db/migrate/*_gutentag_cache_counter.gutentag.rb").first
21
+ if migration_file
22
+ inject_into_file migration_file,
23
+ "\n # inserted by Alchemy CMS upgrader\n return if column_exists?(:gutentag_tags, :taggings_count)\n",
24
+ { after: sentinel, verbose: true }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,26 +1,27 @@
1
- require 'alchemy/shell'
1
+ # frozen_string_literal: true
2
+ require "alchemy/shell"
2
3
 
3
4
  module Alchemy
4
5
  class Upgrader
5
6
  extend Alchemy::Shell
6
7
 
7
- Dir["#{File.dirname(__FILE__)}/upgrader/*.rb"].each { |f| require f }
8
+ Dir["#{File.dirname(__FILE__)}/upgrader/*.rb"].sort.each { |f| require f }
8
9
 
9
10
  class << self
10
11
  def copy_new_config_file
11
12
  desc "Copy configuration file."
12
- config_file = Rails.root.join('config/alchemy/config.yml')
13
- default_config = File.join(File.dirname(__FILE__), '../../config/alchemy/config.yml')
13
+ config_file = Rails.root.join("config/alchemy/config.yml")
14
+ default_config = File.join(File.dirname(__FILE__), "../../config/alchemy/config.yml")
14
15
  if !File.exist? config_file
15
16
  log "No configuration file found. Creating it."
16
- FileUtils.cp default_config, Rails.root.join('config/alchemy/config.yml')
17
+ FileUtils.cp default_config, Rails.root.join("config/alchemy/config.yml")
17
18
  elsif FileUtils.identical? default_config, config_file
18
19
  log "Configuration file already present.", :skip
19
20
  else
20
21
  log "Custom configuration file found."
21
- FileUtils.cp default_config, Rails.root.join('config/alchemy/config.yml.defaults')
22
+ FileUtils.cp default_config, Rails.root.join("config/alchemy/config.yml.defaults")
22
23
  log "Copied new default configuration file."
23
- todo "Check the default configuration file (./config/alchemy/config.yml.defaults) for new configuration options and insert them into your config file.", 'Configuration has changed'
24
+ todo "Check the default configuration file (./config/alchemy/config.yml.defaults) for new configuration options and insert them into your config file.", "Configuration has changed"
24
25
  end
25
26
  end
26
27
  end
@@ -7,6 +7,6 @@
7
7
  if Alchemy.user_class < ActiveRecord::Base
8
8
  Alchemy.user_class.class_eval do
9
9
  model_stamper
10
- stampable stamper_class_name: Alchemy.user_class.name
10
+ stampable stamper_class_name: Alchemy.user_class_name
11
11
  end
12
12
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "4.6.7"
4
+ VERSION = "5.0.0.beta1"
5
5
 
6
6
  def self.version
7
7
  VERSION
data/lib/alchemy_cms.rb CHANGED
@@ -1,62 +1,63 @@
1
+ # frozen_string_literal: true
1
2
  # Instantiate the global Alchemy namespace
2
3
  module Alchemy
3
- Alchemy::YAML_WHITELIST_CLASSES = %w(Symbol Date Regexp)
4
+ YAML_WHITELIST_CLASSES = %w(Symbol Date Regexp)
4
5
  end
5
6
 
6
7
  # Require globally used external libraries
7
- require 'acts_as_list'
8
- require 'action_view/dependency_tracker'
9
- require 'active_model_serializers'
10
- require 'awesome_nested_set'
11
- require 'cancan'
12
- require 'dragonfly'
13
- require 'gutentag'
14
- require 'handlebars_assets'
15
- require 'jquery-rails'
16
- require 'jquery-ui-rails'
17
- require 'kaminari'
18
- require 'non-stupid-digest-assets'
19
- require 'ransack'
20
- require 'request_store'
21
- require 'responders'
22
- require 'sassc-rails'
23
- require 'simple_form'
24
- require 'select2-rails'
25
- require 'turbolinks'
26
- require 'userstamp'
8
+ require "acts_as_list"
9
+ require "action_view/dependency_tracker"
10
+ require "active_model_serializers"
11
+ require "awesome_nested_set"
12
+ require "cancan"
13
+ require "dragonfly"
14
+ require "gutentag"
15
+ require "handlebars_assets"
16
+ require "jquery-rails"
17
+ require "jquery-ui-rails"
18
+ require "kaminari"
19
+ require "non-stupid-digest-assets"
20
+ require "ransack"
21
+ require "request_store"
22
+ require "responders"
23
+ require "sassc-rails"
24
+ require "simple_form"
25
+ require "select2-rails"
26
+ require "turbolinks"
27
+ require "userstamp"
28
+ require "webpacker"
27
29
 
28
30
  # Require globally used Alchemy mixins
29
- require_relative 'alchemy/ability_helper'
30
- require_relative 'alchemy/admin/locale'
31
- require_relative 'alchemy/auth_accessors'
32
- require_relative 'alchemy/cache_digests/template_tracker'
33
- require_relative 'alchemy/config'
34
- require_relative 'alchemy/configuration_methods'
35
- require_relative 'alchemy/controller_actions'
36
- require_relative 'alchemy/deprecation'
37
- require_relative 'alchemy/elements_finder'
38
- require_relative 'alchemy/error_tracking'
39
- require_relative 'alchemy/errors'
40
- require_relative 'alchemy/essence'
41
- require_relative 'alchemy/filetypes'
42
- require_relative 'alchemy/forms/builder'
43
- require_relative 'alchemy/hints'
44
- require_relative 'alchemy/i18n'
45
- require_relative 'alchemy/logger'
46
- require_relative 'alchemy/modules'
47
- require_relative 'alchemy/name_conversions'
48
- require_relative 'alchemy/on_page_layout'
49
- require_relative 'alchemy/on_page_layout/callbacks_runner'
50
- require_relative 'alchemy/page_layout'
51
- require_relative 'alchemy/paths'
52
- require_relative 'alchemy/permissions'
53
- require_relative 'alchemy/ssl_protection'
54
- require_relative 'alchemy/resource'
55
- require_relative 'alchemy/tinymce'
56
- require_relative 'alchemy/taggable'
31
+ require_relative "alchemy/ability_helper"
32
+ require_relative "alchemy/admin/locale"
33
+ require_relative "alchemy/admin/preview_url"
34
+ require_relative "alchemy/auth_accessors"
35
+ require_relative "alchemy/cache_digests/template_tracker"
36
+ require_relative "alchemy/config"
37
+ require_relative "alchemy/configuration_methods"
38
+ require_relative "alchemy/controller_actions"
39
+ require_relative "alchemy/deprecation"
40
+ require_relative "alchemy/elements_finder"
41
+ require_relative "alchemy/errors"
42
+ require_relative "alchemy/essence"
43
+ require_relative "alchemy/filetypes"
44
+ require_relative "alchemy/forms/builder"
45
+ require_relative "alchemy/hints"
46
+ require_relative "alchemy/i18n"
47
+ require_relative "alchemy/logger"
48
+ require_relative "alchemy/modules"
49
+ require_relative "alchemy/name_conversions"
50
+ require_relative "alchemy/on_page_layout"
51
+ require_relative "alchemy/on_page_layout/callbacks_runner"
52
+ require_relative "alchemy/page_layout"
53
+ require_relative "alchemy/paths"
54
+ require_relative "alchemy/permissions"
55
+ require_relative "alchemy/resource"
56
+ require_relative "alchemy/tinymce"
57
+ require_relative "alchemy/taggable"
57
58
 
58
59
  # Require hacks
59
- require_relative 'kaminari/scoped_pagination_url_helper'
60
+ require_relative "kaminari/scoped_pagination_url_helper"
60
61
 
61
62
  # Finally require Alchemy itself
62
- require_relative 'alchemy/engine'
63
+ require_relative "alchemy/engine"
@@ -1,14 +1,15 @@
1
- require 'rails'
1
+ # frozen_string_literal: true
2
+ require "rails"
2
3
 
3
4
  module Alchemy
4
5
  module Generators
5
6
  class Base < ::Rails::Generators::Base
6
- class_option :template_engine, type: :string, aliases: '-e', desc: 'Template engine for the views. Available options are "erb", "haml", and "slim".'
7
+ class_option :template_engine, type: :string, aliases: "-e", desc: 'Template engine for the views. Available options are "erb", "haml", and "slim".'
7
8
 
8
9
  private
9
10
 
10
11
  def conditional_template(source, destination)
11
- files = Dir.glob(destination.gsub(/\.([a-z]+)$/, '*'))
12
+ files = Dir.glob(destination.gsub(/\.([a-z]+)$/, "*"))
12
13
  if files.any?
13
14
  ext = File.extname(files.first)[1..-1]
14
15
 
@@ -28,7 +29,7 @@ module Alchemy
28
29
  # Rails is clever enough to default this to whatever template
29
30
  # engine is configured through its generator configuration,
30
31
  # but we'll default it to erb anyway, just in case.
31
- options[:template_engine] || 'erb'
32
+ options[:template_engine] || "erb"
32
33
  end
33
34
 
34
35
  def load_alchemy_yaml(name)
@@ -1,24 +1,20 @@
1
- require_relative '../base'
1
+ # frozen_string_literal: true
2
+ require_relative "../base"
2
3
 
3
4
  module Alchemy
4
5
  module Generators
5
6
  class ElementsGenerator < Base
6
7
  desc "This generator generates your elements view partials."
7
- source_root File.expand_path('templates', __dir__)
8
+ source_root File.expand_path("templates", __dir__)
8
9
 
9
10
  def create_partials
10
- @elements = load_alchemy_yaml('elements.yml')
11
+ @elements = load_alchemy_yaml("elements.yml")
11
12
  return unless @elements
12
13
 
13
14
  @elements.each do |element|
14
15
  @element = element
15
16
  @contents = element["contents"] || []
16
- if element["name"] =~ /\A[a-z0-9_-]+\z/
17
- @element_name = element["name"].underscore
18
- else
19
- raise "Element name '#{element['name']}' has wrong format. Only lowercase and non whitespace characters allowed."
20
- end
21
-
17
+ @element_name = element_name(element)
22
18
  conditional_template "view.html.#{template_engine}", "#{elements_dir}/_#{@element_name}.html.#{template_engine}"
23
19
  end
24
20
  end
@@ -28,6 +24,14 @@ module Alchemy
28
24
  def elements_dir
29
25
  @_elements_dir ||= "app/views/alchemy/elements"
30
26
  end
27
+
28
+ def element_name(element)
29
+ if element["name"] =~ Alchemy::Element::NAME_REGEXP
30
+ element["name"].underscore
31
+ else
32
+ raise "Element name '#{element["name"]}' has wrong format. Only lowercase and non whitespace characters allowed."
33
+ end
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -1,15 +1,16 @@
1
- require 'rails'
1
+ # frozen_string_literal: true
2
+ require "rails"
2
3
 
3
4
  module Alchemy
4
5
  module Generators
5
6
  class EssenceGenerator < ::Rails::Generators::Base
6
7
  desc "This generator generates an Alchemy essence for you."
7
8
  argument :essence_name, banner: "YourEssenceName"
8
- source_root File.expand_path('templates', __dir__)
9
+ source_root File.expand_path("templates", __dir__)
9
10
 
10
11
  def init
11
12
  @essence_name = essence_name.underscore
12
- @essence_view_path = 'app/views/alchemy/essences'
13
+ @essence_view_path = "app/views/alchemy/essences"
13
14
  end
14
15
 
15
16
  def create_model
@@ -19,20 +20,21 @@ module Alchemy
19
20
  def act_as_essence
20
21
  essence_class_file = "app/models/#{@essence_name}.rb"
21
22
  essence_class = @essence_name.classify
22
- inject_into_class essence_class_file, essence_class, <<-CLASSMETHOD
23
- acts_as_essence(
24
- # Your options:
25
- #
26
- # ingredient_column: [String or Symbol] - Specifies the column name you use for storing the content in the database. (Default :body)
27
- # validate_column: [String or Symbol] - Which column should be validated. (Default: ingredient_column)
28
- # preview_text_column: [String or Symbol] - Specifies the column for the preview_text method. (Default: ingredient_column)
29
- # preview_text_method: [String or Symbol] - A method called on ingredient to get the preview text. (Default: ingredient_column)
30
- )
31
- CLASSMETHOD
23
+ inject_into_class essence_class_file, essence_class, <<~CLASSMETHOD
24
+ acts_as_essence(
25
+ # Your options:
26
+ #
27
+ # ingredient_column: [String or Symbol] - Specifies the column name you use for storing the content in the database. (Default :body)
28
+ # validate_column: [String or Symbol] - Which column should be validated. (Default: ingredient_column)
29
+ # preview_text_column: [String or Symbol] - Specifies the column for the preview_text method. (Default: ingredient_column)
30
+ # preview_text_method: [String or Symbol] - A method called on ingredient to get the preview text. (Default: ingredient_column)
31
+ )
32
+ CLASSMETHOD
32
33
  end
33
34
 
34
35
  def copy_templates
35
36
  essence_name = @essence_name.classify.demodulize.underscore
37
+ @essence_editor_local = "#{essence_name}_editor"
36
38
  template "view.html.erb", "#{@essence_view_path}/_#{essence_name}_view.html.erb"
37
39
  template "editor.html.erb", "#{@essence_view_path}/_#{essence_name}_editor.html.erb"
38
40
  end
@@ -0,0 +1,17 @@
1
+ <%%#
2
+ Available locals:
3
+ * <%= @essence_editor_local %> - A Alchemy::ContentEditor instance
4
+
5
+ Please consult Alchemy::Content.rb docs for further methods on the content object
6
+ %>
7
+ <%%= content_tag :div,
8
+ id: <%= @essence_editor_local %>.dom_id,
9
+ class: <%= @essence_editor_local %>.css_classes,
10
+ data: <%= @essence_editor_local %>.data_attributes do %>
11
+ <%%= content_label(<%= @essence_editor_local %>) %>
12
+ <%%= text_field_tag(
13
+ <%= @essence_editor_local %>.form_field_name,
14
+ <%= @essence_editor_local %>.ingredient,
15
+ id: <%= @essence_editor_local %>.form_field_id
16
+ ) %>
17
+ <%% end %>