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
@@ -14,10 +14,10 @@ module Alchemy
14
14
  def dependencies
15
15
  case @name.to_s
16
16
  when /^alchemy\/pages\/show/
17
- PageLayout.all.map { |p| "alchemy/page_layouts/_#{p['name']}" }
17
+ PageLayout.all.map { |p| "alchemy/page_layouts/_#{p["name"]}" }
18
18
  when /^alchemy\/page_layouts\/_(\w+)/
19
19
  page_layout = PageLayout.get($1)
20
- layout_elements = page_layout.fetch('elements', [])
20
+ layout_elements = page_layout.fetch("elements", [])
21
21
  layout_elements.map { |name| "alchemy/elements/_#{name}_view" } +
22
22
  layout_elements.map { |name| "alchemy/elements/_#{name}" }
23
23
  when /^alchemy\/elements\/_(\w+)_view/, /^alchemy\/elements\/_(\w+)/
@@ -32,9 +32,10 @@ module Alchemy
32
32
  private
33
33
 
34
34
  def essence_types(name)
35
- element = Element.definitions.detect { |e| e['name'] == name }
35
+ element = Element.definitions.detect { |e| e["name"] == name }
36
36
  return [] unless element
37
- element.fetch('contents', []).collect { |c| c['type'] }
37
+
38
+ element.fetch("contents", []).collect { |c| c["type"] }
38
39
  end
39
40
  end
40
41
  end
@@ -31,11 +31,7 @@ module Alchemy
31
31
  # a value of nil means there is no new default
32
32
  # any not nil value is the new default
33
33
  def deprecated_configs
34
- {
35
- url_nesting: true,
36
- require_ssl: nil,
37
- auto_logout_time: nil,
38
- }
34
+ {}
39
35
  end
40
36
 
41
37
  private
@@ -28,7 +28,9 @@ module Alchemy
28
28
  # matches the current I18n.locale then the prefix os omitted.
29
29
  # Also, if only one published language exists.
30
30
  #
31
- def prefix_locale?(locale = Language.current.code)
31
+ def prefix_locale?(locale = Language.current&.code)
32
+ return false unless locale
33
+
32
34
  multi_language? && locale != ::I18n.default_locale.to_s
33
35
  end
34
36
 
@@ -8,7 +8,7 @@ module Alchemy
8
8
  before_action :set_current_alchemy_site
9
9
  before_action :set_alchemy_language
10
10
 
11
- helper 'alchemy/pages'
11
+ helper "alchemy/pages"
12
12
 
13
13
  helper_method :current_alchemy_user,
14
14
  :alchemy_user_signed_in?,
@@ -36,6 +36,7 @@ module Alchemy
36
36
  def current_alchemy_user
37
37
  current_user_method = Alchemy.current_user_method
38
38
  raise NoCurrentUserFoundError if !respond_to?(current_user_method, true)
39
+
39
40
  send current_user_method
40
41
  end
41
42
 
@@ -66,8 +67,8 @@ module Alchemy
66
67
  else
67
68
  # find the best language and remember it for later
68
69
  @language = load_alchemy_language_from_params ||
69
- load_alchemy_language_from_session ||
70
- Language.default
70
+ load_alchemy_language_from_session ||
71
+ Language.default
71
72
  end
72
73
  store_current_alchemy_language(@language)
73
74
  end
@@ -81,7 +82,7 @@ module Alchemy
81
82
  # Load language from session if it's present on current site.
82
83
  # Otherwise return nil so we can load the default language from current site.
83
84
  def load_alchemy_language_from_session
84
- if session[:alchemy_language_id].present?
85
+ if session[:alchemy_language_id].present? && Site.current
85
86
  Site.current.languages.find_by(id: session[:alchemy_language_id])
86
87
  end
87
88
  end
@@ -96,7 +97,7 @@ module Alchemy
96
97
  # Also stores language in +Language.current+
