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
@@ -25,18 +25,19 @@ module Alchemy
25
25
  #
26
26
  def language_links(options = {})
27
27
  options = {
28
- linkname: 'name',
28
+ linkname: "name",
29
29
  show_title: true,
30
- spacer: '',
31
- reverse: false
30
+ spacer: "",
31
+ reverse: false,
32
32
  }.merge(options)
33
- languages = Language.on_current_site.published.with_root_page.order("name #{options[:reverse] ? 'DESC' : 'ASC'}")
33
+ languages = Language.on_current_site.published.with_root_page.order("name #{options[:reverse] ? "DESC" : "ASC"}")
34
34
  return nil if languages.count < 2
35
+
35
36
  render(
36
37
  partial: "alchemy/language_links/language",
37
38
  collection: languages,
38
39
  spacer_template: "alchemy/language_links/spacer",
39
- locals: {languages: languages, options: options}
40
+ locals: { languages: languages, options: options },
40
41
  )
41
42
  end
42
43
 
@@ -50,7 +51,7 @@ module Alchemy
50
51
  render @page, page: @page
51
52
  rescue ActionView::MissingTemplate
52
53
  warning("PageLayout: '#{@page.page_layout}' not found. Rendering standard page_layout.")
53
- render 'alchemy/page_layouts/standard', page: @page
54
+ render "alchemy/page_layouts/standard", page: @page
54
55
  end
55
56
 
56
57
  # Renders a partial for current site
@@ -72,182 +73,37 @@ module Alchemy
72
73
  ""
73
74
  end
74
75
 
75
- # Renders the navigation.
76
- # @deprecated
77
- #
78
- # It produces a html <ul><li></li></ul> structure with all necessary classes so you can produce every navigation the web uses today.
79
- # I.E. dropdown-navigations, simple mainnavigations or even complex nested ones.
80
- #
81
- # === HTML output:
82
- #
83
- # <ul class="navigation level_1">
84
- # <li class="first home"><a href="/home" class="active" title="Homepage" lang="en" data-page-id="1">Homepage</a></li>
85
- # <li class="contact"><a href="/contact" title="Contact" lang="en" data-page-id="2">Contact</a></li>
86
- # <li class="last imprint"><a href="/imprint" title="Imprint" lang="en" data-page-id="3">Imprint</a></li>
87
- # </ul>
88
- #
89
- # As you can see: Everything you need.
90
- #
91
- # Not pleased with the way Alchemy produces the navigation structure?
92
- #
93
- # Then feel free to overwrite the partials (_renderer.html.erb and _link.html.erb) found in +views/navigation/+ or pass different partials via the options +:navigation_partial+ and +:navigation_link_partial+.
94
- #
95
- # === Passing HTML classes and ids to the renderer
96
- #
97
- # A second hash can be passed as html_options to the navigation renderer partial.
98
- #
99
- # ==== Example:
100
- #
101
- # <%= render_navigation({from_page: 'subnavi'}, {class: 'navigation', id: 'subnavigation'}) %>
102
- #
103
- #
104
- # @option options submenu [Boolean] (false)
105
- # Do you want a nested <ul> <li> structure for the deeper levels of your navigation, or not?
106
- # Used to display the subnavigation within the mainnaviagtion. I.e. for dropdown menues.
107
- #
108
- # @option options all_sub_menues [Boolean] (false)
109
- # Renders the whole page tree.
110
- #
111
- # @option options from_page [Alchemy::Page] (@root_page)
112
- # Do you want to render a navigation from a different page then the current page?
113
- # Then pass an Page instance or a Alchemy::PageLayout name as string.
114
- #
115
- # @option options spacer [String] (nil)
116
- # A spacer for the entries can be passed.
117
- # Simple string, or even a complex html structure.
118
- # I.e: "<span class='spacer'>|</spacer>".
119
- #
120
- # @option options navigation_partial [String] ("navigation/renderer")
121
- # Pass a different partial to be taken for the navigation rendering.
122
- # Alternatively you could override the +app/views/alchemy/navigation/renderer+ partial in your app.
123
- #
124
- # @option options navigation_link_partial [String] ("navigation/link")
125
- # Alchemy places an <a> html link in <li> tags.
126
- # The tag automatically has an active css class if necessary.
127
- # So styling is everything. But maybe you don't want this.
128
- # So feel free to make you own partial and pass the filename here.
129
- # Alternatively you could override the +app/views/alchemy/navigation/link+ partial in your app.
130
- #
131
- # @option options show_nonactive [Boolean] (false)
132
- # Commonly Alchemy only displays the submenu of the active page (if submenu: true).
133
- # If you want to display all child pages then pass true (together with submenu: true of course).
134
- # I.e. for css-driven drop down menues.
135
- #
136
- # @option options show_title [Boolean] (true)
137
- # For our beloved SEOs :)
138
- # Appends a title attribute to all links and places the +page.title+ content into it.
139
- #
140
- # @option options restricted_only [Boolean] (false)
141
- # Render only restricted pages. I.E for members only navigations.
142
- #
143
- # @option options reverse [Boolean] (false)
144
- # Reverse the output of the pages
145
- #
146
- # @option options reverse_children [Boolean] (false)
147
- # Like reverse option, but only reverse the children of the first level
148
- #
149
- # @option options deepness [Fixnum] (nil)
150
- # Show only pages up to this depth.
151
- #
152
- def render_navigation(options = {}, html_options = {})
153
- options = {
154
- submenu: false,
155
- all_sub_menues: false,
156
- from_page: @root_page || Language.current_root_page,
157
- spacer: nil,
158
- navigation_partial: 'alchemy/navigation/renderer',
159
- navigation_link_partial: 'alchemy/navigation/link',
160
- show_nonactive: false,
161
- restricted_only: false,
162
- show_title: true,
163
- reverse: false,
164
- reverse_children: false
165
- }.merge(options)
166
- page = page_or_find(options[:from_page])
167
- return nil if page.blank?
168
- pages = page.children.accessible_by(current_ability, :see)
169
- pages = pages.restricted if options.delete(:restricted_only)
170
- if depth = options[:deepness]
171
- pages = pages.where('depth <= ?', depth)
172
- end
173
- if options[:reverse]
174
- pages.reverse!
175
- end
176
- render options[:navigation_partial],
177
- options: options,
178
- pages: pages,
179
- html_options: html_options
180
- end
181
- deprecate render_navigation: 'Create a menu and use render_menu instead', deprecator: Alchemy::Deprecation
182
-
183
76
  # Renders a menu partial
