pages_core 3.6.2 → 3.8.2

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 (332) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -3
  3. data/Rakefile +3 -1
  4. data/app/assets/builds/pages_core/admin-dist.js +55 -0
  5. data/app/assets/stylesheets/pages/admin/components/forms.scss +20 -0
  6. data/app/assets/stylesheets/pages/admin/components/image_editor.scss +1 -0
  7. data/app/assets/stylesheets/pages/admin/components/image_grid.scss +33 -5
  8. data/app/assets/stylesheets/pages/admin/components/layout.scss +2 -1
  9. data/app/assets/stylesheets/pages/admin/components/login.scss +6 -0
  10. data/app/assets/stylesheets/pages/admin/components/tabs.scss +5 -0
  11. data/app/assets/stylesheets/pages/admin/components/tag_editor.scss +13 -7
  12. data/app/assets/stylesheets/pages/admin/controllers/pages.scss +13 -5
  13. data/app/assets/stylesheets/pages/admin.scss +0 -1
  14. data/app/assets/stylesheets/pages/errors.css +2 -0
  15. data/app/controller_dummies/admin/admin_controller.rb +3 -1
  16. data/app/controller_dummies/application_controller.rb +3 -1
  17. data/app/controller_dummies/attachments_controller.rb +3 -1
  18. data/app/controller_dummies/frontend_controller.rb +3 -1
  19. data/app/controller_dummies/images_controller.rb +3 -1
  20. data/app/controller_dummies/page_files_controller.rb +3 -1
  21. data/app/controller_dummies/pages_controller.rb +3 -1
  22. data/app/controller_dummies/sitemaps_controller.rb +3 -1
  23. data/app/controllers/admin/attachments_controller.rb +5 -3
  24. data/app/controllers/admin/categories_controller.rb +2 -0
  25. data/app/controllers/admin/images_controller.rb +16 -8
  26. data/app/controllers/admin/invites_controller.rb +4 -1
  27. data/app/controllers/admin/pages_controller.rb +7 -19
  28. data/app/controllers/admin/password_resets_controller.rb +9 -5
  29. data/app/controllers/admin/users_controller.rb +10 -4
  30. data/app/controllers/concerns/pages_core/admin/news_page_controller.rb +13 -11
  31. data/app/controllers/concerns/pages_core/admin/persistent_params.rb +75 -0
  32. data/app/controllers/concerns/pages_core/authentication.rb +13 -5
  33. data/app/controllers/concerns/pages_core/error_renderer.rb +3 -0
  34. data/app/controllers/concerns/pages_core/error_reporting.rb +36 -0
  35. data/app/controllers/concerns/pages_core/policies_helper.rb +4 -1
  36. data/app/controllers/concerns/pages_core/preview_pages_controller.rb +8 -0
  37. data/app/controllers/concerns/pages_core/process_titler.rb +2 -0
  38. data/app/controllers/concerns/pages_core/rss_controller.rb +2 -0
  39. data/app/controllers/concerns/pages_core/static_cache_controller.rb +48 -0
  40. data/app/controllers/errors_controller.rb +5 -53
  41. data/app/controllers/pages_core/admin_controller.rb +7 -67
  42. data/app/controllers/pages_core/attachments_controller.rb +10 -6
  43. data/app/controllers/pages_core/base_controller.rb +11 -17
  44. data/app/controllers/pages_core/frontend/page_files_controller.rb +6 -2
  45. data/app/controllers/pages_core/frontend/pages_controller.rb +14 -17
  46. data/app/controllers/pages_core/frontend_controller.rb +3 -0
  47. data/app/controllers/pages_core/images_controller.rb +3 -1
  48. data/app/controllers/pages_core/sitemaps_controller.rb +11 -5
  49. data/app/controllers/sessions_controller.rb +3 -1
  50. data/app/formatters/pages_core/html_formatter.rb +13 -63
  51. data/app/formatters/pages_core/image_embedder.rb +79 -0
  52. data/app/formatters/pages_core/link_renderer.rb +4 -2
  53. data/app/helpers/admin/admin_helper.rb +2 -0
  54. data/app/helpers/admin/menu_helper.rb +6 -4
  55. data/app/helpers/admin/pages_helper.rb +4 -57
  56. data/app/helpers/application_helper.rb +3 -1
  57. data/app/helpers/frontend_helper.rb +3 -1
  58. data/app/helpers/pages_core/admin/admin_helper.rb +22 -106
  59. data/app/helpers/pages_core/admin/content_tabs_helper.rb +31 -0
  60. data/app/helpers/pages_core/admin/date_range_helper.rb +55 -0
  61. data/app/helpers/pages_core/admin/form_builder.rb +8 -0
  62. data/app/helpers/pages_core/admin/image_uploads_helper.rb +47 -0
  63. data/app/helpers/pages_core/admin/labelled_field_helper.rb +12 -9
  64. data/app/helpers/pages_core/admin/page_blocks_helper.rb +66 -0
  65. data/app/helpers/pages_core/admin/page_json_helper.rb +23 -0
  66. data/app/helpers/pages_core/admin/tag_editor_helper.rb +11 -39
  67. data/app/helpers/pages_core/application_helper.rb +3 -0
  68. data/app/helpers/pages_core/attachments_helper.rb +31 -27
  69. data/app/helpers/pages_core/form_builder.rb +17 -13
  70. data/app/helpers/pages_core/frontend_helper.rb +3 -3
  71. data/app/helpers/pages_core/head_tags_helper.rb +18 -22
  72. data/app/helpers/pages_core/images_helper.rb +3 -0
  73. data/app/helpers/pages_core/meta_tags_helper.rb +3 -1
  74. data/app/helpers/pages_core/open_graph_tags_helper.rb +8 -6
  75. data/app/helpers/pages_core/page_path_helper.rb +24 -3
  76. data/app/javascript/admin-dist.js +2 -0
  77. data/app/javascript/components/Attachments/Attachment.jsx +121 -0
  78. data/app/javascript/components/Attachments/AttachmentEditor.jsx +116 -0
  79. data/app/javascript/components/Attachments/Placeholder.jsx +10 -0
  80. data/app/javascript/components/Attachments.jsx +165 -0
  81. data/app/{assets/javascripts/pages/admin/components/date_range_select.jsx → javascript/components/DateRangeSelect.jsx} +16 -5
  82. data/app/javascript/components/EditableImage.jsx +61 -0
  83. data/app/javascript/components/FileUploadButton.jsx +47 -0
  84. data/app/{assets/javascripts/pages/admin/components/focal_point.jsx → javascript/components/ImageCropper/FocalPoint.jsx} +12 -1
  85. data/app/javascript/components/ImageCropper/Image.jsx +65 -0
  86. data/app/javascript/components/ImageCropper/Toolbar.jsx +73 -0
  87. data/app/javascript/components/ImageCropper/useCrop.js +199 -0
  88. data/app/javascript/components/ImageCropper.jsx +90 -0
  89. data/app/javascript/components/ImageEditor/Form.jsx +98 -0
  90. data/app/javascript/components/ImageEditor.jsx +62 -0
  91. data/app/javascript/components/ImageGrid/DragElement.jsx +30 -0
  92. data/app/javascript/components/ImageGrid/FilePlaceholder.jsx +9 -0
  93. data/app/javascript/components/ImageGrid/GridImage.jsx +103 -0
  94. data/app/javascript/components/ImageGrid/Placeholder.jsx +23 -0
  95. data/app/javascript/components/ImageGrid.jsx +257 -0
  96. data/app/javascript/components/ImageUploader.jsx +171 -0
  97. data/app/{assets/javascripts/pages/admin/components/modal.jsx → javascript/components/Modal.jsx} +13 -2
  98. data/app/{assets/javascripts/pages/admin/components/page_dates.jsx → javascript/components/PageDates.jsx} +11 -1
  99. data/app/{assets/javascripts/pages/admin/components/page_files.jsx → javascript/components/PageFiles.jsx} +11 -2
  100. data/app/{assets/javascripts/pages/admin/components/page_images.jsx → javascript/components/PageImages.jsx} +11 -2
  101. data/app/{assets/javascripts/pages/admin/components/page_tree_store.jsx → javascript/components/PageTree.jsx} +127 -137
  102. data/app/{assets/javascripts/pages/admin/components/page_tree.jsx → javascript/components/PageTreeDraggable.jsx} +44 -38
  103. data/app/{assets/javascripts/pages/admin/components/page_tree_node.jsx → javascript/components/PageTreeNode.jsx} +46 -31
  104. data/app/javascript/components/RichTextArea.jsx +213 -0
  105. data/app/javascript/components/RichTextToolbarButton.jsx +20 -0
  106. data/app/javascript/components/TagEditor/AddTagForm.jsx +42 -0
  107. data/app/javascript/components/TagEditor/Tag.jsx +32 -0
  108. data/app/javascript/components/TagEditor.jsx +61 -0
  109. data/app/javascript/components/Toast.jsx +72 -0
  110. data/app/javascript/components/drag/draggedOrder.js +51 -0
  111. data/app/javascript/components/drag/useDragCollection.js +84 -0
  112. data/app/javascript/components/drag/useDragUploader.js +112 -0
  113. data/app/javascript/components/drag/useDraggable.js +17 -0
  114. data/app/javascript/components/drag.js +6 -0
  115. data/app/javascript/components.js +15 -0
  116. data/app/javascript/controllers/EditPageController.js +20 -0
  117. data/app/javascript/controllers/LoginController.js +29 -0
  118. data/app/javascript/controllers/MainController.js +65 -0
  119. data/app/javascript/controllers/PageOptionsController.js +62 -0
  120. data/app/javascript/features/RichText.jsx +34 -0
  121. data/app/javascript/hooks.js +2 -0
  122. data/app/javascript/index.js +38 -0
  123. data/app/{assets/javascripts/pages/admin/lib/tree.jsx → javascript/lib/Tree.js} +64 -63
  124. data/app/javascript/lib/copyToClipboard.js +13 -0
  125. data/app/javascript/lib/readyHandler.js +22 -0
  126. data/app/javascript/lib/request.js +36 -0
  127. data/app/javascript/stores/ModalStore.jsx +12 -0
  128. data/app/javascript/stores/ToastStore.jsx +14 -0
  129. data/app/javascript/stores.js +2 -0
  130. data/app/jobs/pages_core/autopublish_job.rb +3 -1
  131. data/app/jobs/pages_core/sweep_cache_job.rb +4 -2
  132. data/app/mailers/admin_mailer.rb +4 -14
  133. data/app/models/attachment.rb +10 -8
  134. data/app/models/autopublisher.rb +3 -0
  135. data/app/models/category.rb +3 -1
  136. data/app/models/concerns/pages_core/has_roles.rb +2 -0
  137. data/app/models/concerns/pages_core/humanizable_param.rb +9 -6
  138. data/app/models/concerns/pages_core/page_model/attachments.rb +2 -0
  139. data/app/models/concerns/pages_core/page_model/autopublishable.rb +2 -0
  140. data/app/models/concerns/pages_core/page_model/dated_page.rb +11 -11
  141. data/app/models/concerns/pages_core/page_model/images.rb +8 -2
  142. data/app/models/concerns/pages_core/page_model/localizable.rb +2 -0
  143. data/app/models/concerns/pages_core/page_model/pathable.rb +26 -25
  144. data/app/models/concerns/pages_core/page_model/redirectable.rb +3 -1
  145. data/app/models/concerns/pages_core/page_model/searchable.rb +19 -0
  146. data/app/models/concerns/pages_core/page_model/sortable.rb +6 -5
  147. data/app/models/concerns/pages_core/page_model/status.rb +2 -0
  148. data/app/models/concerns/pages_core/page_model/templateable.rb +7 -2
  149. data/app/models/concerns/pages_core/page_model/tree.rb +27 -20
  150. data/app/models/concerns/pages_core/searchable_document.rb +71 -0
  151. data/app/models/concerns/pages_core/sweepable.rb +4 -2
  152. data/app/models/concerns/pages_core/taggable.rb +33 -12
  153. data/app/models/image.rb +14 -1
  154. data/app/models/invite.rb +3 -1
  155. data/app/models/invite_role.rb +5 -3
  156. data/app/models/page.rb +6 -3
  157. data/app/models/page_builder.rb +2 -0
  158. data/app/models/page_category.rb +3 -1
  159. data/app/models/page_exporter.rb +23 -10
  160. data/app/models/page_file.rb +3 -1
  161. data/app/models/page_image.rb +3 -3
  162. data/app/models/page_path.rb +13 -5
  163. data/app/models/password_reset_token.rb +3 -1
  164. data/app/models/role.rb +9 -6
  165. data/app/models/search_document.rb +72 -0
  166. data/app/models/tag.rb +9 -6
  167. data/app/models/tagging.rb +4 -2
  168. data/app/models/user.rb +8 -5
  169. data/app/policies/invite_policy.rb +2 -0
  170. data/app/policies/page_file_policy.rb +2 -0
  171. data/app/policies/page_image_policy.rb +2 -0
  172. data/app/policies/page_policy.rb +2 -0
  173. data/app/policies/policy.rb +2 -0
  174. data/app/policies/user_policy.rb +2 -0
  175. data/app/{serializers/admin/attachment_serializer.rb → resources/admin/attachment_resource.rb} +10 -7
  176. data/app/{serializers/admin/image_serializer.rb → resources/admin/image_resource.rb} +13 -11
  177. data/app/resources/admin/page_file_resource.rb +10 -0
  178. data/app/resources/admin/page_image_resource.rb +10 -0
  179. data/app/resources/export/attachment_resource.rb +10 -0
  180. data/app/resources/export/page_image_resource.rb +45 -0
  181. data/app/resources/export/page_resource.rb +42 -0
  182. data/app/{serializers/page_image_serializer.rb → resources/page_image_resource.rb} +10 -16
  183. data/app/resources/page_resource.rb +33 -0
  184. data/app/services/pages_core/create_user_service.rb +5 -2
  185. data/app/services/pages_core/destroy_invite_service.rb +25 -0
  186. data/app/services/pages_core/invite_service.rb +4 -2
  187. data/app/views/admin/images/show.json.jbuilder +2 -0
  188. data/app/views/admin/pages/_edit_content.html.erb +1 -1
  189. data/app/views/admin/pages/_edit_files.html.erb +1 -5
  190. data/app/views/admin/pages/_edit_images.html.erb +1 -5
  191. data/app/views/admin/pages/_edit_options.html.erb +74 -55
  192. data/app/views/admin/pages/_form.html.erb +19 -0
  193. data/app/views/admin/pages/edit.html.erb +35 -61
  194. data/app/views/admin/pages/index.html.erb +0 -1
  195. data/app/views/admin/pages/new.html.erb +32 -32
  196. data/app/views/admin/pages/news.html.erb +1 -1
  197. data/app/views/admin/users/_access_control.html.erb +5 -1
  198. data/app/views/admin/users/login.html.erb +12 -4
  199. data/app/views/errors/500.html.erb +2 -20
  200. data/app/views/errors/_generic_help.html.erb +1 -1
  201. data/app/views/feeds/pages.rss.builder +3 -2
  202. data/app/views/layouts/admin/_header.html.erb +1 -1
  203. data/app/views/layouts/admin/_page_header.html.erb +33 -0
  204. data/app/views/layouts/admin.html.erb +23 -42
  205. data/app/views/pages_core/_google_analytics.html.erb +8 -0
  206. data/app/views/sitemaps/show.xml.builder +2 -0
  207. data/config/routes.rb +5 -5
  208. data/db/migrate/20111219033112_create_pages_tables.rb +192 -271
  209. data/db/migrate/20180625154059_enable_search_extensions.rb +10 -0
  210. data/db/migrate/20210209151400_create_search_configurations.rb +35 -0
  211. data/db/migrate/20210210235200_create_search_documents.rb +74 -0
  212. data/lib/pages_core/admin_menu_item.rb +3 -0
  213. data/lib/pages_core/archive_finder.rb +12 -16
  214. data/lib/pages_core/attachment_embedder.rb +4 -6
  215. data/lib/pages_core/cache_sweeper.rb +10 -108
  216. data/lib/pages_core/configuration/base.rb +5 -0
  217. data/lib/pages_core/configuration/pages.rb +4 -2
  218. data/lib/pages_core/configuration.rb +2 -0
  219. data/lib/pages_core/digest_verifier.rb +5 -5
  220. data/lib/pages_core/engine.rb +53 -5
  221. data/lib/pages_core/extensions/string_extensions.rb +3 -1
  222. data/lib/pages_core/extensions.rb +2 -0
  223. data/lib/pages_core/page_path_constraint.rb +2 -0
  224. data/lib/pages_core/pages_plugin.rb +3 -1
  225. data/lib/pages_core/plugin.rb +4 -52
  226. data/lib/pages_core/pub_sub.rb +2 -0
  227. data/lib/pages_core/static_cache/null_handler.rb +17 -0
  228. data/lib/pages_core/static_cache/page_cache_handler.rb +56 -0
  229. data/lib/pages_core/static_cache/varnish_handler.rb +55 -0
  230. data/lib/pages_core/static_cache.rb +26 -0
  231. data/lib/pages_core/templates/block_configuration.rb +4 -1
  232. data/lib/pages_core/templates/configuration.rb +5 -1
  233. data/lib/pages_core/templates/configuration_handler.rb +5 -3
  234. data/lib/pages_core/templates/configuration_proxy.rb +2 -0
  235. data/lib/pages_core/templates/controller_actions.rb +2 -0
  236. data/lib/pages_core/templates/template_configuration.rb +18 -13
  237. data/lib/pages_core/templates.rb +5 -3
  238. data/lib/pages_core/version.rb +3 -1
  239. data/lib/pages_core.rb +13 -5
  240. data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +2 -7
  241. data/lib/rails/generators/pages_core/install/install_generator.rb +3 -7
  242. data/lib/rails/generators/pages_core/install/templates/active_job_initializer.rb +2 -0
  243. data/lib/rails/generators/pages_core/install/templates/application_controller.rb +2 -0
  244. data/lib/rails/generators/pages_core/install/templates/application_helper.rb +2 -0
  245. data/lib/rails/generators/pages_core/install/templates/delayed_job +1 -0
  246. data/lib/rails/generators/pages_core/install/templates/delayed_job_initializer.rb +17 -0
  247. data/lib/rails/generators/pages_core/install/templates/frontend_controller.rb +2 -0
  248. data/lib/rails/generators/pages_core/install/templates/frontend_helper.rb +2 -0
  249. data/lib/rails/generators/pages_core/install/templates/gitignore.erb +12 -1
  250. data/lib/rails/generators/pages_core/install/templates/page_templates_initializer.rb +4 -2
  251. data/lib/rails/generators/pages_core/install/templates/pages_controller.rb +2 -0
  252. data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +2 -6
  253. data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +18 -14
  254. data/lib/rails/generators/pages_core/rspec/templates/factories.rb +3 -8
  255. data/lib/rails/generators/pages_core/rspec/templates/mailer_macros.rb +2 -0
  256. data/lib/rails/generators/pages_core/rspec/templates/page_templates_spec.rb +26 -0
  257. data/lib/rails/generators/pages_core/rspec/templates/rails_helper.rb +91 -0
  258. data/lib/rails/generators/pages_core/rspec/templates/spec_helper.rb +89 -36
  259. data/lib/tasks/pages/cache.rake +8 -5
  260. data/lib/tasks/pages/export.rake +3 -1
  261. data/lib/tasks/pages/page_paths.rake +2 -0
  262. data/lib/tasks/pages.rake +3 -2
  263. data/template.rb +2 -0
  264. metadata +194 -157
  265. data/app/assets/javascripts/pages/admin/components/attachment.jsx +0 -130
  266. data/app/assets/javascripts/pages/admin/components/attachment_editor.jsx +0 -131
  267. data/app/assets/javascripts/pages/admin/components/attachments.jsx +0 -211
  268. data/app/assets/javascripts/pages/admin/components/drag_uploader.jsx +0 -174
  269. data/app/assets/javascripts/pages/admin/components/editable_image.jsx +0 -57
  270. data/app/assets/javascripts/pages/admin/components/file_upload_button.jsx +0 -44
  271. data/app/assets/javascripts/pages/admin/components/grid_image.jsx +0 -124
  272. data/app/assets/javascripts/pages/admin/components/image_editor.jsx +0 -496
  273. data/app/assets/javascripts/pages/admin/components/image_grid.jsx +0 -301
  274. data/app/assets/javascripts/pages/admin/components/image_uploader.jsx +0 -171
  275. data/app/assets/javascripts/pages/admin/components/modal_store.jsx +0 -20
  276. data/app/assets/javascripts/pages/admin/components/rich_text_area.jsx +0 -63
  277. data/app/assets/javascripts/pages/admin/components/rich_text_toolbar.jsx +0 -58
  278. data/app/assets/javascripts/pages/admin/components/toast.jsx +0 -37
  279. data/app/assets/javascripts/pages/admin/components/toast_store.jsx +0 -52
  280. data/app/assets/javascripts/pages/admin/components.jsx +0 -2
  281. data/app/assets/javascripts/pages/admin/features/content_tabs.jsx +0 -72
  282. data/app/assets/javascripts/pages/admin/features/edit_page.jsx +0 -97
  283. data/app/assets/javascripts/pages/admin/features/rich_text.jsx +0 -14
  284. data/app/assets/javascripts/pages/admin/features/tag_editor.jsx +0 -160
  285. data/app/assets/javascripts/pages/admin.jsx +0 -17
  286. data/app/assets/javascripts/pages/login_form.jsx +0 -21
  287. data/app/controllers/concerns/pages_core/domain_based_cache.rb +0 -26
  288. data/app/serializers/admin/page_file_serializer.rb +0 -6
  289. data/app/serializers/admin/page_image_serializer.rb +0 -6
  290. data/app/serializers/page_export_serializer.rb +0 -30
  291. data/app/serializers/page_file_export_serializer.rb +0 -4
  292. data/app/serializers/page_image_export_serializer.rb +0 -40
  293. data/app/serializers/page_serializer.rb +0 -21
  294. data/app/views/admin_mailer/error_report.html.erb +0 -70
  295. data/app/views/errors/500_critical.html.erb +0 -7
  296. data/app/views/errors/report.html.erb +0 -4
  297. data/app/views/layouts/admin/_analytics.html.erb +0 -16
  298. data/config/removed_migrations.yml +0 -60
  299. data/db/migrate/20120627033112_rename_textbits.rb +0 -17
  300. data/db/migrate/20121010055412_drop_removed_tables.rb +0 -81
  301. data/db/migrate/20130130053932_add_queue_to_delayed_jobs.rb +0 -9
  302. data/db/migrate/20130303053932_remove_filter_from_localizations.rb +0 -9
  303. data/db/migrate/20130303160632_remove_imagesets.rb +0 -22
  304. data/db/migrate/20130303161732_remove_sms_subscribers.rb +0 -14
  305. data/db/migrate/20130823133208_update_page_redirect_to.rb +0 -10
  306. data/db/migrate/20140203183900_create_roles.rb +0 -66
  307. data/db/migrate/20140414150500_change_locale_names.rb +0 -11
  308. data/db/migrate/20140604142100_remove_openid_url.rb +0 -9
  309. data/db/migrate/20140920231700_convert_images_to_dis.rb +0 -81
  310. data/db/migrate/20140922124600_convert_page_files_to_dis.rb +0 -50
  311. data/db/migrate/20141004003100_create_password_reset_tokens.rb +0 -10
  312. data/db/migrate/20141006181300_remove_user_cruft.rb +0 -11
  313. data/db/migrate/20141007173000_create_invites.rb +0 -16
  314. data/db/migrate/20150204130800_update_delayed_job_table.rb +0 -9
  315. data/db/migrate/20150401131300_localize_images.rb +0 -38
  316. data/db/migrate/20150520174300_add_meta_image_to_page.rb +0 -5
  317. data/db/migrate/20150904164200_add_pinned_to_tags.rb +0 -5
  318. data/db/migrate/20151002174800_create_page_paths.rb +0 -10
  319. data/db/migrate/20151021103400_drop_binaries_table.rb +0 -7
  320. data/db/migrate/20151204151000_remove_page_content_order.rb +0 -5
  321. data/db/migrate/20160330220900_rename_pages_categories.rb +0 -6
  322. data/db/migrate/20160405202700_change_localization_limit.rb +0 -9
  323. data/db/migrate/20170716040500_remove_page_comments.rb +0 -23
  324. data/db/migrate/20170716213400_remove_sessions.rb +0 -15
  325. data/db/migrate/20180207134000_add_dates_to_pages.rb +0 -11
  326. data/db/migrate/20190211154800_create_attachments.rb +0 -73
  327. data/db/migrate/20190318115000_fix_page_file_ids.rb +0 -34
  328. data/lib/rails/generators/pages_core/frontend/templates/application.js.erb +0 -15
  329. data/lib/rails/generators/pages_core/install/templates/cache_sweeper_initializer.rb +0 -6
  330. data/lib/tasks/pages/update.rake +0 -17
  331. data/vendor/assets/javascripts/ReactCrop.min.js +0 -1
  332. data/vendor/assets/javascripts/reflux.min.js +0 -1