97
98
  #
98
99
  def store_current_alchemy_language(language)
99
- if language && language.id
100
+ if language&.id
100
101
  session[:alchemy_language_id] = language.id
101
102
  Language.current = language
102
103
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
- Deprecation = ActiveSupport::Deprecation.new('5.0', 'Alchemy')
3
+ Deprecation = ActiveSupport::Deprecation.new("5.0", "Alchemy")
3
4
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'alchemy/logger'
3
+ require "alchemy/logger"
4
4
 
5
5
  module Alchemy
6
6
  # Loads elements from given page
@@ -86,7 +86,7 @@ module Alchemy
86
86
  Alchemy::Page.find_by(
87
87
  language: Alchemy::Language.current,
88
88
  page_layout: page_or_layout,
89
- restricted: false
89
+ restricted: false,
90
90
  )
91
91
  end
92
92
  end
@@ -104,10 +104,10 @@ module Alchemy
104
104
 
105
105
  def random_function
106
106
  case ActiveRecord::Base.connection_config[:adapter]
107
- when 'postgresql', 'sqlite3'
108
- then 'RANDOM()'
107
+ when "postgresql", "sqlite3"
108
+ "RANDOM()"
109
109
  else
110
- 'RAND()'
110
+ "RAND()"
111
111
  end
112
112
  end
113
113
  end
@@ -1,39 +1,47 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
3
  class Engine < Rails::Engine
3
4
  isolate_namespace Alchemy
4
- engine_name 'alchemy'
5
- config.mount_at = '/'
5
+ engine_name "alchemy"
6
+ config.mount_at = "/"
6
7
 
7
- initializer 'alchemy.lookup_context' do
8
- Alchemy::LOOKUP_CONTEXT = ActionView::LookupContext.new(Rails.root.join('app', 'views', 'alchemy'))
8
+ initializer "alchemy.lookup_context" do
9
+ Alchemy::LOOKUP_CONTEXT = ActionView::LookupContext.new(Rails.root.join("app", "views", "alchemy"))
9
10
  end
10
11
 
11
- initializer 'alchemy.dependency_tracker' do
12
+ initializer "alchemy.admin.preview_url" do
13
+ Alchemy::Admin::PREVIEW_URL = Alchemy::Admin::PreviewUrl.new(routes: Alchemy::Engine.routes)
14
+ end
15
+
16
+ initializer "alchemy.dependency_tracker" do
12
17
  [:erb, :slim, :haml].each do |handler|
13
18
  ActionView::DependencyTracker.register_tracker(handler, CacheDigests::TemplateTracker)
14
19
  end
15
20
  end
16
21
 