184
77
  #
185
78
  # Menu partials are placed in the `app/views/alchemy/menus` folder
186
79
  # Use the `rails g alchemy:menus` generator to create the partials
187
80
  #
188
- # @param [String] - Name of the menu
81
+ # @param [String] - Type of the menu
189
82
  # @param [Hash] - A set of options available in your menu partials
190
- def render_menu(name, options = {})
191
- root_node = Alchemy::Node.roots.find_by(name: name, site: Alchemy::Site.current)
83
+ def render_menu(menu_type, options = {})
84
+ root_node = Alchemy::Node.roots.find_by(
85
+ menu_type: menu_type,
86
+ language: Alchemy::Language.current,
87
+ )
192
88
  if root_node.nil?
193
- warning("Menu with name #{name} not found!")
89
+ warning("Menu with type #{menu_type} not found!")
194
90
  return
195
91
  end
196
92
 
197
- options = {
198
- node_partial_name: "#{root_node.view_folder_name}/node"
199
- }.merge(options)
200
-
201
- render(root_node.to_partial_path, menu: root_node, node: root_node, options: options)
93
+ render("alchemy/menus/#{menu_type}/wrapper", menu: root_node, options: options)
202
94
  rescue ActionView::MissingTemplate => e
203
95
  warning <<~WARN
204
- Menu partial not found for #{name}.
96
+ Menu partial not found for #{menu_type}.
205
97
  #{e}
206
98
  WARN
207
99
  end
208
100
 
209
- # Renders navigation the children and all siblings of the given page (standard is the current page).
210
- #
211
- # Use this helper if you want to render the subnavigation independent from the mainnavigation. I.E. to place it in a different area on your website.
212
- #
213
- # This helper passes all its options to the the render_navigation helper.
214
- #
215
- # === Options:
216
- #
217
- # from_page: @page # The page to render the navigation from
218
- # submenu: true # Shows the nested children
219
- # level: 2 # Normally there is no need to change the level parameter, just in a few special cases
220
- #
221
- def render_subnavigation(options = {}, html_options = {})
222
- default_options = {
223
- from_page: @page,
224
- submenu: true,
225
- level: 2
226
- }
227
- options = default_options.merge(options)
228
- if !options[:from_page].nil?
229
- while options[:from_page].level > options[:level]
230
- options[:from_page] = options[:from_page].parent
231
- end
232
- render_navigation(options, html_options)
233
- else
234
- return nil
235
- end
236
- end
237
- deprecate :render_subnavigation, deprecator: Alchemy::Deprecation
238
-
239
101
  # Returns true if page is in the active branch