@@ -1,55 +1,56 @@
1
1
  /*
2
- Based on
3
-
4
- js-tree by Wang Zuo
5
- https://github.com/wangzuo/js-tree
6
-
7
- react-ui-tree
8
- https://github.com/pqx/react-ui-tree
9
-
10
- The MIT License (MIT)
11
-
12
- Copyright (c) 2015 Wang Zuo
13
-
14
- Permission is hereby granted, free of charge, to any person obtaining a copy
15
- of this software and associated documentation files (the "Software"), to deal
16
- in the Software without restriction, including without limitation the rights
17
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
- copies of the Software, and to permit persons to whom the Software is
19
- furnished to do so, subject to the following conditions:
20
-
21
- The above copyright notice and this permission notice shall be included in
22
- all copies or substantial portions of the Software.
23
-
24
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
- SOFTWARE.
31
-
32
- Copyright (c) 2015 pqx Limited
33
-
34
- Permission is hereby granted, free of charge, to any person obtaining a copy
35
- of this software and associated documentation files (the "Software"), to deal
36
- in the Software without restriction, including without limitation the rights
37
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
- copies of the Software, and to permit persons to whom the Software is
39
- furnished to do so, subject to the following conditions:
40
-
41
- The above copyright notice and this permission notice shall be included in
42
- all copies or substantial portions of the Software.
43
-
44
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50
- SOFTWARE.
51
- */
52
- class Tree {
2
+ Based on
3
+
4
+ js-tree by Wang Zuo
5
+ https://github.com/wangzuo/js-tree
6
+
7
+ react-ui-tree
8
+ https://github.com/pqx/react-ui-tree
9
+
10
+ The MIT License (MIT)
11
+
12
+ Copyright (c) 2015 Wang Zuo
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in
22
+ all copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+
32
+ Copyright (c) 2015 pqx Limited
33
+
34
+ Permission is hereby granted, free of charge, to any person obtaining a copy
35
+ of this software and associated documentation files (the "Software"), to deal
36
+ in the Software without restriction, including without limitation the rights
37
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38
+ copies of the Software, and to permit persons to whom the Software is
39
+ furnished to do so, subject to the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be included in
42
+ all copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50
+ SOFTWARE.
51
+ */
52
+
53
+ export default class Tree {
53
54
  constructor(obj) {
54
55
  this.cnt = 1;
55
56
  this.obj = obj || { children: [] };
@@ -63,7 +64,7 @@ class Tree {
63
64
  var self = this;
64
65
 
65
66
  var index = { id: startId, node: obj };
66
- indexes[this.cnt + ''] = index;
67
+ indexes[this.cnt + ""] = index;
67
68
  this.cnt++;
68
69
 
69
70
  if (obj.children && obj.children.length) {
@@ -72,7 +73,7 @@ class Tree {
72
73
 
73
74
  function walk(objs, parent) {
74
75
  var children = [];
75
- objs.forEach(function(obj, i) {
76
+ objs.forEach(function(obj) {
76
77
  var index = {};
77
78
  index.id = self.cnt;
78
79
  index.node = obj;
@@ -81,7 +82,7 @@ class Tree {
81
82
  index.parent = parent.id;
82
83
  }
83
84
 
84
- indexes[self.cnt + ''] = index;
85
+ indexes[self.cnt + ""] = index;
85
86
  children.push(self.cnt);
86
87
  self.cnt++;
87
88
 
@@ -92,7 +93,7 @@ class Tree {
92
93
  parent.children = children;
93
94
 
94
95
  children.forEach(function(id, i) {
95
- var index = indexes[id + ''];
96
+ var index = indexes[id + ""];
96
97
  if (i > 0) {
97
98
  index.prev = children[i - 1];
98
99
  }
@@ -106,7 +107,7 @@ class Tree {
106
107
  }
107
108
 
108
109
  getIndex(id) {
109
- var index = this.indexes[id + ''];
110
+ var index = this.indexes[id + ""];
110
111
  if (index) {
111
112
  return index;
112
113
  }
@@ -117,7 +118,7 @@ class Tree {
117
118
  del(index);
118
119
 
119
120
  function del(index) {
120
- delete self.indexes[index.id + ''];
121
+ delete self.indexes[index.id + ""];
121
122
  if (index.children && index.children.length) {
122
123
  index.children.forEach(function(child) {
123
124
  del(self.getIndex(child));
@@ -259,13 +260,13 @@ class Tree {
259
260
  var obj = this.remove(fromId);
260
261
  var index = null;
261
262
 
262
- if (placement === 'before') {
263
+ if (placement === "before") {
263
264
  index = this.insertBefore(obj, toId);
264
- } else if (placement === 'after') {
265
+ } else if (placement === "after") {
265
266
  index = this.insertAfter(obj, toId);
266
- } else if(placement === 'prepend') {
267
+ } else if(placement === "prepend") {
267
268
  index = this.prepend(obj, toId);
268
- } else if(placement === 'append') {
269
+ } else if(placement === "append") {
269
270
  index = this.append(obj, toId);
270
271
  }
271
272
 
@@ -276,7 +277,7 @@ class Tree {
276
277
 
277
278
  getParent(id) {
278
279
  var indexes = this.indexes;
279
- if (indexes.hasOwnProperty(id)) {
280
+ if (Object.prototype.hasOwnProperty.call(indexes, id)) {
280
281
  return this.getIndex(indexes[id].parent);
281
282
  }
282
283
  }
@@ -284,7 +285,7 @@ class Tree {
284
285
  getNodeByTop(top) {
285
286
  var indexes = this.indexes;
286
287
  for(var id in indexes) {
287
- if (indexes.hasOwnProperty(id)) {
288
+ if (Object.prototype.hasOwnProperty.call(indexes, id)) {
288
289
  if(indexes[id].top === top) {
289
290
  return indexes[id];
290
291
  }
@@ -0,0 +1,13 @@
1
+ export function copySupported () {
2
+ return document.queryCommandSupported &&
3
+ document.queryCommandSupported("copy");
4
+ }
5
+
6
+ export default function copyToClipboard (str) {
7
+ const el = document.createElement("textarea");
8
+ el.value = str;
9
+ document.body.appendChild(el);
10
+ el.select();
11
+ document.execCommand("copy");
12
+ document.body.removeChild(el);
13
+ }
@@ -0,0 +1,22 @@
1
+ let readyHandlers = [];
2
+
3
+ const handleState = () => {
4
+ if (["interactive", "complete"].indexOf(document.readyState) > -1) {
5
+ while(readyHandlers.length > 0) {
6
+ (readyHandlers.shift())();
7
+ }
8
+ }
9
+ };
10
+
11
+ class ReadyHandler {
12
+ constructor () {
13
+ document.onreadystatechange = handleState;
14
+ }
15
+
16
+ ready (handler) {
17
+ readyHandlers.push(handler);
18
+ handleState();
19
+ }
20
+ }
21
+
22
+ export default new ReadyHandler();
@@ -0,0 +1,36 @@
1
+ export function csrfToken() {
2
+ return document.querySelector("[name=csrf-token]").content;
3
+ }
4
+
5
+ function jsonFetchOptions() {
6
+ return({ method: "POST",
7
+ headers: { "Content-Type": "application/json; charset=utf-8",
8
+ "X-CSRF-Token": csrfToken() } });
9
+ }
10
+
11
+ export async function postJson(url, data) {
12
+ const options = { ...jsonFetchOptions(), method: "POST" };
13
+ if (data) {
14
+ options.body = JSON.stringify(data);
15
+ }
16
+ const response = await fetch(url, options);
17
+ return response.json();
18
+ }
19
+
20
+ export async function putJson(url, data) {
21
+ const options = { ...jsonFetchOptions(), method: "PUT" };
22
+ if (data) {
23
+ options.body = JSON.stringify(data);
24
+ }
25
+ const response = await fetch(url, options);
26
+ return response.json();
27
+ }
28
+
29
+ export async function post(url, data) {
30
+ const response = await fetch(url, {
31
+ method: "POST",
32
+ body: data,
33
+ headers: { "X-CSRF-Token": csrfToken() }
34
+ });
35
+ return response.json();
36
+ }
@@ -0,0 +1,12 @@
1
+ import { createStore } from "redux";
2
+
3
+ export default createStore((state = {}, action) => {
4
+ switch(action.type) {
5
+ case "OPEN":
6
+ return {...state, component: action.payload };
7
+ case "CLOSE":
8
+ return {...state, component: null };
9
+ default:
10
+ return state;
11
+ }
12
+ });
@@ -0,0 +1,14 @@
1
+ import { createStore } from "redux";
2
+
3
+ export default createStore((state = [], action) => {
4
+ switch(action.type) {
5
+ case "ERROR":
6
+ return [...state, { message: action.message, type: "error" }];
7
+ case "NOTICE":
8
+ return [...state, { message: action.message, type: "notice" }];
9
+ case "NEXT":
10
+ return state.slice(1);
11
+ default:
12
+ return state;
13
+ }
14
+ });
@@ -0,0 +1,2 @@
1
+ export { default as ModalStore } from "./stores/ModalStore";
2
+ export { default as ToastStore } from "./stores/ToastStore";
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
- class AutopublishJob < ActiveJob::Base
4
+ class AutopublishJob < ApplicationJob
3
5
  queue_as :pages_core
4
6
 
5
7
  def perform
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
- class SweepCacheJob < ActiveJob::Base
4
+ class SweepCacheJob < ApplicationJob
3
5
  queue_as :pages_core
4
6
 
5
7
  def perform
6
- PagesCore::CacheSweeper.sweep!
8
+ PagesCore::StaticCache.handler.sweep_now!
7
9
  end
8
10
  end
9
11
  end
@@ -1,17 +1,7 @@
1
- class AdminMailer < ActionMailer::Base
2
- default from: proc { "\"Pages\" <support@anyone.no>" }
1
+ # frozen_string_literal: true
3
2
 
4
- def error_report(error_report, from, description)
5
- @error_report = error_report
6
- @from = from
7
- @description = description
8
- short_message = @error_report[:message].gsub(/[\s\n]+/, " ")[0..80]
9
- mail(
10
- to: "system+error@anyone.no",
11
- from: "\"Error reports\" <system+error@anyone.no>",
12
- subject: "[#{PagesCore.config(:site_name)}] Error: #{short_message}"
13
- )
14
- end
3
+ class AdminMailer < ApplicationMailer
4
+ default from: proc { "\"Pages\" <support@anyone.no>" }
15
5
 
16
6
  def password_reset(user, url)
17
7
  @user = user
@@ -26,7 +16,7 @@ class AdminMailer < ActionMailer::Base
26
16
  @invite = invite
27
17
  @url = url
28
18
  mail(
29
- to: @invite.email,
19
+ to: @invite.email,
30
20
  subject: "#{PagesCore.config(:site_name)} has invited you to Pages"
31
21
  )
32
22
  end
@@ -1,4 +1,6 @@
1
- class Attachment < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class Attachment < ApplicationRecord
2
4
  include Dis::Model
3
5
  include PagesCore::Sweepable
4
6
 
@@ -25,12 +27,12 @@ class Attachment < ActiveRecord::Base
25
27
 
26
28
  def formats
27
29
  {
28
- "audio/mpeg" => :mp3,
29
- "image/gif" => :gif,
30
- "image/jpeg" => :jpg,
31
- "image/jpg" => :jpg,
32
- "image/pjpeg" => :jpg,
33
- "image/png" => :png,
30
+ "audio/mpeg" => :mp3,
31
+ "image/gif" => :gif,
32
+ "image/jpeg" => :jpg,
33
+ "image/jpg" => :jpg,
34
+ "image/pjpeg" => :jpg,
35
+ "image/png" => :png,
34
36
  "application/pdf" => :pdf
35
37
  }
36
38
  end
@@ -52,7 +54,7 @@ class Attachment < ActiveRecord::Base
52
54
 
53
55
  def filename_extension
54
56
  if filename_extension?
55
- filename.match(/\.([^\.]+)$/)[1]
57
+ filename.match(/\.([^.]+)$/)[1]
56
58
  else
57
59
  ""
58
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Autopublisher
2
4
  class << self
3
5
  def run!(_options = {})
@@ -13,6 +15,7 @@ class Autopublisher
13
15
 
14
16
  def queue!
15
17
  return unless queued_pages.any?
18
+
16
19
  PagesCore::AutopublishJob
17
20
  .set(wait_until: queued_pages.first.published_at)
18
21
  .perform_later
@@ -1,4 +1,6 @@
1
- class Category < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class Category < ApplicationRecord
2
4
  has_many :page_categories, dependent: :destroy
3
5
  has_many :pages, through: :page_categories
4
6
  validates :name, presence: true
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module HasRoles
3
5
  extend ActiveSupport::Concern
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module HumanizableParam
3
5
  include ActiveSupport::Inflector
4
6
  extend ActiveSupport::Concern
5
7
 
6
8
  def humanized_param(slug)
7
- return id.to_s unless slug && slug.present?
9
+ return id.to_s unless slug&.present?
10
+
8
11
  "#{id}-" + transliterate(slug)
9
12
  .downcase
10
- .gsub(/[\[\{]/, "(")
11
- .gsub(/[\]\}]/, ")")
12
- .gsub(/[^[[:alnum:]]()\-]+/, "-")
13
- .gsub(/[\-]{2,}/, "-")
14
- .gsub(/(^\-|\-$)/, "")
13
+ .gsub(/[\[{]/, "(")
14
+ .gsub(/}\]/, ")")
15
+ .gsub(/[^[[:alnum:]]()-]+/, "-")
16
+ .gsub(/-{2,}/, "-")
17
+ .gsub(/(^-|-$)/, "")
15
18
  end
16
19
  end
17
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Attachments
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Autopublishable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module DatedPage
@@ -14,25 +16,21 @@ module PagesCore
14
16
  module ClassMethods
15
17
  end
16
18
 
17
- # Finds the page's next sibling by date. Returns nil if there isn't one.
19
+ # Finds the page's next sibling by date. Returns nil if there
20
+ # isn't one.
18
21
  def next_sibling_by_date
19
- siblings = siblings_by_date
20
- return unless siblings.any?
21
-
22
- siblings[(siblings.to_a.index(self) + 1)...siblings.length]
23
- .try(&:first)
22
+ siblings_by_date.where("starts_at >= ?", starts_at)&.first
24
23
  end
25
24
 
26
- # Finds the page's previous sibling by date. Returns nil if there isn't one.
25
+ # Finds the page's previous sibling by date. Returns nil if
26
+ # there isn't one.
27
27
  def previous_sibling_by_date
28
- siblings = siblings_by_date
29
- return unless siblings.any?
30
-
31
- siblings[0...siblings.to_a.index(self)].try(&:last)
28
+ siblings_by_date.where("starts_at < ?", starts_at)&.last
32
29
  end
33
30
 
34
31
  def upcoming?
35
32
  return false unless ends_at?
33
+
36
34
  ends_at > Time.zone.now
37
35
  end
38
36
 
@@ -53,6 +51,8 @@ module PagesCore
53
51
 
54
52
  def siblings_by_date
55
53
  siblings.reorder("starts_at ASC, pages.id DESC")
54
+ .where
55
+ .not(id: id)
56
56
  end
57
57
  end
58
58
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Images
@@ -6,7 +8,9 @@ module PagesCore
6
8
  included do
7
9
  belongs_to_image :image, optional: true
8
10
  belongs_to_image :meta_image, class_name: "Image", optional: true
9
- has_many :page_images, -> { order("position") }, inverse_of: :page
11
+ has_many :page_images, -> { order("position") },
12
+ inverse_of: :page,
13
+ dependent: :destroy
10
14
  has_many(
11
15
  :images,
12
16
  -> { where(page_images: { primary: false }).order("position") },
@@ -16,7 +20,9 @@ module PagesCore
16
20
  after_save :update_primary_image
17
21
 
18
22
  accepts_nested_attributes_for :page_images,
19
- reject_if: proc { |a| a["image_id"].blank? },
23
+ reject_if: proc { |a|
24
+ a["image_id"].blank?
25
+ },
20
26
  allow_destroy: true
21
27
  end
22
28
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Localizable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Pathable
@@ -6,43 +8,32 @@ module PagesCore
6
8
  included do
7
9
  has_many :page_paths, dependent: :destroy
8
10
 
9
- validates :path_segment, format: { with: /\A[[[:alnum:]]\-_]*\z/ }
11
+ validates :path_segment, format: { with: /\A[[[:alnum:]]-_]*\z/ }
10
12
  validate :path_segment_cannot_be_routable
11
13
  before_validation :ensure_no_path_segment_on_deletion
12
14
  after_save :ensure_path_segment
13
15
  after_save :associate_page_path
14
16
  end
15
17
 
16
- def full_path(last_segment = nil)
17
- last_segment ||= path_segment
18
- return nil unless full_path?(last_segment)
19
- if parent
20
- [parent.full_path, last_segment].join("/")
21
- else
22
- last_segment
23
- end
18
+ def full_path
19
+ generate_full_path
24
20
  end
25
21
 
26
- def full_path?(last_segment = nil)
27
- last_segment ||= path_segment
28
- if parent
29
- parent.full_path? && last_segment.present?
30
- else
31
- last_segment.present?
32
- end
22
+ def full_path?
23
+ path_segment.present? && pathable?
33
24
  end
34
25
 
35
26
  def ensure_path_segment
36
27
  return if deleted? || path_segment? || !name?
37
- if path_collision?(generated_path_segment)
38
- update path_segment: "#{generated_path_segment}-#{id}"
39
- else
40
- update path_segment: generated_path_segment
41
- end
28
+
29
+ segment = generated_path_segment
30
+ segment = "#{segment}-#{id}" if path_collision?(segment)
31
+ update(path_segment: segment)
42
32
  end
43
33
 
44
34
  def pathable?
45
35
  return true unless parent
36
+
46
37
  parent.full_path?
47
38
  end
48
39
 
@@ -50,18 +41,27 @@ module PagesCore
50
41
 
51
42
  def associate_page_path
52
43
  return if deleted? || !full_path?
44
+
53
45
  PagePath.build(self)
54
46
  end
55
47
 
56
48
  def ensure_no_path_segment_on_deletion
57
49
  return unless deleted?
50
+
58
51
  self.path_segment = nil
59
52
  end
60
53
 
54
+ def generate_full_path(last_segment = nil)
55
+ last_segment ||= path_segment
56
+ return nil unless last_segment.present? && pathable?
57
+
58
+ [parent&.full_path, last_segment].compact.join("/")
59
+ end
60
+
61
61
  def generated_path_segment
62
- transliterated_name.gsub(/[^[[:alnum:]]\-_]+/, "-")
63
- .gsub(/[\-]{2,}/, "-")
64
- .gsub(/(^\-|\-$)/, "")
62
+ transliterated_name.gsub(/[^[[:alnum:]]-_]+/, "-")
63
+ .gsub(/-{2,}/, "-")
64
+ .gsub(/(^-|-$)/, "")
65
65
  .mb_chars
66
66
  .downcase
67
67
  end
@@ -81,12 +81,13 @@ module PagesCore
81
81
 
82
82
  def path_collision?(path_segment)
83
83
  sibling_path_segments.include?(path_segment) ||
84
- page_path_matches_routes?(full_path(path_segment))
84
+ page_path_matches_routes?(generate_full_path(path_segment))
85
85
  end
86
86
 
87
87
  def path_segment_cannot_be_routable
88
88
  return unless full_path?
89
89
  return unless page_path_matches_routes?(full_path)
90
+
90
91
  errors.add(:path_segment, "can't match an existing URL")
91
92
  end
92
93