17
- initializer 'alchemy.non_digest_assets' do
22
+ initializer "alchemy.non_digest_assets" do
18
23
  NonStupidDigestAssets.whitelist += [/^tinymce\//]
19
24
  end
20
25
 
21
26
  # Gutentag downcases all tgas before save.
22
27
  # We support having tags with uppercase characters.
23
28
  # The Gutentag search is case insensitive.
24
- initializer 'alchemy.gutentag_normalizer' do
29
+ initializer "alchemy.gutentag_normalizer" do
25
30
  Gutentag.normaliser = ->(value) { value.to_s }
26
31
  end
27
32
 
28
- config.after_initialize do
29
- require_relative './userstamp'
33
+ # Custom Ransack sort arrows
34
+ initializer "alchemy.ransack" do
35
+ Ransack.configure do |config|
36
+ config.custom_arrows = {
37
+ up_arrow: '<i class="fa fas fa-xs fa-arrow-up"></i>',
38
+ down_arrow: '<i class="fa fas fa-xs fa-arrow-down"></i>',
39
+ }
40
+ end
30
41
  end
31
42
 
32
- initializer "alchemy.error_tracking" do
33
- if defined?(Airbrake)
34
- require_relative "error_tracking/airbrake_handler"
35
- Alchemy::ErrorTracking.notification_handler = Alchemy::ErrorTracking::AirbrakeHandler
36
- end
43
+ config.after_initialize do
44
+ require_relative "./userstamp"
37
45
  end
38
46
  end
39
47
  end
@@ -23,13 +23,6 @@ module Alchemy
23
23
  end
24
24
  end
25
25
 
26
- class DefaultLanguageNotDeletable < StandardError
27
- # Raised if one tries to delete the default language.
28
- def message
29
- "Default language is not deletable!"
30
- end
31
- end
32
-
33
26
  class ElementDefinitionError < StandardError
34
27
  # Raised if element definition can not be found.
35
28
  def initialize(attributes)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_record'
3
+ require "active_record"
4
4
 
5
5
  module Alchemy #:nodoc:
6
6
  # A bogus association that skips eager loading for essences not having an ingredient association
@@ -40,7 +40,7 @@ module Alchemy #:nodoc:
40
40
  register_as_essence_association!
41
41
 
42
42
  configuration = {
43
- ingredient_column: 'body'
43
+ ingredient_column: "body",
44
44
  }.update(options)
45
45
 
46
46
  @_classes_with_ingredient_association ||= []
@@ -48,7 +48,7 @@ module Alchemy #:nodoc:
48
48
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
49
49
  attr_writer :validation_errors
50
50
  include Alchemy::Essence::InstanceMethods
51
- stampable stamper_class_name: Alchemy.user_class.name
51
+
52
52
  validate :validate_ingredient, on: :update, if: -> { validations.any? }
53
53
 
54
54
  has_one :content, as: :essence, class_name: "Alchemy::Content", inverse_of: :essence
@@ -62,7 +62,7 @@ module Alchemy #:nodoc:
62
62
  delegate :trashed?, to: :element, allow_nil: true
63
63
  delegate :public?, to: :element, allow_nil: true
64
64
 
65
- after_update :touch_content
65
+ after_save :touch_element
66
66
 
67
67
  def acts_as_essence_class
68
68
  #{name}
@@ -109,7 +109,7 @@ module Alchemy #:nodoc:
109
109
  def register_as_essence_association!
110
110
  klass_name = model_name.to_s
111
111
  arguments = [:has_many, klass_name.demodulize.tableize.to_sym, through: :contents,
112
- source: :essence, source_type: klass_name]
112
+ source: :essence, source_type: klass_name]
113
113
  %w(Page Element).each { |k| "Alchemy::#{k}".constantize.send(*arguments) }
114
114
  end
115
115
  end
@@ -171,7 +171,7 @@ module Alchemy #:nodoc:
171
171
  end
172
172
 
173
173
  def validations
174
- @validations ||= definition.present? ? definition['validate'] || [] : []
174
+ @validations ||= definition.present? ? definition["validate"] || [] : []
175
175
  end
176
176
 
177
177
  def validation_errors
@@ -187,6 +187,7 @@ module Alchemy #:nodoc:
187
187
 
188
188
  def validate_uniqueness(validate = true)
189
189
  return if !validate || !public?
190
+
190
191
  if duplicates.any?
191
192
  errors.add(ingredient_column, :taken)
192
193
  validation_errors << :taken
@@ -194,7 +195,7 @@ module Alchemy #:nodoc:
194
195
  end
195
196
 
196
197
  def validate_format(format)
197
- matcher = Config.get('format_matchers')[format] || format
198
+ matcher = Config.get("format_matchers")[format] || format
198
199
  if ingredient.to_s.match(Regexp.new(matcher)).nil?
199
200
  errors.add(ingredient_column, :invalid)
200
201
  validation_errors << :invalid
@@ -216,7 +217,7 @@ module Alchemy #:nodoc:
216
217
  end
217
218
  end
218
219
 
219
- # Returns the value stored from the database column that is configured as ingredient column.
220
+ # Sets the value stored in the database column that is configured as ingredient column.
220
221
  def ingredient=(value)