240
102
  def page_active?(page)
241
103
  @_page_ancestors ||= Page.ancestors_for(@page)
242
104
  @_page_ancestors.include?(page)
243
105
  end
244
106
 
245
- # Returns +'active'+ if the given external page is in the current url path or +nil+.
246
- def external_page_css_class(page)
247
- return nil if !page.definition['redirects_to_external']
248
- request.path.split('/').delete_if(&:blank?).first == page.urlname.gsub(/^\//, '') ? 'active' : nil
249
- end
250
-
251
107
  # Returns page links in a breadcrumb beginning from root to current page.
252
108
  #
253
109
  # === Options:
@@ -264,11 +120,11 @@ module Alchemy
264
120
  page: @page,
265
121
  restricted_only: false,
266
122
  reverse: false,
267
- link_active_page: false
123
+ link_active_page: false,
268
124
  }.merge(options)
269
125
 
270
- pages = Page.
271
- ancestors_for(options[:page]).
126
+ pages = options[:page].
127
+ self_and_ancestors.contentpages.
272
128
  accessible_by(current_ability, :see)
273
129
 
274
130
  if options.delete(:restricted_only)
@@ -276,7 +132,7 @@ module Alchemy
276
132
  end
277
133
 
278
134
  if options.delete(:reverse)
279
- pages = pages.reorder('lft DESC')
135
+ pages = pages.reorder("lft DESC")
280
136
  end
281
137
 
282
138
  if options[:without].present?
@@ -284,7 +140,7 @@ module Alchemy
284
140
  pages = pages.where.not(id: without.try(:collect, &:id) || without.id)
285
141
  end
286
142
 
287
- render 'alchemy/breadcrumb/wrapper', pages: pages, options: options
143
+ render "alchemy/breadcrumb/wrapper", pages: pages, options: options
288
144
  end
289
145
 
290
146
  # Returns current page title
@@ -296,10 +152,11 @@ module Alchemy
296
152
  #
297
153
  def page_title(options = {})
298
154
  return "" if @page.title.blank?
155
+
299
156
  options = {
300
157
  prefix: "",
301
158
  suffix: "",
302
- separator: ""
159
+ separator: "",
303
160
  }.update(options)
304
161
  title_parts = [options[:prefix]]
305
162
  if response.status == 200
@@ -320,14 +177,7 @@ module Alchemy
320
177
  end
321
178
 
322
179
  def meta_robots
323
- "#{@page.robot_index? ? '' : 'no'}index, #{@page.robot_follow? ? '' : 'no'}follow"
324
- end
325
-
326
- # @deprecated
327
- def render_cell(name, _options = {})
328
- render_elements(only: name, fixed: true)
180
+ "#{@page.robot_index? ? "" : "no"}index, #{@page.robot_follow? ? "" : "no"}follow"
329
181
  end
330
- deprecate render_cell: 'Use render_elements(only: <cell-name>, fixed: true) instead',
331
- deprecator: Alchemy::Deprecation
332
182
  end
333
183
  end
@@ -18,7 +18,8 @@ module Alchemy
18
18
 
19
19
  # Returns the correct params-hash for passing to show_page_path
20
20
  def show_page_path_params(page, optional_params = {})
21
- raise ArgumentError, 'Page is nil' if page.nil?
21
+ raise ArgumentError, "Page is nil" if page.nil?
22
+
22
23
  url_params = {urlname: page.urlname}.update(optional_params)
23
24
  prefix_locale? ? url_params.update(locale: page.language_code) : url_params
24
25
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Alchemy
4
4
  begin
5
- base_class = Object.const_get('::ApplicationMailer')
5
+ base_class = Object.const_get("::ApplicationMailer")
6
6
  rescue NameError
7
7
  base_class = ActionMailer::Base
8
8
  end
@@ -8,7 +8,7 @@ module Alchemy
8
8
  from: mail_from,
9
9
  to: mail_to,
10
10
  reply_to: message.try(:email),
11
- subject: subject
11
+ subject: subject,
12
12
  )
13
13
  end
14
14
  end
@@ -22,15 +22,15 @@ module Alchemy
22
22
  include Alchemy::Filetypes
23
23
  include Alchemy::NameConversions
24
24
  include Alchemy::Taggable
25
- include Alchemy::ContentTouching
25
+ include Alchemy::TouchElements
26
26
 
