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
@@ -1,7 +1,10 @@
1
+ from django.contrib.auth import get_user_model
2
+ from django.contrib.auth.models import Group, Permission
1
3
  from django.test import TestCase
2
4
  from django.urls import reverse
3
5
  from django.utils.http import urlencode
4
6
 
7
+ from wagtail.models import GroupPagePermission, Page
5
8
  from wagtail.test.testapp.models import EventPage
6
9
  from wagtail.test.utils import WagtailTestUtils
7
10
 
@@ -13,6 +16,47 @@ class TestContentTypeUse(WagtailTestUtils, TestCase):
13
16
  self.user = self.login()
14
17
  self.christmas_page = EventPage.objects.get(title="Christmas")
15
18
 
19
+ def test_with_no_permission(self):
20
+ request_url = reverse(
21
+ "wagtailadmin_pages:type_use", args=("tests", "eventpage")
22
+ )
23
+ group = Group.objects.create(name="test group")
24
+ self.user.is_superuser = False
25
+ self.user.save()
26
+ self.user.groups.add(group)
27
+ group.permissions.add(
28
+ Permission.objects.get(
29
+ content_type__app_label="wagtailadmin", codename="access_admin"
30
+ )
31
+ )
32
+ # No GroupPagePermission created
33
+
34
+ response = self.client.get(request_url)
35
+ self.assertEqual(response.status_code, 302)
36
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
37
+
38
+ def test_with_minimal_permissions(self):
39
+ request_url = reverse(
40
+ "wagtailadmin_pages:type_use", args=("tests", "eventpage")
41
+ )
42
+ group = Group.objects.create(name="test group")
43
+ self.user.is_superuser = False
44
+ self.user.save()
45
+ self.user.groups.add(group)
46
+ group.permissions.add(
47
+ Permission.objects.get(
48
+ content_type__app_label="wagtailadmin", codename="access_admin"
49
+ ),
50
+ )
51
+ GroupPagePermission.objects.create(
52
+ group=group,
53
+ page=Page.objects.first(),
54
+ permission_type="change",
55
+ )
56
+
57
+ response = self.client.get(request_url)
58
+ self.assertEqual(response.status_code, 200)
59
+
16
60
  def test_content_type_use(self):
17
61
  # Get use of event page
18
62
  request_url = reverse(
@@ -23,7 +67,7 @@ class TestContentTypeUse(WagtailTestUtils, TestCase):
23
67
  # Check response
24
68
  self.assertEqual(response.status_code, 200)
25
69
  self.assertTemplateUsed(response, "wagtailadmin/generic/listing.html")
26
- self.assertTemplateUsed(response, "wagtailadmin/pages/usage_results.html")
70
+ self.assertTemplateUsed(response, "wagtailadmin/generic/listing_results.html")
27
71
  self.assertContains(response, "Christmas")
28
72
 
29
73
  # Links to 'delete' etc should include a 'next' URL parameter pointing back here
@@ -33,4 +77,40 @@ class TestContentTypeUse(WagtailTestUtils, TestCase):
33
77
  + urlencode({"next": request_url})
34
78
  )
35
79
  self.assertContains(response, delete_url)