221
222
  if respond_to?(ingredient_setter_method)
222
223
  send(ingredient_setter_method, value)
@@ -225,19 +226,19 @@ module Alchemy #:nodoc:
225
226
 
226
227
  # Returns the setter method for ingredient column
227
228
  def ingredient_setter_method
228
- ingredient_column.to_s + '='
229
+ ingredient_column.to_s + "="
229
230
  end
230
231
 
231
232
  # Essence definition from config/elements.yml
232
233
  def definition
233
234
  return {} if element.nil? || element.content_definitions.nil?
234
- element.content_definitions.detect { |c| c['name'] == content.name } || {}
235
+
236
+ element.content_definitions.detect { |c| c["name"] == content.name } || {}
235
237
  end
236
238
 
237
- # Touch content. Called after update.
238
- def touch_content
239
- return nil if content.nil?
240
- content.touch
239
+ # Touches element. Called after save.
240
+ def touch_element
241
+ element&.touch
241
242
  end
242
243
 
243
244
  # Returns the first x (default 30) characters of ingredient for the Element#preview_text method.
@@ -247,11 +248,11 @@ module Alchemy #:nodoc:
247
248
  end
248
249
 
249
250
  def open_link_in_new_window?
250
- respond_to?(:link_target) && link_target == 'blank'
251
+ respond_to?(:link_target) && link_target == "blank"
251
252
  end
252
253
 
253
254
  def partial_name
254
- self.class.name.split('::').last.underscore
255
+ self.class.name.split("::").last.underscore
255
256
  end
256
257
 
257
258
  def acts_as_essence?
@@ -8,7 +8,7 @@ module Alchemy
8
8
  "audio/mpeg",
9
9
  "audio/mp4",
10
10
  "audio/wav",
11
- "audio/x-wav"
11
+ "audio/x-wav",
12
12
  ]
13
13
 
14
14
  IMAGE_FILE_TYPES = [
@@ -17,7 +17,7 @@ module Alchemy
17
17
  "image/png",
18
18
  "image/svg+xml",
19
19
  "image/tiff",
20
- "image/x-psd"
20
+ "image/x-psd",
21
21
  ]
22
22
 
23
23
  VCARD_FILE_TYPES = ["text/x-vcard", "application/vcard"]
@@ -29,18 +29,18 @@ module Alchemy
29
29
  "video/mpeg",
30
30
  "video/quicktime",
31
31
  "video/x-msvideo",
32
- "video/x-ms-wmv"
32
+ "video/x-ms-wmv",
33
33
  ]
34
34
 
35
35
  TEXT_FILE_TYPES = [
36
36
  "application/rtf",
37
- "text/plain"
37
+ "text/plain",
38
38
  ]
39
39
 
40
40
  EXCEL_FILE_TYPES = [
41
41
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
42
42
  "application/vnd.ms-excel",
43
- "text/csv"
43
+ "text/csv",
44
44
  ]
45
45
  end
46
46
  end
@@ -11,7 +11,7 @@ module Alchemy
11
11
  if object.respond_to?(:attribute_fixed?) && object.attribute_fixed?(attribute_name)
12
12
  options[:disabled] = true
13
13
  options[:input_html] = options.fetch(:input_html, {}).merge(
14
- 'data-alchemy-tooltip' => Alchemy.t(:attribute_fixed, attribute_name)
14
+ "data-alchemy-tooltip" => Alchemy.t(:attribute_fixed, attribute_name),
15
15
  )
16
16
  end
17
17
 
@@ -22,10 +22,10 @@ module Alchemy
22
22
  #
23
23
  def submit(label, options = {})
24
24
  options = {
25
- wrapper_html: {class: 'submit'}
25
+ wrapper_html: {class: "submit"},
26
26
  }.update(options)
