alchemy_cms 4.4.4 → 5.0.0.beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +56 -18
  3. data/.github/workflows/stale.yml +1 -1
  4. data/.gitignore +20 -2
  5. data/.hound.yml +2 -1
  6. data/.prettierrc +6 -0
  7. data/.rubocop.yml +33 -20
  8. data/CHANGELOG.md +121 -0
  9. data/Gemfile +24 -22
  10. data/README.md +31 -19
  11. data/Rakefile +10 -8
  12. data/alchemy_cms.gemspec +7 -5
  13. data/app/assets/javascripts/alchemy/admin.js +1 -2
  14. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +2 -1
  15. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -2
  16. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +5 -5
  17. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +17 -17
  18. data/app/assets/javascripts/alchemy/node_select.js +39 -0
  19. data/app/assets/javascripts/alchemy/templates/index.js +2 -0
  20. data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
  21. data/app/assets/javascripts/alchemy/templates/node_folder.hbs +3 -0
  22. data/app/assets/javascripts/alchemy/templates/page.hbs +1 -1
  23. data/app/assets/stylesheets/alchemy/_mixins.scss +2 -3
  24. data/app/assets/stylesheets/alchemy/_variables.scss +2 -2
  25. data/app/assets/stylesheets/alchemy/admin.scss +3 -2
  26. data/app/assets/stylesheets/alchemy/base.scss +0 -1
  27. data/app/assets/stylesheets/alchemy/elements.scss +1 -1
  28. data/app/assets/stylesheets/alchemy/forms.scss +5 -0
  29. data/app/assets/stylesheets/alchemy/lists.scss +0 -8
  30. data/app/assets/stylesheets/alchemy/node-select.scss +43 -0
  31. data/app/assets/stylesheets/alchemy/nodes.scss +6 -1
  32. data/app/assets/stylesheets/alchemy/sitemap.scss +63 -21
  33. data/app/assets/stylesheets/alchemy/tables.scss +1 -24
  34. data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
  35. data/app/controllers/alchemy/admin/base_controller.rb +13 -33
  36. data/app/controllers/alchemy/admin/clipboard_controller.rb +5 -4
  37. data/app/controllers/alchemy/admin/contents_controller.rb +1 -2
  38. data/app/controllers/alchemy/admin/dashboard_controller.rb +10 -9
  39. data/app/controllers/alchemy/admin/elements_controller.rb +20 -20
  40. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +12 -14
  41. data/app/controllers/alchemy/admin/languages_controller.rb +35 -2
  42. data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -2
  43. data/app/controllers/alchemy/admin/nodes_controller.rb +5 -14
  44. data/app/controllers/alchemy/admin/pages_controller.rb +50 -63
  45. data/app/controllers/alchemy/admin/pictures_controller.rb +16 -16
  46. data/app/controllers/alchemy/admin/resources_controller.rb +21 -13
  47. data/app/controllers/alchemy/admin/sites_controller.rb +18 -0
  48. data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
  49. data/app/controllers/alchemy/admin/tags_controller.rb +5 -3
  50. data/app/controllers/alchemy/admin/trash_controller.rb +6 -6
  51. data/app/controllers/alchemy/api/base_controller.rb +2 -2
  52. data/app/controllers/alchemy/api/contents_controller.rb +4 -4
  53. data/app/controllers/alchemy/api/elements_controller.rb +8 -8
  54. data/app/controllers/alchemy/api/nodes_controller.rb +65 -0
  55. data/app/controllers/alchemy/api/pages_controller.rb +15 -22
  56. data/app/controllers/alchemy/attachments_controller.rb +5 -5
  57. data/app/controllers/alchemy/base_controller.rb +10 -9
  58. data/app/controllers/alchemy/messages_controller.rb +16 -23
  59. data/app/controllers/alchemy/pages_controller.rb +13 -11
  60. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +3 -2
  61. data/app/controllers/concerns/alchemy/admin/current_language.rb +23 -0
  62. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -5
  63. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +4 -4
  64. data/app/controllers/concerns/alchemy/page_redirects.rb +2 -9
  65. data/app/controllers/concerns/alchemy/site_redirects.rb +2 -2
  66. data/app/decorators/alchemy/content_editor.rb +55 -0
  67. data/app/decorators/alchemy/element_editor.rb +39 -0
  68. data/app/helpers/alchemy/admin/attachments_helper.rb +6 -6
  69. data/app/helpers/alchemy/admin/base_helper.rb +36 -35
  70. data/app/helpers/alchemy/admin/contents_helper.rb +3 -3
  71. data/app/helpers/alchemy/admin/elements_helper.rb +3 -88
  72. data/app/helpers/alchemy/admin/essences_helper.rb +8 -117
  73. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  74. data/app/helpers/alchemy/admin/navigation_helper.rb +24 -23
  75. data/app/helpers/alchemy/admin/pages_helper.rb +12 -12
  76. data/app/helpers/alchemy/admin/pictures_helper.rb +4 -6
  77. data/app/helpers/alchemy/admin/tags_helper.rb +8 -7
  78. data/app/helpers/alchemy/base_helper.rb +13 -8
  79. data/app/helpers/alchemy/elements_block_helper.rb +2 -31
  80. data/app/helpers/alchemy/elements_helper.rb +12 -58
  81. data/app/helpers/alchemy/pages_helper.rb +24 -174
  82. data/app/helpers/alchemy/url_helper.rb +2 -1
  83. data/app/mailers/alchemy/base_mailer.rb +1 -1
  84. data/app/mailers/alchemy/messages_mailer.rb +1 -1
  85. data/app/models/alchemy/attachment.rb +20 -18
  86. data/app/models/alchemy/base_record.rb +2 -5
  87. data/app/models/alchemy/content.rb +33 -52
  88. data/app/models/alchemy/content/factory.rb +24 -31
  89. data/app/models/alchemy/element.rb +45 -53
  90. data/app/models/alchemy/element/definitions.rb +4 -4
  91. data/app/models/alchemy/element/element_contents.rb +9 -6
  92. data/app/models/alchemy/element/element_essences.rb +4 -3
  93. data/app/models/alchemy/element/presenters.rb +3 -2
  94. data/app/models/alchemy/element_to_page.rb +1 -1
  95. data/app/models/alchemy/essence_boolean.rb +1 -3
  96. data/app/models/alchemy/essence_date.rb +2 -3
  97. data/app/models/alchemy/essence_file.rb +4 -4
  98. data/app/models/alchemy/essence_html.rb +1 -3
  99. data/app/models/alchemy/essence_link.rb +1 -3
  100. data/app/models/alchemy/essence_node.rb +18 -0
  101. data/app/models/alchemy/essence_page.rb +3 -16
  102. data/app/models/alchemy/essence_picture.rb +17 -16
  103. data/app/models/alchemy/essence_picture_view.rb +7 -6
  104. data/app/models/alchemy/essence_richtext.rb +1 -3
  105. data/app/models/alchemy/essence_select.rb +1 -3
  106. data/app/models/alchemy/essence_text.rb +0 -2
  107. data/app/models/alchemy/folded_page.rb +1 -0
  108. data/app/models/alchemy/language.rb +21 -35
  109. data/app/models/alchemy/language/code.rb +4 -4
  110. data/app/models/alchemy/legacy_page_url.rb +1 -1
  111. data/app/models/alchemy/message.rb +3 -3
  112. data/app/models/alchemy/node.rb +55 -9
  113. data/app/models/alchemy/page.rb +53 -123
  114. data/app/models/alchemy/page/fixed_attributes.rb +3 -2
  115. data/app/models/alchemy/page/page_elements.rb +35 -44
  116. data/app/models/alchemy/page/page_naming.rb +20 -70
  117. data/app/models/alchemy/page/page_natures.rb +7 -34
  118. data/app/models/alchemy/page/page_scopes.rb +23 -29
  119. data/app/models/alchemy/page/url_path.rb +64 -0
  120. data/app/models/alchemy/picture.rb +40 -30
  121. data/app/models/alchemy/picture/preprocessor.rb +26 -0
  122. data/app/models/alchemy/picture/transformations.rb +9 -7
  123. data/app/models/alchemy/picture/url.rb +5 -5
  124. data/app/models/alchemy/site.rb +6 -36
  125. data/app/models/alchemy/site/layout.rb +2 -2
  126. data/app/models/concerns/alchemy/touch_elements.rb +24 -0
  127. data/app/serializers/alchemy/content_serializer.rb +0 -3
  128. data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
  129. data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
  130. data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
  131. data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
  132. data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
  133. data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
  134. data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
  135. data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
  136. data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
  137. data/app/serializers/alchemy/node_serializer.rb +14 -0
  138. data/app/serializers/alchemy/page_serializer.rb +2 -1
  139. data/app/serializers/alchemy/page_tree_serializer.rb +11 -14
  140. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
  141. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
  142. data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
  143. data/app/views/alchemy/admin/contents/create.js.erb +1 -3
  144. data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
  145. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  146. data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
  147. data/app/views/alchemy/admin/elements/index.html.erb +3 -3
  148. data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
  149. data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
  150. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
  151. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
  152. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
  153. data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
  154. data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
  155. data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
  156. data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
  157. data/app/views/alchemy/admin/languages/index.html.erb +23 -4
  158. data/app/views/alchemy/admin/languages/new.html.erb +1 -0
  159. data/app/views/alchemy/admin/layoutpages/index.html.erb +6 -2
  160. data/app/views/alchemy/admin/nodes/_form.html.erb +23 -15
  161. data/app/views/alchemy/admin/nodes/_node.html.erb +5 -19
  162. data/app/views/alchemy/admin/nodes/index.html.erb +3 -18
  163. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
  164. data/app/views/alchemy/admin/pages/_form.html.erb +1 -2
  165. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
  166. data/app/views/alchemy/admin/pages/_page.html.erb +14 -25
  167. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
  168. data/app/views/alchemy/admin/pages/_sitemap.html.erb +6 -0
  169. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  170. data/app/views/alchemy/admin/pages/info.html.erb +0 -9
  171. data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
  172. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
  173. data/app/views/alchemy/admin/partials/_routes.html.erb +8 -0
  174. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
  175. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  176. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
  177. data/app/views/alchemy/admin/pictures/index.html.erb +18 -3
  178. data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
  179. data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
  180. data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
  181. data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
  182. data/app/views/alchemy/admin/sites/index.html.erb +21 -9
  183. data/app/views/alchemy/admin/sites/new.html.erb +1 -0
  184. data/app/views/alchemy/admin/tags/index.html.erb +2 -2
  185. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
  186. data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
  187. data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
  188. data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
  189. data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
  190. data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
  191. data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
  192. data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
  193. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
  194. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
  195. data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
  196. data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
  197. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
  198. data/app/views/alchemy/pages/show.rss.builder +3 -2
  199. data/app/views/layouts/alchemy/admin.html.erb +1 -0
  200. data/babel.config.js +12 -0
  201. data/bin/rails +5 -4
  202. data/config/alchemy/config.yml +23 -22
  203. data/config/brakeman.ignore +1 -1
  204. data/config/initializers/assets.rb +2 -1
  205. data/config/initializers/dragonfly.rb +2 -1
  206. data/config/initializers/mime_types.rb +1 -0
  207. data/config/initializers/mini_profiler.rb +3 -2
  208. data/config/initializers/simple_form.rb +6 -6
  209. data/config/locales/alchemy.en.yml +37 -14
  210. data/config/routes.rb +32 -28
  211. data/config/spring.rb +3 -2
  212. data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
  213. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
  214. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
  215. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
  216. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
  217. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
  218. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
  219. data/lib/alchemy/admin/locale.rb +3 -1
  220. data/lib/alchemy/admin/preview_url.rb +85 -0
  221. data/lib/alchemy/auth_accessors.rb +8 -7
  222. data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
  223. data/lib/alchemy/config.rb +26 -2
  224. data/lib/alchemy/configuration_methods.rb +3 -1
  225. data/lib/alchemy/controller_actions.rb +6 -5
  226. data/lib/alchemy/deprecation.rb +2 -1
  227. data/lib/alchemy/elements_finder.rb +5 -5
  228. data/lib/alchemy/engine.rb +23 -8
  229. data/lib/alchemy/errors.rb +0 -7
  230. data/lib/alchemy/essence.rb +17 -16
  231. data/lib/alchemy/filetypes.rb +5 -5
  232. data/lib/alchemy/forms/builder.rb +4 -4
  233. data/lib/alchemy/hints.rb +1 -1
  234. data/lib/alchemy/i18n.rb +2 -1
  235. data/lib/alchemy/modules.rb +12 -12
  236. data/lib/alchemy/name_conversions.rb +5 -5
  237. data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
  238. data/lib/alchemy/page_layout.rb +15 -12
  239. data/lib/alchemy/paths.rb +1 -1
  240. data/lib/alchemy/permissions.rb +7 -6
  241. data/lib/alchemy/resource.rb +23 -13
  242. data/lib/alchemy/resources_helper.rb +12 -18
  243. data/lib/alchemy/routing_constraints.rb +1 -1
  244. data/lib/alchemy/seeder.rb +42 -14
  245. data/lib/alchemy/shell.rb +13 -10
  246. data/lib/alchemy/taggable.rb +1 -0
  247. data/lib/alchemy/tasks/tidy.rb +4 -3
  248. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  249. data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
  250. data/lib/alchemy/test_support/factories.rb +1 -1
  251. data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
  252. data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
  253. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
  254. data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
  255. data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
  256. data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
  257. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
  258. data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
  259. data/lib/alchemy/test_support/factories/language_factory.rb +21 -14
  260. data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
  261. data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
  262. data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
  263. data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
  264. data/lib/alchemy/test_support/integration_helpers.rb +1 -0
  265. data/lib/alchemy/test_support/shared_contexts.rb +5 -4
  266. data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
  267. data/lib/alchemy/tinymce.rb +15 -13
  268. data/lib/alchemy/upgrader.rb +8 -7
  269. data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
  270. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
  271. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
  272. data/lib/alchemy/version.rb +1 -1
  273. data/lib/alchemy_cms.rb +52 -50
  274. data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
  275. data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
  276. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
  277. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
  278. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
  279. data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
  280. data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
  281. data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
  282. data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
  283. data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
  284. data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
  285. data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
  286. data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
  287. data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
  288. data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
  289. data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
  290. data/lib/generators/alchemy/install/install_generator.rb +110 -0
  291. data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
  292. data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
  293. data/lib/generators/alchemy/install/templates/menus.yml.tt +8 -0
  294. data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
  295. data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +5 -5
  296. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
  297. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
  298. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
  299. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
  300. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +2 -2
  301. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +2 -2
  302. data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
  303. data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
  304. data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
  305. data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
  306. data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
  307. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
  308. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
  309. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
  310. data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
  311. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
  312. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
  313. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
  314. data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
  315. data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
  316. data/lib/tasks/alchemy/db.rake +3 -19
  317. data/lib/tasks/alchemy/install.rake +3 -2
  318. data/lib/tasks/alchemy/tidy.rake +9 -8
  319. data/lib/tasks/alchemy/upgrade.rake +28 -105
  320. data/package.json +45 -0
  321. data/package/admin.js +14 -0
  322. data/package/src/__tests__/i18n.spec.js +70 -0
  323. data/package/src/i18n.js +48 -0
  324. data/package/src/node_tree.js +72 -0
  325. data/package/src/translations.js +32 -0
  326. data/package/src/utils/__tests__/ajax.spec.js +124 -0
  327. data/package/src/utils/__tests__/events.spec.js +38 -0
  328. data/package/src/utils/ajax.js +48 -0
  329. data/package/src/utils/events.js +16 -0
  330. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  331. data/vendor/assets/fonts/fa-regular-400.svg +798 -358
  332. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  333. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  334. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  335. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  336. data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
  337. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  338. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  339. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  340. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
  341. data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
  342. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
  343. data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
  344. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
  345. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
  346. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
  347. data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
  348. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
  349. data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
  350. data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
  351. metadata +131 -83
  352. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
  353. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
  354. data/app/helpers/alchemy/essences_helper.rb +0 -119
  355. data/app/models/concerns/alchemy/content_touching.rb +0 -23
  356. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
  357. data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
  358. data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -33
  359. data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
  360. data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
  361. data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
  362. data/app/views/alchemy/navigation/_link.html.erb +0 -19
  363. data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
  364. data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
  365. data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
  366. data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
  367. data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
  368. data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
  369. data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
  370. data/lib/alchemy/ssl_protection.rb +0 -32
  371. data/lib/alchemy/tasks/helpers.rb +0 -81
  372. data/lib/alchemy/test_support/controller_requests.rb +0 -93
  373. data/lib/alchemy/upgrader/four_point_four.rb +0 -52
  374. data/lib/alchemy/upgrader/four_point_one.rb +0 -42
  375. data/lib/alchemy/upgrader/four_point_two.rb +0 -85
  376. data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -43
  377. data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -148
  378. data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -28
  379. data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
  380. data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
  381. data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
  382. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
  383. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
  384. data/lib/tasks/alchemy/convert.rake +0 -95
  385. data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
  386. data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -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, 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,7 +22,7 @@ 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) }