27
27
  dragonfly_accessor :file, app: :alchemy_attachments do
28
28
  after_assign { |f| write_attribute(:file_mime_type, f.mime_type) }
29
29
  end
30
30
 
31
- stampable stamper_class_name: Alchemy.user_class.name
31
+ stampable stamper_class_name: Alchemy.user_class_name
32
32
 
33
- has_many :essence_files, class_name: 'Alchemy::EssenceFile', foreign_key: 'attachment_id'
33
+ has_many :essence_files, class_name: "Alchemy::EssenceFile", foreign_key: "attachment_id"
34
34
  has_many :contents, through: :essence_files
35
35
  has_many :elements, through: :contents
36
36
  has_many :pages, through: :elements
@@ -42,24 +42,25 @@ module Alchemy
42
42
  end
43
43
 
44
44
  def allowed_filetypes
45
- Config.get(:uploader).fetch('allowed_filetypes', {}).fetch('alchemy/attachments', [])
45
+ Config.get(:uploader).fetch("allowed_filetypes", {}).fetch("alchemy/attachments", [])
46
46
  end
47
47
 
48
48
  def file_types_for_select
49
49
  file_types = Alchemy::Attachment.pluck(:file_mime_type).uniq.map do |type|
50
- [Alchemy.t(type, scope: 'mime_types'), type]
50
+ [Alchemy.t(type, scope: "mime_types"), type]
51
51
  end
52
52
  file_types.sort_by(&:first)
53
53
  end
54
54
  end
55
55
 
56
56
  validates_presence_of :file
57
- validates_size_of :file, maximum: Config.get(:uploader)['file_size_limit'].megabytes
58
- validates_property :ext, of: :file,
57
+ validates_size_of :file, maximum: Config.get(:uploader)["file_size_limit"].megabytes
58
+ validates_property :ext,
59
+ of: :file,
59
60
  in: allowed_filetypes,
60
61
  case_sensitive: false,
61
62
  message: Alchemy.t("not a valid file"),
62
- unless: -> { self.class.allowed_filetypes.include?('*') }
63
+ unless: -> { self.class.allowed_filetypes.include?("*") }
63
64
 
64
65
  before_save :set_name, if: :file_name_changed?
65
66
 
@@ -71,13 +72,13 @@ module Alchemy
71
72
  {
72
73
  "name" => read_attribute(:file_name),
73
74
  "size" => read_attribute(:file_size),
74
- 'error' => errors[:file].join
75
+ "error" => errors[:file].join,
75
76
  }
76
77
  end
77
78
 
78
79
  # An url save filename without format suffix
79
80
  def urlname