36
- self.assertNotContains(response, "data-bulk-action-select-all-checkbox")
80
+ self.assertContains(response, "data-bulk-action-select-all-checkbox")
81
+
82
+ with self.assertNumQueries(33):
83
+ self.client.get(request_url)
84
+
85
+ def test_content_type_use_results(self):
86
+ # Get the results view of event page use, with search and filter
87
+ ameristralia_page = EventPage.objects.get(title="Ameristralia Day")
88
+ user = get_user_model().objects.get(email="eventmoderator@example.com")
89
+ request_url = reverse(
90
+ "wagtailadmin_pages:type_use_results",
91
+ args=("tests", "eventpage"),
92
+ )
93
+ response = self.client.get(
94
+ request_url,
95
+ data={"q": "Ameristralia", "owner": user.pk},
96
+ )
97
+
98
+ # Check response
99
+ self.assertEqual(response.status_code, 200)
100
+ self.assertTemplateNotUsed(response, "wagtailadmin/generic/listing.html")
101
+ self.assertTemplateUsed(response, "wagtailadmin/generic/listing_results.html")
102
+ self.assertContains(response, "Ameristralia Day")
103
+
104
+ # Links to 'delete' etc should include a 'next' URL parameter pointing back
105
+ # to the full view, not the results-only view
106
+ full_view_url = reverse(
107
+ "wagtailadmin_pages:type_use",
108
+ args=("tests", "eventpage"),
109
+ )
110
+ delete_url = (
111
+ reverse("wagtailadmin_pages:delete", args=(ameristralia_page.id,))
112
+ + "?"
113
+ + urlencode({"next": full_view_url})
114
+ )
115
+ self.assertContains(response, delete_url)
116
+ self.assertContains(response, "data-bulk-action-select-all-checkbox")
@@ -13,6 +13,7 @@ from django.urls import reverse
13
13
  from django.utils import timezone
14
14
  from django.utils.translation import gettext_lazy as _
15
15
 
16
+ from wagtail.admin.action_menu import ActionMenuItem
16
17
  from wagtail.admin.admin_url_finder import AdminURLFinder
17
18
  from wagtail.exceptions import PageClassNotFoundError
18
19
  from wagtail.models import (
@@ -218,6 +219,75 @@ class TestPageEdit(WagtailTestUtils, TestCase):
218
219
  expected_url = "/admin/pages/%d/edit/" % self.event_page.id
219
220
  self.assertEqual(url_finder.get_edit_url(self.event_page), expected_url)
220
221
 
222
+ def test_construct_page_action_menu_hook_with_custom_default_button(self):
223
+ class CustomDefaultItem(ActionMenuItem):
224
+ label = "Custom button"
225
+ name = "custom-default"
226
+ classname = "custom-class"
227
+ icon_name = "check"
228
+
229
+ class Media:
230
+ js = ["js/custom-default.js"]
231
+ css = {"all": ["css/custom-default.css"]}
232
+
233
+ def add_custom_default_item(menu_items, request, context):
234
+ menu_items.insert(0, CustomDefaultItem())
235
+
236
+ with self.register_hook(
237
+ "construct_page_action_menu",
238
+ add_custom_default_item,
239
+ ):
240
+ response = self.client.get(
241
+ reverse("wagtailadmin_pages:edit", args=(self.event_page.id,))
242
+ )
243
+
244
+ self.assertEqual(response.status_code, 200)
245
+
246
+ soup = self.get_soup(response.content)
247
+ form = soup.select_one("form[data-edit-form]")
248
+ custom_action = form.select_one("button[name='custom-default']")
249
+ self.assertIsNotNone(custom_action)
250
+
251
+ # We're replacing the save button, so it should not be in a dropdown
252
+ # as it's the main action
253
+ dropdown_parent = custom_action.find_parent(attrs={"class": "w-dropdown"})
254
+ self.assertIsNone(dropdown_parent)
255
+
256
+ self.assertEqual(custom_action.text.strip(), "Custom button")
257
+ self.assertEqual(custom_action.attrs.get("class"), ["button", "custom-class"])
258
+ icon = custom_action.select_one("svg use[href='#icon-check']")
259
+ self.assertIsNotNone(icon)
260
+
261
+ # Should contain media files
262
+ js = soup.select_one("script[src='/static/js/custom-default.js']")
263
+ self.assertIsNotNone(js)
264
+ css = soup.select_one("link[href='/static/css/custom-default.css']")
265
+ self.assertIsNotNone(css)
266
+
267
+ # The save button should now be in the dropdown
268
+ save_item = form.select_one(".w-dropdown .action-save")
269
+ self.assertIsNotNone(save_item)
270
+
271
+ def test_construct_page_action_menu_hook_removes_all_buttons(self):
272
+ def remove_all_buttons(menu_items, request, context):
273
+ menu_items[:] = []
274
+
275
+ with self.register_hook(
276
+ "construct_page_action_menu",
277
+ remove_all_buttons,
278
+ ):
279
+ response = self.client.get(
280
+ reverse("wagtailadmin_pages:edit", args=(self.event_page.id,))
281
+ )
282
+
283
+ # It shouldn't crash due to assuming a default button is present
284
+ self.assertEqual(response.status_code, 200)
285
+
286
+ soup = self.get_soup(response.content)
287
+ form = soup.select_one("form[data-edit-form]")
288
+ actions = form.select("footer button")
289
+ self.assertEqual(len(actions), 0)
290
+
221
291
  def test_usage_count_information_shown(self):
222
292
  PageChooserModel.objects.create(page=self.event_page)
223
293
 
@@ -6,6 +6,7 @@ from django.urls import reverse
6
6
  from django.utils.http import urlencode
7
7
 
8
8
  from wagtail import hooks
9
+ from wagtail.admin.staticfiles import versioned_static
9
10
  from wagtail.admin.widgets import Button
10
11
  from wagtail.models import GroupPagePermission, Locale, Page, Site, Workflow
11
12
  from wagtail.test.testapp.models import (
@@ -93,6 +94,13 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
93
94
  count=3,
94
95
  )
95
96
 
97
+ bulk_actions_js = versioned_static("wagtailadmin/js/bulk-actions.js")
98
+ self.assertContains(
99
+ response,
100
+ f'<script defer src="{bulk_actions_js}"></script>',
101
+ html=True,
102
+ )
103
+
96
104
  def test_explore_results(self):
97
105
  explore_results_url = reverse(
98
106
  "wagtailadmin_explore_results", args=(self.root_page.id,)
@@ -396,7 +404,11 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
396
404
  )
397
405
 
398
406
  # Check response
399
- self.assertEqual(response.status_code, 404)
407
+ self.assertEqual(response.status_code, 200)
408
+ self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
409
+
410
+ # Check that we got page one
411
+ self.assertEqual(response.context["page_obj"].number, 1)
400
412
 
401
413
  def test_pagination_out_of_range(self):
402
414
  self.make_pages()
@@ -406,7 +418,14 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
406
418
  )