@@ -30,7 +30,7 @@ module Alchemy
30
30
 
31
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
@@ -28,29 +28,25 @@ module Alchemy
28
28
  belongs_to :element, touch: true, inverse_of: :contents
29
29
  has_one :page, through: :element
30
30
 
31
- stampable stamper_class_name: Alchemy.user_class_name
32
-
33
- acts_as_list scope: [:element_id]
34
-
35
31
  # Essence scopes
36
- scope :essence_booleans, -> { where(essence_type: "Alchemy::EssenceBoolean") }
37
- scope :essence_dates, -> { where(essence_type: "Alchemy::EssenceDate") }
38
- scope :essence_files, -> { where(essence_type: "Alchemy::EssenceFile") }
39
- scope :essence_htmls, -> { where(essence_type: "Alchemy::EssenceHtml") }
40
- scope :essence_links, -> { where(essence_type: "Alchemy::EssenceLink") }
41
- scope :essence_pictures, -> { where(essence_type: "Alchemy::EssencePicture") }
32
+ scope :essence_booleans, -> { where(essence_type: "Alchemy::EssenceBoolean") }
33
+ scope :essence_dates, -> { where(essence_type: "Alchemy::EssenceDate") }
34
+ scope :essence_files, -> { where(essence_type: "Alchemy::EssenceFile") }
35
+ scope :essence_htmls, -> { where(essence_type: "Alchemy::EssenceHtml") }
36
+ scope :essence_links, -> { where(essence_type: "Alchemy::EssenceLink") }
37
+ scope :essence_pictures, -> { where(essence_type: "Alchemy::EssencePicture") }
42
38
  scope :essence_richtexts, -> { where(essence_type: "Alchemy::EssenceRichtext") }