27
- template.content_tag('div', options.delete(:wrapper_html)) do
28
- template.content_tag('button', label, options.delete(:input_html))
27
+ template.content_tag("div", options.delete(:wrapper_html)) do
28
+ template.content_tag("button", label, options.delete(:input_html))
29
29
  end
30
30
  end
31
31
  end
data/lib/alchemy/hints.rb CHANGED
@@ -35,7 +35,7 @@ module Alchemy
35
35
  # @return String
36
36
  #
37
37
  def hint
38
- hint = definition['hint']
38
+ hint = definition["hint"]
39
39
  if hint == true
40
40
  Alchemy.t(name, scope: hint_translation_scope)
41
41
  else
data/lib/alchemy/i18n.rb CHANGED
@@ -74,11 +74,12 @@ module Alchemy
74
74
 
75
75
  def humanize_default_string!(msg, options)
76
76
  return if options[:default].present?
77
+
77
78
  options[:default] = msg.is_a?(Symbol) ? msg.to_s.humanize : msg
78
79
  end
79
80
 
80
81
  def alchemy_scoped_scope(options)
81
- default_scope = ['alchemy']
82
+ default_scope = ["alchemy"]
82
83
  case options[:scope]
83
84
  when Array
84
85
  default_scope + options[:scope]
@@ -4,7 +4,7 @@ module Alchemy
4
4
  module Modules
5
5
  mattr_accessor :alchemy_modules
6
6
 
7
- @@alchemy_modules = YAML.load_file(File.expand_path('../../config/alchemy/modules.yml', __dir__))
7
+ @@alchemy_modules = YAML.load_file(File.expand_path("../../config/alchemy/modules.yml", __dir__))
8
8
 
9
9
  class << self
10
10
  def included(base)
@@ -28,11 +28,11 @@ module Alchemy
28
28
  definition_hash = module_definition.deep_stringify_keys
29
29
 
30
30
  ### Validate controller(s) existence
31
- if definition_hash['navigation'].is_a?(Hash)
32
- defined_controllers = [definition_hash['navigation']['controller']]
31
+ if definition_hash["navigation"].is_a?(Hash)
32
+ defined_controllers = [definition_hash["navigation"]["controller"]]
33
33
 
34
- if definition_hash['navigation']['sub_navigation'].is_a?(Array)
35
- defined_controllers.concat(definition_hash['navigation']['sub_navigation'].map{ |x| x['controller'] })
34
+ if definition_hash["navigation"]["sub_navigation"].is_a?(Array)
35
+ defined_controllers.concat(definition_hash["navigation"]["sub_navigation"].map{ |x| x["controller"] })
36
36
  end
37
37
 
38
38
  validate_controllers_existence(defined_controllers)
@@ -52,7 +52,7 @@ module Alchemy
52
52
  begin
53
53
  controller_name.constantize
54
54
  rescue NameError
55
- raise "Error in AlchemyCMS module definition: '#{definition_hash['name']}'. Could not find the matching controller class #{controller_name.sub(/^::/, '')} for the specified controller: '#{controller_val}'"
55
+ raise "Error in AlchemyCMS module definition: '#{definition_hash["name"]}'. Could not find the matching controller class #{controller_name.sub(/^::/, "")} for the specified controller: '#{controller_val}'"
56
56
  end
57
57
  end
58
58
  end
@@ -66,11 +66,11 @@ module Alchemy
66
66
  def module_definition_for(name_or_params)
67
67
  case name_or_params
68
68
  when String
69
- alchemy_modules.detect { |m| m['name'] == name_or_params }
69
+ alchemy_modules.detect { |m| m["name"] == name_or_params }
70
70
  when Hash
71
71
  name_or_params.stringify_keys!
72
72
  alchemy_modules.detect do |alchemy_module|
73
- module_navi = alchemy_module.fetch('navigation', {})
73
+ module_navi = alchemy_module.fetch("navigation", {})
74
74
  definition_from_mainnavi(module_navi, name_or_params) ||
