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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  class InvalidRedirectUrl < StandardError; end
@@ -8,7 +10,6 @@ module PagesCore
8
10
  included do
9
11
  validates(:redirect_to,
10
12
  format: { with: %r{\A(/|https?://).+\z},
11
- allow_nil: true,
12
13
  allow_blank: true })
13
14
  end
14
15
 
@@ -24,6 +25,7 @@ module PagesCore
24
25
  unless value.is_a?(String) || value.is_a?(Symbol)
25
26
  raise InvalidRedirectUrl, "must be a string or a symbol"
26
27
  end
28
+
27
29
  path.gsub!("/:#{key}", "/#{value}")
28
30
  end
29
31
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PagesCore
4
+ module PageModel
5
+ module Searchable
6
+ extend ActiveSupport::Concern
7
+
8
+ def search_document_attributes
9
+ super.merge(
10
+ published: published?,
11
+ name: name,
12
+ description: try(&:meta_description?) ? meta_description : excerpt,
13
+ # content: "",
14
+ tags: tag_names.join(" ")
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Sortable
@@ -12,13 +14,12 @@ module PagesCore
12
14
  def order_by_tags(tags)
13
15
  joins(
14
16
  "LEFT JOIN taggings ON taggings.taggable_id = pages.id AND " \
15
- "taggable_type = #{ActiveRecord::Base.connection.quote('Page')}",
16
- "LEFT JOIN tags ON tags.id = taggings.tag_id AND tags.id IN (" +
17
- tags.map(&:id).join(",") +
18
- ")"
17
+ "taggings.tag_id IN (#{tags.map(&:id).join(',')}) AND " \
18
+ "taggings.taggable_type = " \
19
+ "#{ActiveRecord::Base.connection.quote('Page')}"
19
20
  )
20
21
  .group("pages.id, localizations.id")
21
- .reorder(Arel.sql("COUNT(tags.id) DESC, position ASC"))
22
+ .reorder(Arel.sql("COUNT(taggings.id) DESC"))
22
23
  end
23
24
  end
24
25
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Status
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Templateable
@@ -13,6 +15,7 @@ module PagesCore
13
15
 
14
16
  def template
15
17
  return self[:template] if self[:template].present?
18
+
16
19
  inherited_or_default_template
17
20
  end
18
21
 
@@ -29,15 +32,16 @@ module PagesCore
29
32
  def singularized_subtemplate
30
33
  singularized = ActiveSupport::Inflector.singularize(base_template)
31
34
  return if base_template == singularized
35
+
32
36
  find_template_by_expression(
33
- Regexp.new("^" + Regexp.quote(singularized))
37
+ Regexp.new("^#{Regexp.quote(singularized)}")
34
38
  )
35
39
  end
36
40
 
37
41
  def subtemplate_with_postfix
38
42
  find_template_by_expression(
39
43
  Regexp.new(
40
- "^" + Regexp.quote(base_template) + "_?(post|page|subpage|item)"
44
+ "^#{Regexp.quote(base_template)}_?(post|page|subpage|item)"
41
45
  )
42
46
  )
43
47
  end
@@ -69,6 +73,7 @@ module PagesCore
69
73
 
70
74
  def inherited_or_default_template
71
75
  return parent.default_subtemplate.to_s if parent
76
+
72
77
  (default_template_options[:root] || default_template || :index).to_s
73
78
  end
74
79
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module PageModel
3
5
  module Tree
@@ -5,17 +7,17 @@ module PagesCore
5
7
 
6
8
  included do
7
9
  belongs_to :parent,
8
- class_name: "Page",
10
+ class_name: "Page",
9
11
  foreign_key: :parent_page_id,
10
- inverse_of: :children,
11
- optional: true,
12
- touch: true
12
+ inverse_of: :children,
13
+ optional: true,
14
+ touch: true
13
15
 
14
16
  has_many :children,
15
- class_name: "Page",
17
+ class_name: "Page",
16
18
  foreign_key: :parent_page_id,
17
- inverse_of: :parent,
18
- dependent: :destroy
19
+ inverse_of: :parent,
20
+ dependent: :destroy
19
21
 
20
22
  # This must be included after the belongs_to call in order
21
23
  # to override the .parent method.
@@ -26,19 +28,20 @@ module PagesCore
26
28
  def admin_list(locale)
27
29
  left_outer_joins(:parent)
28
30
  .where("pages.status < 4")
29
- .order(
30
- Arel.sql(
31
- <<-QUERY
32
- pages.parent_page_id,
33
- parents_pages.news_page,
34
- case when parents_pages.news_page
35
- then pages.pinned end desc,
36
- case when parents_pages.news_page
37
- then pages.published_at end desc,
38
- position asc
39
- QUERY
40
- )
41
- ).in_locale(locale)
31
+ .order(admin_list_order).in_locale(locale)
32
+ end
33
+
34
+ def admin_list_order
35
+ Arel.sql(
36
+ <<-QUERY
37
+ pages.parent_page_id, parents_pages.news_page,
38
+ case when parents_pages.news_page
39
+ then pages.pinned end desc,
40
+ case when parents_pages.news_page
41
+ then pages.published_at end desc,
42
+ position asc
43
+ QUERY
44
+ )
42
45
  end
43
46
 
44
47
  # Returns all root pages
@@ -66,17 +69,20 @@ module PagesCore
66
69
  # Returns all children, recursively
67
70
  def all_subpages
68
71
  return nil unless subpages.any?
72
+
69
73
  localized_subpages.map { |p| [p, p.all_subpages] }.flatten.compact
70
74
  end
71
75
 
72
76
  def localized_subpages
73
77
  return subpages unless locale?
78
+
74
79
  subpages.localized(locale)
75
80
  end
76
81
 
77
82
  # Finds the page's next sibling. Returns nil if there isn't one.
78
83
  def next_sibling
79
84
  return unless siblings.any?
85
+
80
86
  siblings[(siblings.to_a.index(self) + 1)...siblings.length]
81
87
  .try(&:first)
82
88
  end
@@ -94,6 +100,7 @@ module PagesCore
94
100
  # Finds the page's next sibling. Returns nil if there isn't one.
95
101
  def previous_sibling
96
102
  return unless siblings.any?
103
+
97
104
  siblings[0...siblings.to_a.index(self)].try(&:last)
98
105
  end
99
106
 
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PagesCore
4
+ module SearchableDocument
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_many :search_documents, as: :searchable, dependent: :destroy
9
+ after_save :update_search_documents!
10
+ end
11
+
12
+ class Indexer
13
+ attr_reader :record
14
+
15
+ def initialize(record)
16
+ @record = record
17
+ end
18
+
19
+ class << self
20
+ def index_all!(scope)
21
+ scope.all.find_each { |r| new(r).index! }
22
+ end
23
+ end
24
+
25
+ def index!
26
+ SearchDocument.transaction do
27
+ record.search_documents.where.not(locale: locales).destroy_all
28
+ locales.each do |locale|
29
+ update_index(
30
+ locale,
31
+ localized_record(locale).search_document_attributes
32
+ )
33
+ end
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def locales
40
+ if record.respond_to?(:locales)
41
+ record.locales
42
+ elsif PagesCore.config.locales
43
+ PagesCore.config.locales.keys
44
+ else
45
+ [I18n.default_locale]
46
+ end
47
+ end
48
+
49
+ def localized_record(locale)
50
+ return record unless record.respond_to?(:localize)
51
+
52
+ record.localize(locale)
53
+ end
54
+
55
+ def update_index(locale, attrs)
56
+ record.search_documents.create_or_find_by!(locale: locale).update(attrs)
57
+ end
58
+ end
59
+
60
+ def search_document_attributes
61
+ return {} unless respond_to?(:localized_attributes)
62
+
63
+ content = localized_attributes.keys.map { |a| localizer.get(a) }.join(" ")
64
+ { content: content }
65
+ end
66
+
67
+ def update_search_documents!
68
+ PagesCore::SearchableDocument::Indexer.new(self).index!
69
+ end
70
+ end
71
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module Sweepable
3
5
  extend ActiveSupport::Concern
@@ -12,9 +14,9 @@ module PagesCore
12
14
  protected
13
15
 
14
16
  def sweep_cache!
15
- return unless PagesCore::CacheSweeper.enabled
16
17
  return if cache_swept
17
- PagesCore::SweepCacheJob.perform_later
18
+
19
+ PagesCore::StaticCache.handler.sweep!
18
20
  self.cache_swept = true
19
21
  end
20
22
  end
@@ -1,26 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PagesCore
2
4
  module Taggable
3
5
  extend ActiveSupport::Concern
4
6
 
7
+ attr_accessor :new_tags
8
+
5
9
  included do
6
10
  has_many :taggings,
7
11
  as: :taggable,
8
12
  dependent: :destroy,
9
13
  inverse_of: :taggable
10
14
  has_many :tags, through: :taggings
15
+ after_save :update_taggings
11
16
  end
12
17
 
13
18
  module ClassMethods
14
19
  def tagged_with(*tags)
15
- all
16
- .includes(:tags)
17
- .where("tags.name IN (?)", Tag.parse(tags))
18
- .references(:tags)
20
+ all.includes(:tags)
21
+ .where(tags: { name: Tag.parse(tags) })
22
+ .references(:tags)
19
23
  end
20
24
  end
21
25
 
22
26
  def serialized_tags
23
- tags.order("name ASC").map(&:name).to_json
27
+ tag_names.to_json
24
28
  end
25
29
 
26
30
  def serialized_tags=(json)
@@ -28,12 +32,11 @@ module PagesCore
28
32
  end
29
33
 
30
34
  def tag_with(*list)
31
- Tag.transaction do
32
- taggings.destroy_all
33
- Tag.parse(list).each do |name|
34
- Tag.find_or_create_by(name: name).on(self)
35
- end
36
- end
35
+ @new_tags = Tag.parse(list)
36
+ end
37
+
38
+ def tag_with!(*list)
39
+ update(tag_list: list)
37
40
  end
38
41
 
39
42
  def tag_list=(tag_list)
@@ -41,7 +44,25 @@ module PagesCore
41
44
  end
42
45
 
43
46
  def tag_list
44
- tags.order("name ASC").map(&:name).join(", ")
47
+ tag_names.join(", ")
48
+ end
49
+
50
+ def tag_names
51
+ @new_tags || tags.by_name.map(&:name)
52
+ end
53
+
54
+ private
55
+
56
+ def update_taggings
57
+ return unless new_tags
58
+
59
+ Tag.transaction do
60
+ taggings.includes(:tag).where.not(tag: { name: new_tags }).destroy_all
61
+ new_tags.map { |n| Tag.find_or_create_by(name: n) }
62
+ .each { |t| taggings.create(tag: t) }
63
+ end
64
+
65
+ @new_tags = nil
45
66
  end
46
67
  end
47
68
  end
data/app/models/image.rb CHANGED
@@ -1,7 +1,11 @@
1
- class Image < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class Image < ApplicationRecord
2
4
  include DynamicImage::Model
3
5
  include PagesCore::Sweepable
4
6
 
7
+ validate :ensure_max_size, on: :create
8
+
5
9
  localizable do
6
10
  attribute :alternative
7
11
  attribute :caption
@@ -21,4 +25,13 @@ class Image < ActiveRecord::Base
21
25
  ActiveSupport::Deprecation.warn "Image#byline= is deprecated, use #caption="
22
26
  self.caption = new_caption
23
27
  end
28
+
29
+ private
30
+
31
+ def ensure_max_size
32
+ return unless real_width? && real_height?
33
+ return if real_width * real_height <= 48_000_000
34
+
35
+ errors.add(:data, "is too large")
36
+ end
24
37
  end
data/app/models/invite.rb CHANGED
@@ -1,4 +1,6 @@
1
- class Invite < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class Invite < ApplicationRecord
2
4
  include PagesCore::HasRoles
3
5
 
4
6
  belongs_to :user
@@ -1,9 +1,11 @@
1
- class InviteRole < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class InviteRole < ApplicationRecord
2
4
  belongs_to :invite
3
5
  validates :name,
4
- presence: true,
6
+ presence: true,
5
7
  uniqueness: { scope: :invite_id },
6
- inclusion: { in: proc { Role.roles.map(&:name) } }
8
+ inclusion: { in: proc { Role.roles.map(&:name) } }
7
9
 
8
10
  def to_s
9
11
  name.humanize
data/app/models/page.rb CHANGED
@@ -1,5 +1,8 @@
1
- class Page < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class Page < ApplicationRecord
2
4
  include PagesCore::HumanizableParam
5
+ include PagesCore::SearchableDocument
3
6
  include PagesCore::Sweepable
4
7
  include PagesCore::Taggable
5
8
 
@@ -10,6 +13,7 @@ class Page < ActiveRecord::Base
10
13
  include PagesCore::PageModel::Localizable
11
14
  include PagesCore::PageModel::Pathable
12
15
  include PagesCore::PageModel::Redirectable
16
+ include PagesCore::PageModel::Searchable
13
17
  include PagesCore::PageModel::Sortable
14
18
  include PagesCore::PageModel::Status
15
19
  include PagesCore::PageModel::Tree
@@ -26,9 +30,8 @@ class Page < ActiveRecord::Base
26
30
 
27
31
  validates(:unique_name,
28
32
  format: { with: /\A[\w\d_\-]+\z/,
29
- allow_nil: true,
30
33
  allow_blank: true },
31
- uniqueness: { allow_nil: true, allow_blank: true })
34
+ uniqueness: { allow_blank: true })
32
35
 
33
36
  validates :template, presence: true
34
37
  validates :published_at, presence: true
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # # PageBuilder
2
4
  #
3
5
  # PageBuilder is a simple DSL for building pages, for use in ie. seeds.rb
@@ -1,4 +1,6 @@
1
- class PageCategory < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class PageCategory < ApplicationRecord
2
4
  belongs_to :page
3
5
  belongs_to :category
4
6
  validates :page_id, :category_id, presence: true
@@ -1,21 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "fileutils"
2
4
 
3
5
  class PageExporter
4
- attr_reader :base_dir
6
+ attr_reader :base_dir, :progress_bar
5
7
 
6
- def initialize(base_dir)
8
+ def initialize(base_dir, progress_bar: false)
7
9
  @base_dir = base_dir
10
+ @progress_bar = progress_bar
8
11
  end
9
12
 
10
13
  def export
11
14
  Page.roots.in_locale(I18n.default_locale).each { |p| export_page(p) }
12
- puts
13
15
  end
14
16
 
15
17
  private
16
18
 
19
+ def bar
20
+ @bar ||= ProgressBar.new(Page.count)
21
+ end
22
+
17
23
  def export_page(page)
18
- print "."
24
+ bar.increment! if progress_bar
19
25
  export_page_contents(page)
20
26
  export_images(page)
21
27
  export_files(page)
@@ -23,7 +29,7 @@ class PageExporter
23
29
  end
24
30
 
25
31
  def export_files(page)
26
- path = page_path(page).join("files")
32
+ path = page_path(page).join("attachments")
27
33
  page.attachments.each do |file|
28
34
  write_file(
29
35
  path.join([file.content_hash, file.filename].join("-")),
@@ -44,15 +50,22 @@ class PageExporter
44
50
 
45
51
  def export_page_contents(page)
46
52
  path = page_path(page)
47
- page.locales.map { |l| page.localize(l) }.each do |p|
48
- json = PageExportSerializer.new(p).to_json
49
- basename = path.join("#{page_file_name(p)}.#{p.locale}")
50
- write_file(path.join("page.#{p.locale}.json"), json)
51
- write_file(path.join("page.#{p.locale}.yml"), JSON.parse(json).to_yaml)
53
+ localized_pages(page).each do |p|
54
+ export_page_json(path, page)
52
55
  write_file(path.join("page.#{p.locale}.txt"), text_page(p))
53
56
  end
54
57
  end
55
58
 
59
+ def export_page_json(path, page)
60
+ json = Export::PageResource.new(page).serialize
61
+ write_file(path.join("page.#{page.locale}.json"), json)
62
+ write_file(path.join("page.#{page.locale}.yml"), JSON.parse(json).to_yaml)
63
+ end
64
+
65
+ def localized_pages(page)
66
+ page.locales.map { |l| page.localize(l) }
67
+ end
68
+
56
69
  def page_path(page)
57
70
  base_dir.join(page.self_and_ancestors
58
71
  .reverse
@@ -1,4 +1,6 @@
1
- class PageFile < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class PageFile < ApplicationRecord
2
4
  include PagesCore::Sweepable
3
5
 
4
6
  belongs_to :page
@@ -1,11 +1,11 @@
1
- class PageImage < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class PageImage < ApplicationRecord
2
4
  include PagesCore::Sweepable
3
5
 
4
6
  belongs_to :page
5
7
  belongs_to_image :image
6
8
 
7
- validates :page_id, presence: true
8
-
9
9
  accepts_nested_attributes_for :image
10
10
  validates_associated :image
11
11
 
@@ -1,6 +1,10 @@
1
- class PagePath < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class PagePath < ApplicationRecord
2
4
  class PageNotSavedError < StandardError; end
5
+
3
6
  class NoPathError < StandardError; end
7
+
4
8
  class NoLocaleError < StandardError; end
5
9
 
6
10
  belongs_to :page
@@ -33,12 +37,16 @@ class PagePath < ActiveRecord::Base
33
37
  raise PageNotSavedError unless page.id?
34
38
  raise NoLocaleError unless locale
35
39
  raise NoPathError unless path
36
- existing = get(locale, path)
37
40
 
38
- return create(locale: locale, path: path, page: page) unless existing
41
+ page_path = get_or_create(locale, path, page)
42
+ page_path.update(page: page) unless page_path.page_id == page.id
43
+ page_path
44
+ end
45
+
46
+ private
39
47
 
40
- existing.update(page: page) unless existing.page_id == page.id
41
- existing
48
+ def get_or_create(locale, path, page)
49
+ get(locale, path) || create(locale: locale, path: path, page: page)
42
50
  end
43
51
  end
44
52
  end
@@ -1,4 +1,6 @@
1
- class PasswordResetToken < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class PasswordResetToken < ApplicationRecord
2
4
  belongs_to :user
3
5
  before_create :ensure_token
4
6
  before_create :ensure_expiration
data/app/models/role.rb CHANGED
@@ -1,15 +1,17 @@
1
- class Role < ActiveRecord::Base
1
+ # frozen_string_literal: true
2
+
3
+ class Role < ApplicationRecord
2
4
  belongs_to :user, touch: true
3
5
  validates :name,
4
- presence: true,
6
+ presence: true,
5
7
  uniqueness: { scope: :user_id },
6
- inclusion: { in: proc { Role.roles.map(&:name) } }
8
+ inclusion: { in: proc { Role.roles.map(&:name) } }
7
9
 
8
10
  class << self
9
- def define(name, description, default = false)
11
+ def define(name, description, default: false)
10
12
  if roles.map(&:name).include?(name.to_s)
11
13
  raise ArgumentError, "Tried to define role :#{role}, " \
12
- "but a role by that name already exists"
14
+ "but a role by that name already exists"
13
15
  else
14
16
  roles << OpenStruct.new(
15
17
  name: name.to_s,
@@ -30,11 +32,12 @@ class Role < ActiveRecord::Base
30
32
  protected
31
33
 
32
34
  def config_file
33
- Rails.root.join("config", "roles.yml")
35
+ Rails.root.join("config/roles.yml")
34
36
  end
35
37
 
36
38
  def config_roles
37
39
  return [] unless File.exist?(config_file)
40
+
38
41
  YAML.load_file(config_file).map do |key, opts|
39
42
  OpenStruct.new(name: key.to_s,
40
43
  description: opts["description"],