43
- scope :essence_selects, -> { where(essence_type: "Alchemy::EssenceSelect") }
44
- scope :essence_texts, -> { where(essence_type: "Alchemy::EssenceText") }
45
- scope :named, ->(name) { where(name: name) }
46
- scope :available, -> { published.not_trashed }
47
- scope :published, -> { joins(:element).merge(Element.published) }
48
- scope :not_trashed, -> { joins(:element).merge(Element.not_trashed) }
49
- scope :not_restricted, -> { joins(:element).merge(Element.not_restricted) }
50
-
51
- delegate :restricted?, to: :page, allow_nil: true
52
- delegate :trashed?, to: :element, allow_nil: true
53
- delegate :public?, to: :element, allow_nil: true
39
+ scope :essence_selects, -> { where(essence_type: "Alchemy::EssenceSelect") }
40
+ scope :essence_texts, -> { where(essence_type: "Alchemy::EssenceText") }
41
+ scope :named, ->(name) { where(name: name) }
42
+ scope :available, -> { published.not_trashed }
43
+ scope :published, -> { joins(:element).merge(Element.published) }
44
+ scope :not_trashed, -> { joins(:element).merge(Element.not_trashed) }
45
+ scope :not_restricted, -> { joins(:element).merge(Element.not_restricted) }
46
+
47
+ delegate :restricted?, to: :page, allow_nil: true
48
+ delegate :trashed?, to: :element, allow_nil: true
49
+ delegate :public?, to: :element, allow_nil: true
54
50
 