80
- CGI.escape(file_name.gsub(/\.#{extension}$/, '').tr('.', ' '))
81
+ CGI.escape(file_name.gsub(/\.#{extension}$/, "").tr(".", " "))
81
82
  end
82
83
 
83
84
  # Checks if the attachment is restricted, because it is attached on restricted pages only
@@ -89,6 +90,7 @@ module Alchemy
89
90
  def extension
90
91
  file_name.split(".").last
91
92
  end
93
+
92
94
  alias_method :suffix, :extension
93
95
 
94
96
  # Returns a css class name for kind of file
@@ -96,23 +98,23 @@ module Alchemy
96
98
  def icon_css_class
97
99
  case file_mime_type
98
100
  when "application/pdf"
99
- then "file-pdf"
101
+ "file-pdf"
100
102
  when "application/msword"
101
- then "file-word"
103
+ "file-word"
102
104
  when *TEXT_FILE_TYPES
103
- then "file-alt"
105
+ "file-alt"
104
106
  when *EXCEL_FILE_TYPES
105
- then "file-excel"
107
+ "file-excel"
106
108
  when *VCARD_FILE_TYPES
107
- then "address-card"
109
+ "address-card"
108
110
  when *ARCHIVE_FILE_TYPES
109
- then "file-archive"
111
+ "file-archive"
110
112
  when *AUDIO_FILE_TYPES
111
- then "file-audio"
113
+ "file-audio"
112
114
  when *IMAGE_FILE_TYPES
113
- then "file-image"
115
+ "file-image"
114
116
  when *VIDEO_FILE_TYPES
115
- then "file-video"
117
+ "file-video"
116
118
  else
117
119
  "file"
118
120
  end
@@ -1,13 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
3
  def self.table_name_prefix
3
- 'alchemy_'
4
+ "alchemy_"
4
5
  end
5
6
 
6
7
  class BaseRecord < ActiveRecord::Base
7
8
  self.abstract_class = true
8
-
9
- def active_record_5_1?
10
- ActiveRecord.gem_version >= Gem::Version.new('5.1.0')
11
- end
12
9
  end
13
10
  end
@@ -22,10 +22,13 @@ module Alchemy
22
22
  if definition.blank?
23
23
  raise ContentDefinitionError, "No definition found in elements.yml for #{attributes.inspect} and #{element.inspect}"
24
24
  end
25
- super(name: definition['name'], element_id: element.id)
25
+
26
+ super(
27
+ name: definition[:name],
28
+ essence_type: normalize_essence_type(definition[:type]),
29
+ element_id: element.id
30
+ ).tap(&:build_essence)
26
31
  end
27
- alias_method :build, :new
28
- deprecate build: :new, deprecator: Alchemy::Deprecation
29
32
 
30
33
  # Creates a new content from elements definition in the +elements.yml+ file.
31
34
  #
@@ -34,20 +37,11 @@ module Alchemy
34
37
  #
35
38
  # @return [Alchemy::Content]
36
39
  #
37
- def create(*args)
38
- attributes = args.last || {}
39
- if args.length > 1
40
- Alchemy::Deprecation.warn 'Passing an element as first argument to Alchemy::Content.create is deprecated! Pass an attribute hash with element inside instead.'
41
- element = args.first
42
- else
43
- element = attributes[:element]
44
- end
45
- new(attributes.merge(element: element)).tap do |content|
46
- content.create_essence!(attributes[:essence_type])
40
+ def create(attributes = {})
41
+ new(attributes).tap do |content|
42
+ content.essence.save && content.save
47
43
  end
48
44
  end
49
- alias_method :create_from_scratch, :create
50
- deprecate create_from_scratch: :create, deprecator: Alchemy::Deprecation
51
45
 
52
46
  # Creates a copy of source and also copies the associated essence.
53
47
  #
@@ -62,11 +56,11 @@ module Alchemy
62
56
  new_content = Content.new(
63
57
  source.attributes.
64
58
  except(*SKIPPED_ATTRIBUTES_ON_COPY).
65
- merge(differences.with_indifferent_access)
59
+ merge(differences.with_indifferent_access),
66
60
  )
67
61
  new_essence = source.essence.class.create!(
68
62
  source.essence.attributes.
69
- except(*SKIPPED_ATTRIBUTES_ON_COPY)
63
+ except(*SKIPPED_ATTRIBUTES_ON_COPY),
70
64
  )
71
65
  new_content.tap do |content|
72
66
  content.essence = new_essence
@@ -77,7 +71,7 @@ module Alchemy
77
71
  # Returns all content definitions from elements.yml
78
72
  #
79
73
  def definitions
80
- definitions = Element.definitions.flat_map { |e| e['contents'] }
74
+ definitions = Element.definitions.flat_map { |e| e["contents"] }
81
75
  definitions.compact!
82
76
  definitions
83
77
  end
@@ -119,12 +113,22 @@ module Alchemy
119
113
  element.content_definition_for(name) || {}
120
114
  end
121
115
 
116
+ # Build essence from definition.
117
+ #
118
+ # If an optional type is passed, this type of essence gets created.
119
+ #
120
+ def build_essence(type = essence_type)
121
+ self.essence = essence_class(type).new({
122
+ ingredient: default_value,
123
+ })
124
+ end
125
+
122
126
  # Creates essence from definition.
123
127
  #
124
128
  # If an optional type is passed, this type of essence gets created.
125
129
  #
126
130
  def create_essence!(type = nil)
127
- self.essence = essence_class(type).create!(prepared_attributes_for_essence)
131
+ build_essence(type).save!
128
132
  save!
129
133
  end
130
134
 
@@ -135,18 +139,7 @@ module Alchemy
135
139
  # If an optional type is passed, this type of essence gets constantized.
136
140
  #
137
141
  def essence_class(type = nil)
138
- Content.normalize_essence_type(type || definition['type']).constantize
139
- end
140
-
141
- # Prepares the attributes for creating the essence.
142
- #
143
- # 1. It sets a default text if given in +elements.yml+
144
- #
145
- def prepared_attributes_for_essence
146
- attributes = {
147
- ingredient: default_text(definition['default'])
148
- }
149
- attributes
142
+ Content.normalize_essence_type(type || definition["type"]).constantize
150
143
  end
151
144
  end
152
145
  end