wagtail 6.2.2__py3-none-any.whl → 6.3rc2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_for_translation.py +6 -0
  3. wagtail/actions/publish_revision.py +3 -3
  4. wagtail/admin/action_menu.py +5 -3
  5. wagtail/admin/forms/account.py +1 -1
  6. wagtail/admin/icons.py +2 -6
  7. wagtail/admin/locale/cy/LC_MESSAGES/django.mo +0 -0
  8. wagtail/admin/locale/cy/LC_MESSAGES/django.po +32 -0
  9. wagtail/admin/locale/dv/LC_MESSAGES/django.mo +0 -0
  10. wagtail/admin/locale/dv/LC_MESSAGES/django.po +28 -0
  11. wagtail/admin/locale/en/LC_MESSAGES/django.po +451 -485
  12. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +7 -7
  13. wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
  14. wagtail/admin/locale/sl/LC_MESSAGES/django.po +150 -0
  15. wagtail/admin/locale/sl/LC_MESSAGES/djangojs.mo +0 -0
  16. wagtail/admin/locale/sl/LC_MESSAGES/djangojs.po +9 -2
  17. wagtail/admin/locale/ug/LC_MESSAGES/django.mo +0 -0
  18. wagtail/admin/locale/ug/LC_MESSAGES/django.po +3250 -196
  19. wagtail/admin/localization.py +12 -2
  20. wagtail/admin/panels/model_utils.py +1 -1
  21. wagtail/admin/site_summary.py +0 -2
  22. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  23. wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
  24. wagtail/admin/static/wagtailadmin/images/email-header.jpg +0 -0
  25. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  26. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  27. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +12 -0
  28. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  29. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  30. wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
  31. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  32. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  33. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
  34. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  35. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  36. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  37. wagtail/admin/staticfiles.py +6 -4
  38. wagtail/admin/templates/wagtailadmin/account/account.html +42 -59
  39. wagtail/admin/templates/wagtailadmin/admin_base.html +0 -28
  40. wagtail/admin/templates/wagtailadmin/bulk_actions/footer.html +1 -1
  41. wagtail/admin/templates/wagtailadmin/chooser/_search_results.html +7 -5
  42. wagtail/admin/templates/wagtailadmin/chooser/tables/page_navigate_to_children_cell.html +1 -1
  43. wagtail/admin/templates/wagtailadmin/generic/chooser/results.html +7 -5
  44. wagtail/admin/templates/wagtailadmin/generic/edit.html +0 -8
  45. wagtail/admin/templates/wagtailadmin/generic/form.html +60 -17
  46. wagtail/admin/templates/wagtailadmin/generic/index.html +17 -0
  47. wagtail/admin/templates/wagtailadmin/generic/index_results.html +9 -35
  48. wagtail/admin/templates/wagtailadmin/generic/inspect.html +2 -21
  49. wagtail/admin/templates/wagtailadmin/generic/listing.html +11 -17
  50. wagtail/admin/templates/wagtailadmin/generic/listing_results.html +19 -1
  51. wagtail/admin/templates/wagtailadmin/home/account_summary.html +26 -0
  52. wagtail/admin/templates/wagtailadmin/home/locked_pages.html +28 -18
  53. wagtail/admin/templates/wagtailadmin/home/recent_edits.html +28 -17
  54. wagtail/admin/templates/wagtailadmin/home/site_summary_pages.html +2 -2
  55. wagtail/admin/templates/wagtailadmin/home/upgrade_notification.html +35 -13
  56. wagtail/admin/templates/wagtailadmin/home/user_objects_in_workflow_moderation.html +28 -18
  57. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +43 -32
  58. wagtail/admin/templates/wagtailadmin/home.html +22 -5
  59. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
  60. wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -11
  61. wagtail/admin/templates/wagtailadmin/pages/action_menu/menu_item.html +1 -6
  62. wagtail/admin/templates/wagtailadmin/pages/action_menu/page_locked.html +1 -1
  63. wagtail/admin/templates/wagtailadmin/pages/action_menu/publish.html +1 -1
  64. wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +1 -1
  65. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_delete.html +12 -6
  66. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_move.html +12 -7
  67. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_publish.html +17 -11
  68. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_unpublish.html +15 -9
  69. wagtail/admin/templates/wagtailadmin/pages/confirm_delete.html +9 -9
  70. wagtail/admin/templates/wagtailadmin/pages/confirm_move.html +2 -2
  71. wagtail/admin/templates/wagtailadmin/pages/confirm_unpublish.html +4 -4
  72. wagtail/admin/templates/wagtailadmin/pages/create.html +15 -34
  73. wagtail/admin/templates/wagtailadmin/pages/edit.html +15 -30
  74. wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +6 -0
  75. wagtail/admin/templates/wagtailadmin/pages/explorable_index_results.html +60 -0
  76. wagtail/admin/templates/wagtailadmin/pages/index.html +1 -36
  77. wagtail/admin/templates/wagtailadmin/pages/index_results.html +2 -50
  78. wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +1 -1
  79. wagtail/admin/templates/wagtailadmin/pages/listing/_ordering_cell.html +1 -1
  80. wagtail/admin/templates/wagtailadmin/pages/listing/_page_header_buttons.html +1 -1
  81. wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +3 -3
  82. wagtail/admin/templates/wagtailadmin/pages/listing/_pagination.html +1 -1
  83. wagtail/admin/templates/wagtailadmin/pages/listing.html +24 -0
  84. wagtail/admin/templates/wagtailadmin/pages/search.html +1 -20
  85. wagtail/admin/templates/wagtailadmin/pages/search_results.html +27 -25
  86. wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +0 -1
  87. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +2 -2
  88. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +6 -6
  89. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +1 -1
  90. wagtail/admin/templates/wagtailadmin/shared/action_menu/menu.html +14 -0
  91. wagtail/admin/templates/wagtailadmin/shared/action_menu/menu_item.html +6 -0
  92. wagtail/admin/templates/wagtailadmin/shared/avatar.html +13 -3
  93. wagtail/admin/templates/wagtailadmin/shared/header.html +0 -5
  94. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +1 -1
  95. wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +4 -1
  96. wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html +1 -1
  97. wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +1 -1
  98. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/locale.html +1 -1
  99. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/usage.html +2 -2
  100. wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +94 -52
  101. wagtail/admin/templates/wagtailadmin/{pages/_unsaved_changes_warning.html → shared/unsaved_changes_warning.html} +4 -4
  102. wagtail/admin/templates/wagtailadmin/shared/usage_summary.html +2 -2
  103. wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +1 -7
  104. wagtail/admin/templates/wagtailadmin/shared/workflow_history/listing.html +1 -0
  105. wagtail/admin/templates/wagtailadmin/shared/workflow_history/{list.html → listing_results.html} +33 -35
  106. wagtail/admin/templates/wagtailadmin/tables/references_cell.html +1 -1
  107. wagtail/admin/templates/wagtailadmin/workflows/create.html +11 -36
  108. wagtail/admin/templates/wagtailadmin/workflows/create_task.html +0 -38
  109. wagtail/admin/templates/wagtailadmin/workflows/edit.html +44 -74
  110. wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +27 -66
  111. wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -2
  112. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +4 -4
  113. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +15 -11
  114. wagtail/admin/templates/wagtailadmin/workflows/task_chooser/includes/results.html +7 -5
  115. wagtail/admin/templatetags/wagtailadmin_tags.py +51 -22
  116. wagtail/admin/tests/pages/test_content_type_use_view.py +82 -2
  117. wagtail/admin/tests/pages/test_edit_page.py +70 -0
  118. wagtail/admin/tests/pages/test_explorer_view.py +65 -4
  119. wagtail/admin/tests/pages/test_page_search.py +8 -7
  120. wagtail/admin/tests/pages/test_page_usage.py +3 -1
  121. wagtail/admin/tests/pages/test_preview.py +208 -63
  122. wagtail/admin/tests/pages/test_reorder_page.py +91 -1
  123. wagtail/admin/tests/pages/test_view_draft.py +32 -1
  124. wagtail/admin/tests/pages/test_workflow_history.py +288 -7
  125. wagtail/admin/tests/test_account_management.py +23 -3
  126. wagtail/admin/tests/test_audit_log.py +24 -2
  127. wagtail/admin/tests/test_collections_views.py +17 -5
  128. wagtail/admin/tests/test_dashboard.py +1 -1
  129. wagtail/admin/tests/test_edit_handlers.py +3 -2
  130. wagtail/admin/tests/test_icon_sprite.py +4 -0
  131. wagtail/admin/tests/test_privacy.py +5 -19
  132. wagtail/admin/tests/test_reports_views.py +1 -1
  133. wagtail/admin/tests/test_site_summary.py +3 -3
  134. wagtail/admin/tests/test_templatetags.py +27 -3
  135. wagtail/admin/tests/test_upgrade_notification.py +71 -18
  136. wagtail/admin/tests/test_views.py +2 -2
  137. wagtail/admin/tests/test_views_generic.py +13 -0
  138. wagtail/admin/tests/test_widgets.py +3 -3
  139. wagtail/admin/tests/test_workflows.py +172 -27
  140. wagtail/admin/tests/tests.py +1 -1
  141. wagtail/admin/tests/viewsets/test_model_viewset.py +55 -3
  142. wagtail/admin/ui/side_panels.py +19 -0
  143. wagtail/admin/ui/sidebar.py +4 -3
  144. wagtail/admin/ui/tables/__init__.py +14 -1
  145. wagtail/admin/ui/tables/pages.py +6 -1
  146. wagtail/admin/urls/pages.py +10 -1
  147. wagtail/admin/urls/workflows.py +6 -1
  148. wagtail/admin/views/account.py +5 -1
  149. wagtail/admin/views/collections.py +0 -2
  150. wagtail/admin/views/generic/base.py +118 -1
  151. wagtail/admin/views/generic/history.py +158 -26
  152. wagtail/admin/views/generic/models.py +113 -99
  153. wagtail/admin/views/home.py +24 -9
  154. wagtail/admin/views/page_privacy.py +54 -30
  155. wagtail/admin/views/pages/history.py +11 -4
  156. wagtail/admin/views/pages/listing.py +76 -89
  157. wagtail/admin/views/pages/preview.py +1 -1
  158. wagtail/admin/views/pages/search.py +27 -71
  159. wagtail/admin/views/pages/usage.py +63 -24
  160. wagtail/admin/views/pages/utils.py +4 -3
  161. wagtail/admin/views/reports/base.py +0 -6
  162. wagtail/admin/views/workflows.py +67 -25
  163. wagtail/admin/viewsets/model.py +4 -3
  164. wagtail/admin/widgets/chooser.py +2 -1
  165. wagtail/api/v2/tests/test_pages.py +15 -2
  166. wagtail/blocks/field_block.py +15 -3
  167. wagtail/blocks/static_block.py +3 -0
  168. wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.mo +0 -0
  169. wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.po +29 -1
  170. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +15 -11
  171. wagtail/contrib/forms/templates/wagtailforms/confirm_delete.html +1 -0
  172. wagtail/contrib/forms/templates/wagtailforms/index.html +1 -1
  173. wagtail/contrib/forms/templates/wagtailforms/index_results.html +1 -1
  174. wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +2 -1
  175. wagtail/contrib/forms/templates/wagtailforms/panels/form_responses_panel.html +2 -2
  176. wagtail/contrib/forms/tests/test_views.py +234 -35
  177. wagtail/contrib/forms/utils.py +8 -14
  178. wagtail/contrib/forms/views.py +72 -27
  179. wagtail/contrib/frontend_cache/backends/azure.py +1 -1
  180. wagtail/contrib/frontend_cache/backends/cloudfront.py +2 -2
  181. wagtail/contrib/frontend_cache/backends/dummy.py +11 -0
  182. wagtail/contrib/frontend_cache/tests.py +31 -37
  183. wagtail/contrib/frontend_cache/utils.py +12 -5
  184. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.mo +0 -0
  185. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +16 -1
  186. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +20 -24
  187. wagtail/contrib/redirects/models.py +16 -1
  188. wagtail/contrib/redirects/signal_handlers.py +18 -3
  189. wagtail/contrib/redirects/templates/wagtailredirects/add.html +5 -16
  190. wagtail/contrib/redirects/templates/wagtailredirects/import_summary.html +1 -1
  191. wagtail/contrib/redirects/tests/test_redirects.py +49 -6
  192. wagtail/contrib/redirects/tests/test_signal_handlers.py +42 -1
  193. wagtail/contrib/redirects/views.py +27 -3
  194. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.mo +0 -0
  195. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +60 -1
  196. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +12 -18
  197. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/add.html +5 -8
  198. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/edit.html +15 -10
  199. wagtail/contrib/search_promotions/tests.py +13 -2
  200. wagtail/contrib/search_promotions/views.py +15 -3
  201. wagtail/contrib/settings/locale/cy/LC_MESSAGES/django.mo +0 -0
  202. wagtail/contrib/settings/locale/cy/LC_MESSAGES/django.po +6 -1
  203. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +2 -10
  204. wagtail/contrib/settings/templates/wagtailsettings/edit.html +12 -45
  205. wagtail/contrib/simple_translation/locale/cy/LC_MESSAGES/django.mo +0 -0
  206. wagtail/contrib/simple_translation/locale/cy/LC_MESSAGES/django.po +13 -1
  207. wagtail/contrib/simple_translation/locale/dv/LC_MESSAGES/django.mo +0 -0
  208. wagtail/contrib/simple_translation/locale/dv/LC_MESSAGES/django.po +3 -0
  209. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +4 -4
  210. wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.mo +0 -0
  211. wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.po +5 -2
  212. wagtail/contrib/simple_translation/tests/test_views.py +51 -0
  213. wagtail/contrib/simple_translation/wagtail_hooks.py +16 -11
  214. wagtail/contrib/styleguide/locale/cy/LC_MESSAGES/django.mo +0 -0
  215. wagtail/contrib/styleguide/locale/cy/LC_MESSAGES/django.po +5 -1
  216. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
  217. wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.mo +0 -0
  218. wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.po +27 -1
  219. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  220. wagtail/contrib/typed_table_block/blocks.py +25 -0
  221. wagtail/contrib/typed_table_block/locale/cy/LC_MESSAGES/django.mo +0 -0
  222. wagtail/contrib/typed_table_block/locale/cy/LC_MESSAGES/django.po +12 -1
  223. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  224. wagtail/contrib/typed_table_block/tests.py +24 -1
  225. wagtail/coreutils.py +5 -11
  226. wagtail/documents/admin_urls.py +2 -2
  227. wagtail/documents/locale/cy/LC_MESSAGES/django.mo +0 -0
  228. wagtail/documents/locale/cy/LC_MESSAGES/django.po +10 -0
  229. wagtail/documents/locale/en/LC_MESSAGES/django.po +61 -76
  230. wagtail/documents/migrations/0014_alter_document_file_size.py +18 -0
  231. wagtail/documents/models.py +1 -1
  232. wagtail/documents/rich_text/__init__.py +1 -3
  233. wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
  234. wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_add_tags.html +5 -1
  235. wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_add_to_collection.html +5 -1
  236. wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_delete.html +11 -5
  237. wagtail/documents/templates/wagtaildocs/documents/add.html +13 -41
  238. wagtail/documents/templates/wagtaildocs/documents/edit.html +28 -56
  239. wagtail/documents/templates/wagtaildocs/documents/index.html +1 -4
  240. wagtail/documents/templates/wagtaildocs/homepage/site_summary_documents.html +2 -2
  241. wagtail/documents/templates/wagtaildocs/multiple/add.html +36 -41
  242. wagtail/documents/tests/test_admin_views.py +64 -6
  243. wagtail/documents/tests/test_site_summary.py +3 -3
  244. wagtail/documents/views/documents.py +103 -113
  245. wagtail/documents/views/multiple.py +19 -1
  246. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  247. wagtail/embeds/oembed_providers.py +9 -19
  248. wagtail/fields.py +43 -27
  249. wagtail/images/admin_urls.py +2 -2
  250. wagtail/images/blocks.py +230 -2
  251. wagtail/images/fields.py +17 -29
  252. wagtail/images/image_operations.py +1 -1
  253. wagtail/images/locale/cy/LC_MESSAGES/django.mo +0 -0
  254. wagtail/images/locale/cy/LC_MESSAGES/django.po +128 -1
  255. wagtail/images/locale/en/LC_MESSAGES/django.po +119 -129
  256. wagtail/images/migrations/0025_alter_image_file_alter_rendition_file.py +36 -43
  257. wagtail/images/migrations/0027_image_description.py +20 -0
  258. wagtail/images/models.py +120 -45
  259. wagtail/images/rich_text/__init__.py +1 -3
  260. wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
  261. wagtail/images/static/wagtailimages/js/image-block.js +1 -0
  262. wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_add_tags.html +5 -1
  263. wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_add_to_collection.html +5 -1
  264. wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_delete.html +11 -5
  265. wagtail/images/templates/wagtailimages/chooser/results.html +2 -2
  266. wagtail/images/templates/wagtailimages/homepage/site_summary_images.html +2 -2
  267. wagtail/images/templates/wagtailimages/images/_file_field.html +2 -2
  268. wagtail/images/templates/wagtailimages/images/add.html +13 -31
  269. wagtail/images/templates/wagtailimages/images/edit.html +53 -82
  270. wagtail/images/templates/wagtailimages/images/index.html +1 -4
  271. wagtail/images/templates/wagtailimages/images/url_generator.html +1 -1
  272. wagtail/images/templates/wagtailimages/multiple/add.html +40 -47
  273. wagtail/images/templates/wagtailimages/widgets/image.html +5 -0
  274. wagtail/images/templates/wagtailimages/widgets/image_chooser.html +1 -1
  275. wagtail/images/tests/test_admin_views.py +70 -10
  276. wagtail/images/tests/test_blocks.py +367 -1
  277. wagtail/images/tests/test_image_operations.py +23 -0
  278. wagtail/images/tests/test_models.py +20 -0
  279. wagtail/images/tests/test_signal_handlers.py +99 -95
  280. wagtail/images/tests/test_site_summary.py +3 -3
  281. wagtail/images/tests/test_templatetags.py +11 -7
  282. wagtail/images/tests/tests.py +4 -0
  283. wagtail/images/views/images.py +103 -104
  284. wagtail/images/views/multiple.py +17 -1
  285. wagtail/locale/cy/LC_MESSAGES/django.mo +0 -0
  286. wagtail/locale/cy/LC_MESSAGES/django.po +3 -0
  287. wagtail/locale/en/LC_MESSAGES/django.po +137 -125
  288. wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
  289. wagtail/locale/sl/LC_MESSAGES/django.po +3 -0
  290. wagtail/locales/locale/en/LC_MESSAGES/django.po +8 -8
  291. wagtail/locales/views.py +4 -1
  292. wagtail/migrations/0089_log_entry_data_json_null_to_object.py +1 -7
  293. wagtail/models/__init__.py +122 -14
  294. wagtail/models/audit_log.py +1 -3
  295. wagtail/models/i18n.py +1 -2
  296. wagtail/project_template/Dockerfile +3 -3
  297. wagtail/project_template/requirements.txt +2 -2
  298. wagtail/query.py +17 -4
  299. wagtail/rich_text/__init__.py +2 -3
  300. wagtail/rich_text/pages.py +2 -4
  301. wagtail/rich_text/rewriters.py +2 -2
  302. wagtail/search/backends/database/mysql/query.py +3 -3
  303. wagtail/search/backends/database/sqlite/query.py +6 -6
  304. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  305. wagtail/sites/locale/en/LC_MESSAGES/django.po +6 -6
  306. wagtail/sites/views.py +0 -1
  307. wagtail/snippets/action_menu.py +14 -4
  308. wagtail/snippets/locale/cy/LC_MESSAGES/django.mo +0 -0
  309. wagtail/snippets/locale/cy/LC_MESSAGES/django.po +73 -1
  310. wagtail/snippets/locale/en/LC_MESSAGES/django.po +27 -33
  311. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  312. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  313. wagtail/snippets/templates/wagtailsnippets/bulk_actions/confirm_bulk_delete.html +5 -3
  314. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/locked.html +1 -1
  315. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -11
  316. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu_item.html +1 -6
  317. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +1 -1
  318. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +1 -1
  319. wagtail/snippets/templates/wagtailsnippets/snippets/create.html +1 -18
  320. wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +1 -14
  321. wagtail/snippets/templates/wagtailsnippets/snippets/index.html +2 -5
  322. wagtail/snippets/tests/test_preview.py +193 -61
  323. wagtail/snippets/tests/test_snippets.py +247 -38
  324. wagtail/snippets/tests/test_usage.py +5 -0
  325. wagtail/snippets/tests/test_viewset.py +25 -9
  326. wagtail/snippets/tests/test_workflows.py +232 -19
  327. wagtail/snippets/views/snippets.py +1 -10
  328. wagtail/test/numberformat.py +104 -0
  329. wagtail/test/settings.py +10 -0
  330. wagtail/test/settings_ui.py +2 -0
  331. wagtail/test/testapp/migrations/0010_alter_customimage_file_and_more.py +71 -78
  332. wagtail/test/testapp/migrations/0040_nocreatablesubpagetypespage_nosubpagetypespage.py +54 -0
  333. wagtail/test/testapp/migrations/0041_alter_jsonstreammodel_options.py +17 -0
  334. wagtail/test/testapp/migrations/0042_alter_customdocument_file_size_and_more.py +28 -0
  335. wagtail/test/testapp/migrations/0043_customimage_description.py +41 -0
  336. wagtail/test/testapp/migrations/0044_custompreviewsizesmodel_custompreviewsizespage.py +52 -0
  337. wagtail/test/testapp/migrations/0045_alter_streampage_body.py +52 -0
  338. wagtail/test/testapp/models.py +62 -4
  339. wagtail/test/testapp/rich_text.py +2 -2
  340. wagtail/test/testapp/templates/tests/form_page_landing.html +2 -1
  341. wagtail/test/testapp/urls.py +5 -0
  342. wagtail/test/testapp/views.py +5 -0
  343. wagtail/test/utils/page_tests.py +5 -5
  344. wagtail/test/utils/template_tests.py +2 -2
  345. wagtail/tests/test_blocks.py +15 -0
  346. wagtail/tests/test_page_permissions.py +109 -0
  347. wagtail/tests/test_revision_model.py +27 -0
  348. wagtail/tests/test_signals.py +21 -2
  349. wagtail/tests/test_tests.py +30 -0
  350. wagtail/users/locale/cy/LC_MESSAGES/django.mo +0 -0
  351. wagtail/users/locale/cy/LC_MESSAGES/django.po +118 -1
  352. wagtail/users/locale/dv/LC_MESSAGES/django.mo +0 -0
  353. wagtail/users/locale/dv/LC_MESSAGES/django.po +3 -0
  354. wagtail/users/locale/en/LC_MESSAGES/django.po +89 -113
  355. wagtail/users/locale/sl/LC_MESSAGES/django.mo +0 -0
  356. wagtail/users/locale/sl/LC_MESSAGES/django.po +3 -0
  357. wagtail/users/migrations/0014_userprofile_contrast.py +23 -0
  358. wagtail/users/models.py +11 -0
  359. wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_assign_role.html +5 -1
  360. wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_delete.html +5 -1
  361. wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_set_active_state.html +5 -1
  362. wagtail/users/templates/wagtailusers/groups/create.html +19 -17
  363. wagtail/users/templates/wagtailusers/groups/edit.html +2 -40
  364. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +1 -62
  365. wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.html +0 -1
  366. wagtail/users/templates/wagtailusers/users/create.html +46 -50
  367. wagtail/users/templates/wagtailusers/users/edit.html +45 -62
  368. wagtail/users/templates/wagtailusers/users/index.html +1 -4
  369. wagtail/users/templatetags/wagtailusers_tags.py +1 -5
  370. wagtail/users/tests/test_admin_views.py +85 -66
  371. wagtail/users/views/groups.py +4 -1
  372. wagtail/users/views/users.py +2 -0
  373. {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/METADATA +6 -6
  374. {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/RECORD +378 -367
  375. wagtail/admin/static/wagtailadmin/js/preview-panel.js +0 -2
  376. wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +0 -11
  377. wagtail/admin/templates/wagtailadmin/generic/history_results.html +0 -1
  378. wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +0 -3
  379. wagtail/admin/templates/wagtailadmin/pages/usage_results.html +0 -6
  380. wagtail/admin/templates/wagtailadmin/shared/workflow_history/index.html +0 -17
  381. wagtail/admin/templates/wagtailadmin/shared/workflow_history/results.html +0 -17
  382. wagtail/admin/templates/wagtailadmin/workflows/usage.html +0 -44
  383. {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/LICENSE +0 -0
  384. {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/WHEEL +0 -0
  385. {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/entry_points.txt +0 -0
  386. {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2024-08-07 10:06+0100\n"
11
+ "POT-Creation-Date: 2024-10-21 17:53+0100\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -22,19 +22,19 @@ msgstr ""
22
22
  msgid "Wagtail redirects"
23
23
  msgstr ""
24
24
 
25
- #: filters.py:26 views.py:102 views.py:119
25
+ #: filters.py:12 views.py:102 views.py:119
26
26
  msgid "Type"
27
27
  msgstr ""
28
28
 
29
- #: filters.py:29
29
+ #: filters.py:15
30
30
  msgid "Permanent"
31
31
  msgstr ""
32
32
 
33
- #: filters.py:30
33
+ #: filters.py:16
34
34
  msgid "Temporary"
35
35
  msgstr ""
36
36
 
37
- #: filters.py:32
37
+ #: filters.py:18
38
38
  msgid "All"
39
39
  msgstr ""
40
40
 
@@ -75,7 +75,7 @@ msgstr ""
75
75
  msgid "site"
76
76
  msgstr ""
77
77
 
78
- #: models.py:25 models.py:85
78
+ #: models.py:25 models.py:100
79
79
  msgid "permanent"
80
80
  msgstr ""
81
81
 
@@ -111,28 +111,24 @@ msgstr ""
111
111
  msgid "created at"
112
112
  msgstr ""
113
113
 
114
- #: models.py:87
114
+ #: models.py:102
115
115
  msgid "temporary"
116
116
  msgstr ""
117
117
 
118
- #: models.py:204
118
+ #: models.py:219
119
119
  msgid "redirect"
120
120
  msgstr ""
121
121
 
122
- #: models.py:205
122
+ #: models.py:220
123
123
  msgid "redirects"
124
124
  msgstr ""
125
125
 
126
126
  #: templates/wagtailredirects/add.html:3 templates/wagtailredirects/add.html:5
127
- #: views.py:69
127
+ #: views.py:70
128
128
  msgid "Add redirect"
129
129
  msgstr ""
130
130
 
131
- #: templates/wagtailredirects/add.html:19
132
- msgid "Save"
133
- msgstr ""
134
-
135
- #: templates/wagtailredirects/choose_import_file.html:3 views.py:78
131
+ #: templates/wagtailredirects/choose_import_file.html:3 views.py:79
136
132
  #: wagtail_hooks.py:34
137
133
  msgid "Redirects"
138
134
  msgstr ""
@@ -241,44 +237,44 @@ msgstr ""
241
237
  msgid "Redirect '%(redirect_title)s' updated."
242
238
  msgstr ""
243
239
 
244
- #: views.py:173
240
+ #: views.py:190
245
241
  #, python-format
246
242
  msgid "Redirect '%(redirect_title)s' deleted."
247
243
  msgstr ""
248
244
 
249
- #: views.py:198
245
+ #: views.py:217
250
246
  #, python-format
251
247
  msgid "Redirect '%(redirect_title)s' added."
252
248
  msgstr ""
253
249
 
254
- #: views.py:203
250
+ #: views.py:222
255
251
  msgid "Edit"
256
252
  msgstr ""
257
253
 
258
- #: views.py:210
254
+ #: views.py:229
259
255
  msgid "The redirect could not be created due to errors."
260
256
  msgstr ""
261
257
 
262
- #: views.py:249
258
+ #: views.py:273
263
259
  msgid "Search redirects"
264
260
  msgstr ""
265
261
 
266
- #: views.py:263
262
+ #: views.py:287
267
263
  #, python-format
268
264
  msgid "File format of type \"%(extension)s\" is not supported"
269
265
  msgstr ""
270
266
 
271
- #: views.py:280
267
+ #: views.py:304
272
268
  #, python-format
273
269
  msgid "Imported file has a wrong encoding: %(error_message)s"
274
270
  msgstr ""
275
271
 
276
- #: views.py:287
272
+ #: views.py:311
277
273
  #, python-format
278
274
  msgid "%(error)s encountered while trying to read file: %(filename)s"
279
275
  msgstr ""
280
276
 
281
- #: views.py:378
277
+ #: views.py:402
282
278
  #, python-format
283
279
  msgid "Imported %(total)d redirect"
284
280
  msgid_plural "Imported %(total)d redirects"
@@ -5,7 +5,7 @@ from django.urls import Resolver404
5
5
  from django.utils.functional import cached_property
6
6
  from django.utils.translation import gettext_lazy as _
7
7
 
8
- from wagtail.models import Page
8
+ from wagtail.models import Page, Site
9
9
 
10
10
 
11
11
  class Redirect(models.Model):
@@ -80,6 +80,21 @@ class Redirect(models.Model):
80
80
  return self.redirect_link
81
81
  return None
82
82
 
83
+ def old_links(self, site_root_paths=None):
84
+ """
85
+ Determine the old URLs which this redirect might handle.
86
+
87
+ :param site_root_paths: Pre-calculated root paths (obtained from `Site.get_site_root_paths`)
88
+ :return: List of old links
89
+ """
90
+ if self.site_id is not None:
91
+ return {self.site.root_url + self.old_path}
92
+
93
+ if site_root_paths is None:
94
+ site_root_paths = Site.get_site_root_paths()
95
+
96
+ return {root_paths.root_url + self.old_path for root_paths in site_root_paths}
97
+
83
98
  def get_is_permanent_display(self):
84
99
  if self.is_permanent:
85
100
  return _("permanent")
@@ -1,9 +1,11 @@
1
1
  import logging
2
- from typing import Iterable, Set, Tuple
2
+ from collections.abc import Iterable
3
3
 
4
+ from django.apps import apps
4
5
  from django.conf import settings
5
6
  from django.db.models import Q
6
7
 
8
+ from wagtail.contrib.frontend_cache.utils import PurgeBatch
7
9
  from wagtail.coreutils import BatchCreator, get_dummy_request
8
10
  from wagtail.models import Page, Site
9
11
 
@@ -27,6 +29,19 @@ class BatchRedirectCreator(BatchCreator):
27
29
  clashes_q |= Q(old_path=item.old_path, site_id=item.site_id)
28
30
  Redirect.objects.filter(automatically_created=True).filter(clashes_q).delete()
29
31
 
32
+ def post_process(self):
33
+ if not apps.is_installed("wagtail.contrib.frontend_cache"):
34
+ return
35
+
36
+ batch = PurgeBatch()
37
+
38
+ site_root_paths = Site.get_site_root_paths()
39
+
40
+ for redirect in self.items:
41
+ batch.add_urls(redirect.old_links(site_root_paths))
42
+
43
+ batch.purge()
44
+
30
45
 
31
46
  def autocreate_redirects_on_slug_change(
32
47
  instance_before: Page, instance: Page, **kwargs
@@ -89,8 +104,8 @@ def autocreate_redirects_on_page_move(
89
104
 
90
105
 
91
106
  def _page_urls_for_sites(
92
- page: Page, sites: Tuple[Site], cache_target: Page
93
- ) -> Set[Tuple[Site, str, str]]:
107
+ page: Page, sites: tuple[Site], cache_target: Page
108
+ ) -> set[tuple[Site, str, str]]:
94
109
  urls = set()
95
110
  for site in sites:
96
111
  # use a `HttpRequest` to influence the return value
@@ -1,4 +1,4 @@
1
- {% extends "wagtailadmin/base.html" %}
1
+ {% extends "wagtailadmin/generic/form.html" %}
2
2
  {% load i18n wagtailadmin_tags %}
3
3
  {% block titletag %}{% trans "Add redirect" %}{% endblock %}
4
4
  {% block content %}
@@ -14,22 +14,11 @@
14
14
  {% for field in form.visible_fields %}
15
15
  <li>{% formattedfield field %}</li>
16
16
  {% endfor %}
17
-
18
- <li>
19
- <input type="submit" value="{% trans 'Save' %}" class="button" />
20
- </li>
21
17
  </ul>
22
- </form>
23
-
24
- {% endblock %}
25
18
 
26
- {% block extra_js %}
27
- {{ block.super }}
28
- {% include "wagtailadmin/pages/_editor_js.html" %}
29
- {{ form.media.js }}
30
- {% endblock %}
19
+ {% block footer %}
20
+ {{ block.super }}
21
+ {% endblock %}
22
+ </form>
31
23
 
32
- {% block extra_css %}
33
- {{ block.super }}
34
- {{ form.media.css }}
35
24
  {% endblock %}
@@ -8,7 +8,7 @@
8
8
  <section id="summary" class="nice-padding">
9
9
  <p class="help-block help-warning">
10
10
  {% icon name='warning' %}
11
- {% blocktrans trimmed with total=import_summary.total successes=import_summary.successes errors=import_summary.errors_count %}Found {{ total }} redirects, created {{ successes }} and found {{ errors }} errors.{% endblocktrans %}
11
+ {% blocktrans trimmed with total=import_summary.total|intcomma successes=import_summary.successes|intcomma errors=import_summary.errors_count|intcomma %}Found {{ total }} redirects, created {{ successes }} and found {{ errors }} errors.{% endblocktrans %}
12
12
  </p>
13
13
 
14
14
  <table class="listing">
@@ -7,6 +7,7 @@ from django.urls import reverse
7
7
  from openpyxl.reader.excel import load_workbook
8
8
 
9
9
  from wagtail.admin.admin_url_finder import AdminURLFinder
10
+ from wagtail.contrib.frontend_cache.tests import PURGED_URLS
10
11
  from wagtail.contrib.redirects import models
11
12
  from wagtail.log_actions import registry as log_registry
12
13
  from wagtail.models import Page, Site
@@ -652,12 +653,10 @@ class TestRedirectsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
652
653
  self.assertEqual(response.context["query_string"], "Aaargh")
653
654
 
654
655
  def test_pagination(self):
655
- # page numbers in range should be accepted
656
- response = self.get({"p": 1})
657
- self.assertEqual(response.status_code, 200)
658
- # page numbers out of range should return 404
659
- response = self.get({"p": 9999})
660
- self.assertEqual(response.status_code, 404)
656
+ pages = ["0", "1", "-1", "9999", "Not a page"]
657
+ for page in pages:
658
+ response = self.get({"p": page})
659
+ self.assertEqual(response.status_code, 200)
661
660
 
662
661
  def test_default_ordering(self):
663
662
  for i in range(0, 10):
@@ -776,11 +775,19 @@ class TestRedirectsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
776
775
  self.assertEqual(len(csv_data), 10)
777
776
 
778
777
 
778
+ @override_settings(
779
+ WAGTAILFRONTENDCACHE={
780
+ "dummy": {
781
+ "BACKEND": "wagtail.contrib.frontend_cache.tests.MockBackend",
782
+ },
783
+ },
784
+ )
779
785
  class TestRedirectsAddView(WagtailTestUtils, TestCase):
780
786
  fixtures = ["test.json"]
781
787
 
782
788
  def setUp(self):
783
789
  self.login()
790
+ PURGED_URLS.clear()
784
791
 
785
792
  def get(self, params={}):
786
793
  return self.client.get(reverse("wagtailredirects:add"), params)
@@ -817,6 +824,8 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
817
824
  log_entry = log_registry.get_logs_for_instance(redirect).first()
818
825
  self.assertEqual(log_entry.action, "wagtail.create")
819
826
 
827
+ self.assertEqual(PURGED_URLS, {"http://localhost/test"})
828
+
820
829
  def test_add_with_site(self):
821
830
  localhost = Site.objects.get(hostname="localhost")
822
831
  response = self.post(
@@ -837,6 +846,8 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
837
846
  self.assertEqual(redirects.first().redirect_link, "http://www.test.com/")
838
847
  self.assertEqual(redirects.first().site, localhost)
839
848
 
849
+ self.assertEqual(PURGED_URLS, {"http://localhost/test"})
850
+
840
851
  def test_add_validation_error(self):
841
852
  response = self.post(
842
853
  {
@@ -849,6 +860,7 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
849
860
 
850
861
  # Should not redirect to index
851
862
  self.assertEqual(response.status_code, 200)
863
+ self.assertEqual(PURGED_URLS, set())
852
864
 
853
865
  def test_cannot_add_duplicate_with_no_site(self):
854
866
  models.Redirect.objects.create(
@@ -865,6 +877,7 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
865
877
 
866
878
  # Should not redirect to index
867
879
  self.assertEqual(response.status_code, 200)
880
+ self.assertEqual(PURGED_URLS, set())
868
881
 
869
882
  def test_cannot_add_duplicate_on_same_site(self):
870
883
  localhost = Site.objects.get(hostname="localhost")
@@ -882,6 +895,7 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
882
895
 
883
896
  # Should not redirect to index
884
897
  self.assertEqual(response.status_code, 200)
898
+ self.assertEqual(PURGED_URLS, set())
885
899
 
886
900
  def test_can_reuse_path_on_other_site(self):
887
901
  localhost = Site.objects.get(hostname="localhost")
@@ -909,6 +923,8 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
909
923
  redirects = models.Redirect.objects.filter(redirect_link="http://www.test.com/")
910
924
  self.assertEqual(redirects.count(), 1)
911
925
 
926
+ self.assertEqual(PURGED_URLS, redirects.get().old_links())
927
+
912
928
  def test_add_long_redirect(self):
913
929
  response = self.post(
914
930
  {
@@ -931,7 +947,16 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
931
947
  )
932
948
  self.assertIsNone(redirects.first().site)
933
949
 
950
+ self.assertEqual(PURGED_URLS, redirects.get().old_links())
951
+
934
952
 
953
+ @override_settings(
954
+ WAGTAILFRONTENDCACHE={
955
+ "dummy": {
956
+ "BACKEND": "wagtail.contrib.frontend_cache.tests.MockBackend",
957
+ },
958
+ },
959
+ )
935
960
  class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
936
961
  def setUp(self):
937
962
  # Create a redirect to edit
@@ -943,6 +968,8 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
943
968
  # Login
944
969
  self.user = self.login()
945
970
 
971
+ PURGED_URLS.clear()
972
+
946
973
  def get(self, params={}, redirect_id=None):
947
974
  return self.client.get(
948
975
  reverse("wagtailredirects:edit", args=(redirect_id or self.redirect.id,)),
@@ -995,6 +1022,8 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
995
1022
  )
996
1023
  self.assertIsNone(redirects.first().site)
997
1024
 
1025
+ self.assertEqual(PURGED_URLS, {"http://localhost/test"})
1026
+
998
1027
  def test_edit_with_site(self):
999
1028
  localhost = Site.objects.get(hostname="localhost")
1000
1029
 
@@ -1017,6 +1046,7 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1017
1046
  redirects.first().redirect_link, "http://www.test.com/ive-been-edited"
1018
1047
  )
1019
1048
  self.assertEqual(redirects.first().site, localhost)
1049
+ self.assertEqual(PURGED_URLS, {"http://localhost/test"})
1020
1050
 
1021
1051
  def test_edit_validation_error(self):
1022
1052
  response = self.post(
@@ -1030,6 +1060,7 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1030
1060
 
1031
1061
  # Should not redirect to index
1032
1062
  self.assertEqual(response.status_code, 200)
1063
+ self.assertEqual(PURGED_URLS, set())
1033
1064
 
1034
1065
  def test_edit_duplicate(self):
1035
1066
  models.Redirect.objects.create(
@@ -1046,6 +1077,7 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1046
1077
 
1047
1078
  # Should not redirect to index
1048
1079
  self.assertEqual(response.status_code, 200)
1080
+ self.assertEqual(PURGED_URLS, set())
1049
1081
 
1050
1082
  def test_get_with_no_permission(self, redirect_id=None):
1051
1083
  self.user.is_superuser = False
@@ -1081,6 +1113,13 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1081
1113
  self.assertTemplateUsed(response, "wagtailredirects/edit.html")
1082
1114
 
1083
1115
 
1116
+ @override_settings(
1117
+ WAGTAILFRONTENDCACHE={
1118
+ "dummy": {
1119
+ "BACKEND": "wagtail.contrib.frontend_cache.tests.MockBackend",
1120
+ },
1121
+ },
1122
+ )
1084
1123
  class TestRedirectsDeleteView(WagtailTestUtils, TestCase):
1085
1124
  def setUp(self):
1086
1125
  # Create a redirect to edit
@@ -1092,6 +1131,8 @@ class TestRedirectsDeleteView(WagtailTestUtils, TestCase):
1092
1131
  # Login
1093
1132
  self.login()
1094
1133
 
1134
+ PURGED_URLS.clear()
1135
+
1095
1136
  def get(self, params={}, redirect_id=None):
1096
1137
  return self.client.get(
1097
1138
  reverse("wagtailredirects:delete", args=(redirect_id or self.redirect.id,)),
@@ -1120,3 +1161,5 @@ class TestRedirectsDeleteView(WagtailTestUtils, TestCase):
1120
1161
  # Check that the redirect was deleted
1121
1162
  redirects = models.Redirect.objects.filter(old_path="/test")
1122
1163
  self.assertEqual(redirects.count(), 0)
1164
+
1165
+ self.assertEqual(PURGED_URLS, {"http://localhost/test"})
@@ -1,6 +1,7 @@
1
1
  from django.contrib.auth import get_user_model
2
2
  from django.test import TestCase, override_settings
3
3
 
4
+ from wagtail.contrib.frontend_cache.tests import PURGED_URLS
4
5
  from wagtail.contrib.redirects.models import Redirect
5
6
  from wagtail.coreutils import get_dummy_request
6
7
  from wagtail.models import Page, Site
@@ -11,7 +12,14 @@ from wagtail.test.utils import WagtailTestUtils
11
12
  User = get_user_model()
12
13
 
13
14
 
14
- @override_settings(WAGTAILREDIRECTS_AUTO_CREATE=True)
15
+ @override_settings(
16
+ WAGTAILREDIRECTS_AUTO_CREATE=True,
17
+ WAGTAILFRONTENDCACHE={
18
+ "dummy": {
19
+ "BACKEND": "wagtail.contrib.frontend_cache.tests.MockBackend",
20
+ },
21
+ },
22
+ )
15
23
  class TestAutocreateRedirects(WagtailTestUtils, TestCase):
16
24
  fixtures = ["test.json"]
17
25
 
@@ -25,6 +33,8 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
25
33
  self.event_index = EventIndex.objects.get()
26
34
  self.other_page = Page.objects.get(url_path="/home/about-us/")
27
35
 
36
+ PURGED_URLS.clear()
37
+
28
38
  def trigger_page_slug_changed_signal(self, page):
29
39
  page.slug += "-extra"
30
40
  with self.captureOnCommitCallbacks(execute=True):
@@ -76,9 +86,20 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
76
86
  # the automatically_created flag should have been set to True
77
87
  self.assertTrue(r.automatically_created)
78
88
 
89
+ self.assertEqual(
90
+ PURGED_URLS,
91
+ {
92
+ "http://localhost/events/saint-patrick/pointless-suffix",
93
+ "http://localhost/events/final-event",
94
+ "http://localhost/events/christmas",
95
+ "http://localhost/events",
96
+ },
97
+ )
98
+
79
99
  def test_no_redirects_created_when_page_is_root_for_all_sites_it_belongs_to(self):
80
100
  self.trigger_page_slug_changed_signal(self.home_page)
81
101
  self.assertFalse(Redirect.objects.exists())
102
+ self.assertEqual(len(PURGED_URLS), 0)
82
103
 
83
104
  def test_handling_of_existing_redirects(self):
84
105
  # the page we'll be triggering the change for here is...
@@ -131,6 +152,16 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
131
152
  ).exists()
132
153
  )
133
154
 
155
+ self.assertEqual(
156
+ PURGED_URLS,
157
+ {
158
+ "http://localhost/events/saint-patrick/pointless-suffix",
159
+ "http://localhost/events/final-event",
160
+ "http://localhost/events/christmas",
161
+ "http://localhost/events",
162
+ },
163
+ )
164
+
134
165
  def test_redirect_creation_for_custom_route_paths(self):
135
166
  # Add a page that has overridden get_route_paths()
136
167
  homepage = Page.objects.get(id=2)
@@ -165,6 +196,14 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
165
196
  ),
166
197
  ],
167
198
  )
199
+ self.assertEqual(
200
+ PURGED_URLS,
201
+ {
202
+ "http://localhost/routable-page",
203
+ "http://localhost/routable-page/not-a-valid-route",
204
+ "http://localhost/routable-page/render-method-test",
205
+ },
206
+ )
168
207
 
169
208
  def test_no_redirects_created_when_pages_are_moved_to_a_different_site(self):
170
209
  # Add a new home page
@@ -187,8 +226,10 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
187
226
 
188
227
  # No redirects should have been created
189
228
  self.assertFalse(Redirect.objects.exists())
229
+ self.assertEqual(len(PURGED_URLS), 0)
190
230
 
191
231
  @override_settings(WAGTAILREDIRECTS_AUTO_CREATE=False)
192
232
  def test_no_redirects_created_if_disabled(self):
193
233
  self.trigger_page_slug_changed_signal(self.event_index)
194
234
  self.assertFalse(Redirect.objects.exists())
235
+ self.assertEqual(len(PURGED_URLS), 0)
@@ -1,5 +1,4 @@
1
1
  import os
2
- from typing import List
3
2
 
4
3
  from django.core.exceptions import PermissionDenied, SuspiciousOperation
5
4
  from django.db import transaction
@@ -18,6 +17,7 @@ from wagtail.admin.forms.search import SearchForm
18
17
  from wagtail.admin.ui.tables import Column, StatusTagColumn, TitleColumn
19
18
  from wagtail.admin.views import generic
20
19
  from wagtail.admin.widgets.button import Button
20
+ from wagtail.contrib.frontend_cache.utils import PurgeBatch, purge_urls_from_cache
21
21
  from wagtail.contrib.redirects import models
22
22
  from wagtail.contrib.redirects.filters import RedirectsReportFilterSet
23
23
  from wagtail.contrib.redirects.forms import (
@@ -36,6 +36,7 @@ from wagtail.contrib.redirects.utils import (
36
36
  write_to_file_storage,
37
37
  )
38
38
  from wagtail.log_actions import log
39
+ from wagtail.models import Site
39
40
 
40
41
  permission_checker = PermissionPolicyChecker(permission_policy)
41
42
 
@@ -77,7 +78,6 @@ class IndexView(generic.IndexView):
77
78
  paginate_by = 20
78
79
  page_title = gettext_lazy("Redirects")
79
80
  search_fields = ["old_path", "redirect_page__url_path", "redirect_link"]
80
- _show_breadcrumbs = True
81
81
  columns = [
82
82
  TitleColumn(
83
83
  "old_path",
@@ -123,7 +123,7 @@ class IndexView(generic.IndexView):
123
123
  return super().get_base_queryset().select_related("redirect_page", "site")
124
124
 
125
125
  @cached_property
126
- def header_more_buttons(self) -> List[Button]:
126
+ def header_more_buttons(self) -> list[Button]:
127
127
  buttons = super().header_more_buttons.copy()
128
128
  buttons.append(
129
129
  Button(
@@ -154,6 +154,20 @@ class EditView(generic.EditView):
154
154
  "redirect_title": self.object.title
155
155
  }
156
156
 
157
+ def save_instance(self):
158
+ purger = PurgeBatch()
159
+
160
+ root_paths = Site.get_site_root_paths()
161
+ purger.add_urls(self.object.old_links(root_paths))
162
+
163
+ instance = super().save_instance()
164
+
165
+ purger.add_urls(self.object.old_links(root_paths))
166
+
167
+ purger.purge()
168
+
169
+ return instance
170
+
157
171
 
158
172
  @permission_checker.require("delete")
159
173
  def delete(request, redirect_id):
@@ -168,6 +182,9 @@ def delete(request, redirect_id):
168
182
  with transaction.atomic():
169
183
  log(instance=theredirect, action="wagtail.delete")
170
184
  theredirect.delete()
185
+
186
+ purge_urls_from_cache(theredirect.old_links())
187
+
171
188
  messages.success(
172
189
  request,
173
190
  _("Redirect '%(redirect_title)s' deleted.")
@@ -193,6 +210,8 @@ def add(request):
193
210
  theredirect = form.save()
194
211
  log(instance=theredirect, action="wagtail.create")
195
212
 
213
+ purge_urls_from_cache(theredirect.old_links())
214
+
196
215
  messages.success(
197
216
  request,
198
217
  _("Redirect '%(redirect_title)s' added.")
@@ -217,6 +236,11 @@ def add(request):
217
236
  "wagtailredirects/add.html",
218
237
  {
219
238
  "form": form,
239
+ # Remove these when this view is refactored to a generic.CreateView subclass.
240
+ # Avoid defining new translatable strings.
241
+ "submit_button_label": generic.CreateView.submit_button_label,
242
+ "submit_button_active_label": generic.CreateView.submit_button_active_label,
243
+ "media": form.media,
220
244
  },
221
245
  )
222
246