407
419
 
408
420
  # Check response
409
- self.assertEqual(response.status_code, 404)
421
+ self.assertEqual(response.status_code, 200)
422
+ self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
423
+
424
+ # Check that we got the last page
425
+ self.assertEqual(
426
+ response.context["page_obj"].number,
427
+ response.context["paginator"].num_pages,
428
+ )
410
429
 
411
430
  def test_no_pagination_with_custom_ordering(self):
412
431
  self.make_pages()
@@ -921,6 +940,25 @@ class TestPageExplorerSignposting(WagtailTestUtils, TestCase):
921
940
  response, """<a href="/admin/sites/">Configure a site now.</a>"""
922
941
  )
923
942
 
943
+ def test_searching_at_root(self):
944
+ self.login(username="superuser", password="password")
945
+
946
+ # Message about root level should not show when searching or filtering
947
+ response = self.client.get(reverse("wagtailadmin_explore_root"), {"q": "hello"})
948
+ self.assertEqual(response.status_code, 200)
949
+ self.assertNotContains(
950
+ response,
951
+ "The root level is where you can add new sites to your Wagtail installation.",
952
+ )
953
+ response = self.client.get(
954
+ reverse("wagtailadmin_explore_root"), {"has_child_pages": "true"}
955
+ )
956
+ self.assertEqual(response.status_code, 200)
957
+ self.assertNotContains(
958
+ response,
959
+ "The root level is where you can add new sites to your Wagtail installation.",
960
+ )
961
+
924
962
  def test_admin_at_non_site_page(self):
925
963
  self.login(username="superuser", password="password")
926
964
  response = self.client.get(
@@ -940,6 +978,29 @@ class TestPageExplorerSignposting(WagtailTestUtils, TestCase):
940
978
  response, """<a href="/admin/sites/">Configure a site now.</a>"""
941
979
  )
942
980
 