75
75
  definition_from_subnavi(module_navi, name_or_params)
76
76
  end
@@ -86,7 +86,7 @@ module Alchemy
86
86
  end
87
87
 
88
88
  def definition_from_subnavi(module_navi, params)
89
- subnavi = module_navi['sub_navigation']
89
+ subnavi = module_navi["sub_navigation"]
90
90
  return if subnavi.nil?
91
91
 
92
92
  subnavi.any? do |navi|
@@ -95,15 +95,15 @@ module Alchemy
95
95
  end
96
96
 
97
97
  def controller_matches?(navi, params)
98
- remove_slash(navi['controller']) == remove_slash(params['controller'])
98
+ remove_slash(navi["controller"]) == remove_slash(params["controller"])
99
99
  end
100
100
 
101
101
  def action_matches?(navi, params)
102
- navi['action'] == params['action']
102
+ navi["action"] == params["action"]
103
103
  end
104
104
 
105
105
  def remove_slash(str)
106
- str.gsub(/^\//, '')
106
+ str.gsub(/^\//, "")
107
107
  end
108
108
  end
109
109
  end
@@ -10,17 +10,17 @@ module Alchemy
10
10
  # @returns String
11
11
  def convert_to_urlname(name)
12
12
  name
13
- .gsub(/[äÄ]/, 'ae')
14
- .gsub(/[üÜ]/, 'ue')
15
- .gsub(/[öÖ]/, 'oe')
16
- .gsub(/[ß]/, 'ss')
13
+ .gsub(/[äÄ]/, "ae")
14
+ .gsub(/[üÜ]/, "ue")
15
+ .gsub(/[öÖ]/, "oe")
16
+ .gsub(/[ß]/, "ss")
17
17
  .parameterize
18
18
  end
19
19
 
20
20
  # Converts a filename and suffix into a human readable name.
21
21
  #
22
22
  def convert_to_humanized_name(name, suffix)
23
- name.gsub(/\.#{::Regexp.quote(suffix)}$/i, '').tr('_', ' ').strip
23
+ name.gsub(/\.#{::Regexp.quote(suffix)}$/i, "").tr("_", " ").strip
24
24
  end
25
25
  end
26
26
  end
@@ -18,6 +18,7 @@ module Alchemy
18
18
  def run_on_page_layout_callbacks
19
19
  OnPageLayout.callbacks.each do |page_layout, callbacks|
20
20
  next unless call_page_layout_callback_for?(page_layout)
21
+
21
22
  callbacks.each do |callback|
22
23
  if callback.respond_to?(:call)
23
24
  instance_eval(&callback)
@@ -37,7 +37,8 @@ module Alchemy
37
37
  #
38
38
  def get(name)
39
39
  return {} if name.blank?
40
- all.detect { |a| a['name'].casecmp(name).zero? }
40
+
41
+ all.detect { |a| a["name"].casecmp(name).zero? }
41
42
  end
42
43
 
43
44
  def get_all_by_attributes(attributes)
@@ -66,7 +67,7 @@ module Alchemy
66
67
  #
67
68
  def layouts_with_own_for_select(page_layout_name, language_id, only_layoutpages = false)
68
69
  layouts = selectable_layouts(language_id, only_layoutpages)
69
- if layouts.detect { |l| l['name'] == page_layout_name }.nil?
70
+ if layouts.detect { |l| l["name"] == page_layout_name }.nil?
70
71
  @map_array = [[human_layout_name(page_layout_name), page_layout_name]]
71
72
  else
72
73
  @map_array = []
@@ -87,9 +88,9 @@ module Alchemy
87
88
  @language_id = language_id
88
89
  all.select do |layout|
89
90
  if only_layoutpages
90
- layout['layoutpage'] && layout_available?(layout)
91
+ layout["layoutpage"] && layout_available?(layout)
91
92
  else
92
- !layout['layoutpage'] && layout_available?(layout)
93
+ !layout["layoutpage"] && layout_available?(layout)
93
94
  end
94
95
  end
95
96
  end
@@ -98,7 +99,7 @@ module Alchemy
98
99
  #
99
100
  def element_names_for(page_layout)
100
101
  if definition = get(page_layout)
101
- definition.fetch('elements', [])
102
+ definition.fetch("elements", [])
102
103
  else
103
104
  Rails.logger.warn "\n+++ Warning: No layout definition for #{page_layout} found! in page_layouts.yml\n"
104
105
  []
@@ -118,7 +119,7 @@ module Alchemy
118
119
  # The layout name
119
120
  #
120
121
  def human_layout_name(layout)
121
- Alchemy.t(layout, scope: 'page_layout_names', default: layout.to_s.humanize)
122
+ Alchemy.t(layout, scope: "page_layout_names", default: layout.to_s.humanize)
122
123
  end
123
124
 
124
125
  private
@@ -126,13 +127,13 @@ module Alchemy
126
127
  # Returns true if the given layout is unique and not already taken or it should be hidden.
127
128
  #
128
129
  def layout_available?(layout)
129
- !layout['hide'] && !already_taken?(layout) && available_on_site?(layout)
130
+ !layout["hide"] && !already_taken?(layout) && available_on_site?(layout)
130
131
  end
131
132
 
132
133
  # Returns true if this layout is unique and already taken by another page.
133
134
  #
134
135
  def already_taken?(layout)
135
- layout['unique'] && page_with_layout_existing?(layout['name'])
136
+ layout["unique"] && page_with_layout_existing?(layout["name"])
136
137
  end
137
138
 
138
139
  # Returns true if one page already has the given layout
@@ -152,8 +153,10 @@ module Alchemy
152
153
  # page_layouts: [default_intro]
153
154
  #
154
155
  def available_on_site?(layout)
156
+ return false unless Alchemy::Site.current
157
+
155
158
  Alchemy::Site.current.definition.blank? ||
156
- Alchemy::Site.current.definition.fetch('page_layouts', []).include?(layout['name'])
159
+ Alchemy::Site.current.definition.fetch("page_layouts", []).include?(layout["name"])
157
160
  end
158
161
 
159
162
  # Reads the layout definitions from +config/alchemy/page_layouts.yml+.
@@ -162,21 +165,21 @@ module Alchemy
162
165
  if File.exist?(layouts_file_path)
163
166
  YAML.safe_load(ERB.new(File.read(layouts_file_path)).result, YAML_WHITELIST_CLASSES, [], true) || []
164
167
  else
165
- raise LoadError, "Could not find page_layouts.yml file! Please run `rails generate alchemy:scaffold`"
168
+ raise LoadError, "Could not find page_layouts.yml file! Please run `rails generate alchemy:install`"
166
169
  end
167
170
  end
168
171
 
169
172
  # Returns the page_layouts.yml file path
170
173
  #
171
174
  def layouts_file_path
172
- Rails.root.join 'config/alchemy/page_layouts.yml'
175
+ Rails.root.join "config/alchemy/page_layouts.yml"
173
176
  end
174
177
 
175
178
  # Maps given layouts for Rails select form helper.
176
179
  #
177
180
  def mapped_layouts_for_select(layouts)
178
181
  layouts.each do |layout|
179
- @map_array << [human_layout_name(layout['name']), layout["name"]]
182
+ @map_array << [human_layout_name(layout["name"]), layout["name"]]
180
183
  end
181
184
  @map_array
182
185
  end
data/lib/alchemy/paths.rb CHANGED
@@ -29,6 +29,6 @@ module Alchemy
29
29
 
30
30
  # Defaults
31
31
  #
32
- @@admin_path = 'admin'
32
+ @@admin_path = "admin"
33
33
  @@admin_constraints = {}
34
34
  end