55
51
  class << self
56
52
  # Returns the translated label for a content name.
@@ -72,7 +68,7 @@ module Alchemy
72
68
  Alchemy.t(
73
69
  content_name,
74
70
  scope: "content_names.#{element_name}",
75
- default: Alchemy.t("content_names.#{content_name}", default: content_name.humanize)
71
+ default: Alchemy.t("content_names.#{content_name}", default: content_name.humanize),
76
72
  )
77
73
  end
78
74
  end
@@ -99,6 +95,7 @@ module Alchemy
99
95
  # Settings from the elements.yml definition
100
96
  def settings
101
97
  return {} if definition.blank?
98
+
102
99
  @settings ||= definition.fetch(:settings, {})
103
100
  end
104
101
 
@@ -114,12 +111,14 @@ module Alchemy
114
111
 
115
112
  def siblings
116
113
  return [] if !element
114
+
117
115
  element.contents
118
116
  end
119
117
 
120
118
  # Gets the ingredient from essence
121
119
  def ingredient
122
120
  return nil if essence.nil?
121
+
123
122
  essence.ingredient
124
123
  end
125
124
 
@@ -129,7 +128,7 @@ module Alchemy
129
128
  {
130
129
  name: name,
131
130
  value: serialized_ingredient,
132
- link: essence.try(:link)
131
+ link: essence.try(:link),
133
132
  }.delete_if { |_k, v| v.blank? }