981
+ def test_searching_at_non_site_page(self):
982
+ self.login(username="superuser", password="password")
983
+
984
+ # Message about unroutable pages should not show when searching or filtering
985
+ response = self.client.get(
986
+ reverse("wagtailadmin_explore", args=(self.no_site_page.id,)),
987
+ {"q": "hello"},
988
+ )
989
+ self.assertEqual(response.status_code, 200)
990
+ self.assertNotContains(
991
+ response,
992
+ "There is no site set up for this location.",
993
+ )
994
+ response = self.client.get(
995
+ reverse("wagtailadmin_explore", args=(self.no_site_page.id,)),
996
+ {"has_child_pages": "true"},
997
+ )
998
+ self.assertEqual(response.status_code, 200)
999
+ self.assertNotContains(
1000
+ response,
1001
+ "There is no site set up for this location.",
1002
+ )
1003
+
943
1004
  def test_admin_at_site_page(self):
944
1005
  self.login(username="superuser", password="password")
945
1006
  response = self.client.get(
@@ -1184,7 +1245,7 @@ class TestExplorablePageVisibility(WagtailTestUtils, TestCase):
1184
1245
  response = self.client.get(reverse("wagtailadmin_home"))
1185
1246
  self.assertEqual(response.status_code, 200)
1186
1247
  # Bob should only see the welcome for example.com, not testserver
1187
- self.assertContains(response, "Welcome to the example.com Wagtail CMS")
1248
+ self.assertContains(response, "example.com")
1188
1249
  self.assertNotContains(response, "testserver")
1189
1250
 
1190
1251
  def test_breadcrumb_with_no_user_permissions(self):
@@ -1273,7 +1334,7 @@ class TestInWorkflowStatus(WagtailTestUtils, TestCase):
1273
1334
  # Warm up cache
1274
1335
  self.client.get(self.url)
1275
1336
 
1276
- with self.assertNumQueries(47):
1337
+ with self.assertNumQueries(44):
1277
1338
  response = self.client.get(self.url)
1278
1339
 
1279
1340
  self.assertEqual(response.status_code, 200)
@@ -33,6 +33,9 @@ class TestPageSearch(WagtailTestUtils, TransactionTestCase):
33
33
  self.assertTemplateUsed(response, "wagtailadmin/pages/search.html")
34
34
  self.assertEqual(response.status_code, 200)
35
35
 
36
+ with self.assertNumQueries(22):
37
+ self.get()
38
+
36
39
  def test_search(self):
37
40
  # Find root page
38
41
  root_page = Page.objects.get(id=2)
@@ -110,13 +113,11 @@ class TestPageSearch(WagtailTestUtils, TransactionTestCase):
110
113
  self.assertContains(response, f'href="{expected_new_page_copy_url}"')
111
114
 
112
115
  def test_pagination(self):
113
- # page numbers in range should be accepted
114
- response = self.get({"q": "Hello", "p": 1})
115
- self.assertEqual(response.status_code, 200)
116
- self.assertTemplateUsed(response, "wagtailadmin/pages/search.html")
117
- # page numbers out of range should return 404
118
- response = self.get({"q": "Hello", "p": 9999})
119
- self.assertEqual(response.status_code, 404)
116
+ pages = ["0", "1", "-1", "9999", "Not a page"]
117
+ for page in pages:
118
+ response = self.get({"q": "Hello", "p": page})
119
+ self.assertEqual(response.status_code, 200)
120
+ self.assertTemplateUsed(response, "wagtailadmin/pages/search.html")
120
121
 
121
122
  def test_root_can_appear_in_search_results(self):
122
123
  response = self.get({"q": "root"})
@@ -103,7 +103,9 @@ class TestPageUsage(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
103
103
 
104
104
  self.assertContains(response, "Contact us")
105
105
  self.assertContains(
106
- response, reverse("wagtailadmin_pages:edit", args=(form_page.id,))
106
+ response,
107
+ reverse("wagtailadmin_pages:edit", args=(form_page.id,))
108
+ + "#:w:contentpath=thank_you_redirect_page",
107
109
  )
108
110
  self.assertContains(response, "Thank you redirect page")
109
111
  self.assertContains(response, "<td>Form page with redirect</td>", html=True)