134
133
  end
135
134
 
@@ -145,6 +144,7 @@ module Alchemy
145
144
  # Sets the ingredient from essence
146
145
  def ingredient=(value)
147
146
  raise EssenceMissingError if essence.nil?
147
+
148
148
  essence.ingredient = value
149
149
  end
150
150
 
@@ -156,11 +156,12 @@ module Alchemy
156
156
  #
157
157
  def update_essence(params = {})
158
158
  raise EssenceMissingError if essence.nil?
159
+
159
160
  if essence.update(params)
160
- return true
161
+ true
161
162
  else
162
163
  errors.add(:essence, :validation_failed)
163
- return false
164
+ false
164
165
  end
165
166
  end
166
167
 
@@ -169,34 +170,13 @@ module Alchemy
169
170
  end
170
171
 
171
172
  def has_validations?
172
- definition['validate'].present?
173
- end
174
-
175
- # Returns a string to be passed to Rails form field tags to ensure we have same params layout everywhere.
176
- #
177
- # === Example:
178
- #
179
- # <%= text_field_tag content.form_field_name, content.ingredient %>
180
- #
181
- # === Options:
182
- #
183
- # You can pass an Essence column_name. Default is 'ingredient'
184
- #
185
- # ==== Example:
186
- #
187
- # <%= text_field_tag content.form_field_name(:link), content.ingredient %>
188
- #
189
- def form_field_name(essence_column = 'ingredient')
190
- "contents[#{id}][#{essence_column}]"
191
- end
192
-
193
- def form_field_id(essence_column = 'ingredient')
194
- "contents_#{id}_#{essence_column}"
173
+ definition["validate"].present?
195
174
  end
196
175
 
197
176
  # Returns a string used as dom id on html elements.
198
177
  def dom_id
199
- return '' if essence.nil?
178
+ return "" if essence.nil?
179
+
200
180
  "#{essence_partial_name}_#{id}"
201
181
  end
202
182
 
@@ -211,7 +191,7 @@ module Alchemy
211
191
 
212
192
  # Returns true if this content should be taken for element preview.
213
193
  def preview_content?
214
- !!definition['as_element_title']
194
+ !!definition["as_element_title"]
215
195
  end
216
196
 
217
197
  # Proxy method that returns the preview text from essence.
@@ -221,7 +201,8 @@ module Alchemy
221
201
  end
222
202
 
223
203
  def essence_partial_name
224
- return '' if essence.nil?
204
+ return "" if essence.nil?
205
+
225
206
  essence.partial_name
226
207
  end
227
208
 
@@ -249,7 +230,7 @@ module Alchemy
249
230
  #
250
231
  # If the value is a symbol it gets passed through i18n
251
232
  # inside the +alchemy.default_content_texts+ scope
252
- def default_text(default)
233
+ def default_value(default = definition[:default])
253
234
  case default
254
235
  when Symbol
255
236
  Alchemy.t(default, scope: :default_content_texts)