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
@@ -20,6 +20,8 @@ from wagtail.test.testapp.models import (
20
20
  CustomPermissionTester,
21
21
  EventIndex,
22
22
  EventPage,
23
+ NoCreatableSubpageTypesPage,
24
+ NoSubpageTypesPage,
23
25
  SingletonPageViaMaxCount,
24
26
  )
25
27
 
@@ -39,6 +41,19 @@ class TestPagePermission(TestCase):
39
41
  def test_nonpublisher_page_permissions(self):
40
42
  event_editor = get_user_model().objects.get(email="eventeditor@example.com")
41
43
  homepage = Page.objects.get(url_path="/home/")
44
+
45
+ # As this is a direct child of the homepage, permission checks should
46
+ # mostly mirror those for the homepage itself
47
+ no_creatable_subpages_page = NoCreatableSubpageTypesPage(
48
+ title="No creatable subpages", slug="no-creatable-subpages"
49
+ )
50
+ homepage.add_child(instance=no_creatable_subpages_page)
51
+
52
+ # As this is a direct child of the homepage, permission checks should
53
+ # mostly mirror those for the homepage itself
54
+ no_subpages_page = NoSubpageTypesPage(title="No subpages", slug="no-subpages")
55
+ homepage.add_child(instance=no_subpages_page)
56
+
42
57
  christmas_page = EventPage.objects.get(url_path="/home/events/christmas/")
43
58
  unpublished_event_page = EventPage.objects.get(
44
59
  url_path="/home/events/tentative-unpublished-event/"
@@ -51,6 +66,10 @@ class TestPagePermission(TestCase):
51
66
  )
52
67
 
53
68
  homepage_perms = homepage.permissions_for_user(event_editor)
69
+ no_creatable_subpages_perms = no_creatable_subpages_page.permissions_for_user(
70
+ event_editor
71
+ )
72
+ no_subpages_perms = no_subpages_page.permissions_for_user(event_editor)
54
73
  christmas_page_perms = christmas_page.permissions_for_user(event_editor)
55
74
  unpub_perms = unpublished_event_page.permissions_for_user(event_editor)
56
75
  someone_elses_event_perms = someone_elses_event_page.permissions_for_user(
@@ -59,17 +78,23 @@ class TestPagePermission(TestCase):
59
78
  board_meetings_perms = board_meetings_page.permissions_for_user(event_editor)
60
79
 
61
80
  self.assertFalse(homepage_perms.can_add_subpage())
81
+ self.assertFalse(no_creatable_subpages_perms.can_add_subpage())
82
+ self.assertFalse(no_subpages_perms.can_add_subpage())
62
83
  self.assertTrue(christmas_page_perms.can_add_subpage())
63
84
  self.assertTrue(unpub_perms.can_add_subpage())
64
85
  self.assertTrue(someone_elses_event_perms.can_add_subpage())
65
86
 
66
87
  self.assertFalse(homepage_perms.can_edit())
88
+ self.assertFalse(no_creatable_subpages_perms.can_edit())
89
+ self.assertFalse(no_subpages_perms.can_edit())
67
90
  self.assertTrue(christmas_page_perms.can_edit())
68
91
  self.assertTrue(unpub_perms.can_edit())
69
92
  # basic 'add' permission doesn't allow editing pages owned by someone else
70
93
  self.assertFalse(someone_elses_event_perms.can_edit())
71
94
 
72
95
  self.assertFalse(homepage_perms.can_delete())
96
+ self.assertFalse(no_creatable_subpages_perms.can_delete())
97
+ self.assertFalse(no_subpages_perms.can_delete())
73
98
  self.assertFalse(
74
99
  christmas_page_perms.can_delete()
75
100
  ) # cannot delete because it is published
@@ -77,22 +102,32 @@ class TestPagePermission(TestCase):
77
102
  self.assertFalse(someone_elses_event_perms.can_delete())
78
103
 
79
104
  self.assertFalse(homepage_perms.can_publish())
105
+ self.assertFalse(no_creatable_subpages_perms.can_publish())
106
+ self.assertFalse(no_subpages_perms.can_publish())
80
107
  self.assertFalse(christmas_page_perms.can_publish())
81
108
  self.assertFalse(unpub_perms.can_publish())
82
109
 
83
110
  self.assertFalse(homepage_perms.can_unpublish())
111
+ self.assertFalse(no_creatable_subpages_perms.can_unpublish())
112
+ self.assertFalse(no_subpages_perms.can_unpublish())
84
113
  self.assertFalse(christmas_page_perms.can_unpublish())
85
114
  self.assertFalse(unpub_perms.can_unpublish())
86
115
 
87
116
  self.assertFalse(homepage_perms.can_publish_subpage())
117
+ self.assertFalse(no_creatable_subpages_perms.can_publish_subpage())
118
+ self.assertFalse(no_subpages_perms.can_publish_subpage())
88
119
  self.assertFalse(christmas_page_perms.can_publish_subpage())
89
120
  self.assertFalse(unpub_perms.can_publish_subpage())
90
121
 
91
122
  self.assertFalse(homepage_perms.can_reorder_children())
123
+ self.assertFalse(no_creatable_subpages_perms.can_reorder_children())
124
+ self.assertFalse(no_subpages_perms.can_reorder_children())
92
125
  self.assertFalse(christmas_page_perms.can_reorder_children())
93
126
  self.assertFalse(unpub_perms.can_reorder_children())
94
127
 
95
128
  self.assertFalse(homepage_perms.can_move())
129
+ self.assertFalse(no_creatable_subpages_perms.can_move())
130
+ self.assertFalse(no_subpages_perms.can_move())
96
131
  # cannot move because this would involve unpublishing from its current location
97
132
  self.assertFalse(christmas_page_perms.can_move())
98
133
  self.assertTrue(unpub_perms.can_move())
@@ -119,6 +154,19 @@ class TestPagePermission(TestCase):
119
154
  email="eventmoderator@example.com"
120
155
  )
121
156
  homepage = Page.objects.get(url_path="/home/")
157
+
158
+ # As this is a direct child of the homepage, permission checks should
159
+ # mostly mirror those for the homepage itself
160
+ no_creatable_subpages_page = NoCreatableSubpageTypesPage(
161
+ title="No creatable subpages", slug="no-creatable-subpages"
162
+ )
163
+ homepage.add_child(instance=no_creatable_subpages_page)
164
+
165
+ # As this is a direct child of the homepage, permission checks should
166
+ # mostly mirror those for the homepage itself
167
+ no_subpages_page = NoSubpageTypesPage(title="No subpages", slug="no-subpages")
168
+ homepage.add_child(instance=no_subpages_page)
169
+
122
170
  christmas_page = EventPage.objects.get(url_path="/home/events/christmas/")
123
171
  unpublished_event_page = EventPage.objects.get(
124
172
  url_path="/home/events/tentative-unpublished-event/"
@@ -128,42 +176,61 @@ class TestPagePermission(TestCase):
128
176
  )
129
177
 
130
178
  homepage_perms = homepage.permissions_for_user(event_moderator)
179
+ no_creatable_subpages_perms = no_creatable_subpages_page.permissions_for_user(
180
+ event_moderator
181
+ )
182
+ no_subpages_perms = no_subpages_page.permissions_for_user(event_moderator)
131
183
  christmas_page_perms = christmas_page.permissions_for_user(event_moderator)
132
184
  unpub_perms = unpublished_event_page.permissions_for_user(event_moderator)
133
185
  board_meetings_perms = board_meetings_page.permissions_for_user(event_moderator)
134
186
 
135
187
  self.assertFalse(homepage_perms.can_add_subpage())
188
+ self.assertFalse(no_creatable_subpages_perms.can_add_subpage())
189
+ self.assertFalse(no_subpages_perms.can_add_subpage())
136
190
  self.assertTrue(christmas_page_perms.can_add_subpage())
137
191
  self.assertTrue(unpub_perms.can_add_subpage())
138
192
 
139
193
  self.assertFalse(homepage_perms.can_edit())
194
+ self.assertFalse(no_creatable_subpages_perms.can_edit())
195
+ self.assertFalse(no_subpages_perms.can_edit())
140
196
  self.assertTrue(christmas_page_perms.can_edit())
141
197
  self.assertTrue(unpub_perms.can_edit())
142
198
 
143
199
  self.assertFalse(homepage_perms.can_delete())
200
+ self.assertFalse(no_creatable_subpages_perms.can_delete())
201
+ self.assertFalse(no_subpages_perms.can_delete())
144
202
  # can delete a published page because we have publish permission
145
203
  self.assertTrue(christmas_page_perms.can_delete())
146
204
  self.assertTrue(unpub_perms.can_delete())
147
205
 
148
206
  self.assertFalse(homepage_perms.can_publish())
207
+ self.assertFalse(no_creatable_subpages_perms.can_publish())
208
+ self.assertFalse(no_subpages_perms.can_publish())
149
209
  self.assertTrue(christmas_page_perms.can_publish())
150
210
  self.assertTrue(unpub_perms.can_publish())
151
211
 
152
212
  self.assertFalse(homepage_perms.can_unpublish())
213
+ self.assertFalse(no_creatable_subpages_perms.can_unpublish())
153
214
  self.assertTrue(christmas_page_perms.can_unpublish())
154
215
  self.assertFalse(
155
216
  unpub_perms.can_unpublish()
156
217
  ) # cannot unpublish a page that isn't published
157
218
 
158
219
  self.assertFalse(homepage_perms.can_publish_subpage())
220
+ self.assertFalse(no_creatable_subpages_perms.can_publish_subpage())
221
+ self.assertFalse(no_subpages_perms.can_publish_subpage())
159
222
  self.assertTrue(christmas_page_perms.can_publish_subpage())
160
223
  self.assertTrue(unpub_perms.can_publish_subpage())
161
224
 
162
225
  self.assertFalse(homepage_perms.can_reorder_children())
226
+ self.assertFalse(no_creatable_subpages_perms.can_reorder_children())
227
+ self.assertFalse(no_subpages_perms.can_reorder_children())
163
228
  self.assertTrue(christmas_page_perms.can_reorder_children())
164
229
  self.assertTrue(unpub_perms.can_reorder_children())
165
230
 
166
231
  self.assertFalse(homepage_perms.can_move())
232
+ self.assertFalse(no_creatable_subpages_perms.can_move())
233
+ self.assertFalse(no_subpages_perms.can_move())
167
234
  self.assertTrue(christmas_page_perms.can_move())
168
235
  self.assertTrue(unpub_perms.can_move())
169
236
 
@@ -325,6 +392,19 @@ class TestPagePermission(TestCase):
325
392
  def test_superuser_has_full_permissions(self):
326
393
  user = get_user_model().objects.get(email="superuser@example.com")
327
394
  homepage = Page.objects.get(url_path="/home/").specific
395
+
396
+ # As this is a direct child of the homepage, permission checks should
397
+ # mostly mirror those for the homepage itself
398
+ no_creatable_subpages_page = NoCreatableSubpageTypesPage(
399
+ title="No creatable subpages", slug="no-creatable-subpages"
400
+ )
401
+ homepage.add_child(instance=no_creatable_subpages_page)
402
+
403
+ # As this is a direct child of the homepage, permission checks should
404
+ # mostly mirror those for the homepage itself
405
+ no_subpages_page = NoSubpageTypesPage(title="No subpages", slug="no-subpages")
406
+ homepage.add_child(instance=no_subpages_page)
407
+
328
408
  root = Page.objects.get(url_path="/").specific
329
409
  unpublished_event_page = EventPage.objects.get(
330
410
  url_path="/home/events/tentative-unpublished-event/"
@@ -334,35 +414,64 @@ class TestPagePermission(TestCase):
334
414
  )
335
415
 
336
416
  homepage_perms = homepage.permissions_for_user(user)
417
+ no_creatable_subpages_perms = no_creatable_subpages_page.permissions_for_user(
418
+ user
419
+ )
420
+ no_subpages_perms = no_subpages_page.permissions_for_user(user)
337
421
  root_perms = root.permissions_for_user(user)
338
422
  unpub_perms = unpublished_event_page.permissions_for_user(user)
339
423
  board_meetings_perms = board_meetings_page.permissions_for_user(user)
340
424
 
341
425
  self.assertTrue(homepage_perms.can_add_subpage())
426
+ self.assertFalse(
427
+ no_creatable_subpages_perms.can_add_subpage()
428
+ ) # There are no 'creatable' subpage types
429
+ self.assertFalse(
430
+ no_subpages_perms.can_add_subpage()
431
+ ) # There are no subpage types
342
432
  self.assertTrue(root_perms.can_add_subpage())
343
433
 
344
434
  self.assertTrue(homepage_perms.can_edit())
435
+ self.assertTrue(no_creatable_subpages_perms.can_edit())
436
+ self.assertTrue(no_subpages_perms.can_edit())
345
437
  self.assertFalse(
346
438
  root_perms.can_edit()
347
439
  ) # root is not a real editable page, even to superusers
348
440
 
349
441
  self.assertTrue(homepage_perms.can_delete())
442
+ self.assertTrue(no_creatable_subpages_perms.can_delete())
443
+ self.assertTrue(no_subpages_perms.can_delete())
350
444
  self.assertFalse(root_perms.can_delete())
351
445
 
352
446
  self.assertTrue(homepage_perms.can_publish())
447
+ self.assertTrue(no_creatable_subpages_perms.can_publish())
448
+ self.assertTrue(no_subpages_perms.can_publish())
353
449
  self.assertFalse(root_perms.can_publish())
354
450
 
355
451
  self.assertTrue(homepage_perms.can_unpublish())
452
+ self.assertTrue(no_creatable_subpages_perms.can_unpublish())
453
+ self.assertTrue(no_subpages_perms.can_unpublish())
356
454
  self.assertFalse(root_perms.can_unpublish())
357
455
  self.assertFalse(unpub_perms.can_unpublish())
358
456
 
359
457
  self.assertTrue(homepage_perms.can_publish_subpage())
458
+ self.assertFalse(
459
+ no_creatable_subpages_perms.can_publish_subpage()
460
+ ) # There are no 'creatable' subpages, so a new one cannot be 'created and published' here
461
+ self.assertFalse(
462
+ no_subpages_perms.can_publish_subpage()
463
+ ) # There are no subpages, so a new one cannot be 'created and published' here
464
+
360
465
  self.assertTrue(root_perms.can_publish_subpage())
361
466
 
362
467
  self.assertTrue(homepage_perms.can_reorder_children())
468
+ self.assertTrue(no_creatable_subpages_perms.can_reorder_children())
469
+ self.assertTrue(no_subpages_perms.can_reorder_children())
363
470
  self.assertTrue(root_perms.can_reorder_children())
364
471
 
365
472
  self.assertTrue(homepage_perms.can_move())
473
+ self.assertTrue(no_creatable_subpages_perms.can_move())
474
+ self.assertTrue(no_subpages_perms.can_move())
366
475
  self.assertFalse(root_perms.can_move())
367
476
 
368
477
  self.assertTrue(homepage_perms.can_move_to(root))
@@ -70,6 +70,9 @@ class TestRevisableModel(TestCase):
70
70
  self.assertEqual(self.instance.get_base_content_type(), self.content_type)
71
71
  self.assertEqual(self.instance.get_content_type(), self.content_type)
72
72
 
73
+ # The for_instance() method should return the revision
74
+ self.assertEqual(Revision.objects.for_instance(self.instance).first(), revision)
75
+
73
76
  def test_content_type_with_inheritance(self):
74
77
  instance = RevisableGrandChildModel.objects.create(text="test")
75
78
  instance.text = "test updated"
@@ -87,6 +90,18 @@ class TestRevisableModel(TestCase):
87
90
  self.assertEqual(instance.get_base_content_type(), base_content_type)
88
91
  self.assertEqual(instance.get_content_type(), content_type)
89
92
 
93
+ # The for_instance() method should return the revision,
94
+ # whether we're using the specific instance
95
+ self.assertIsInstance(instance, RevisableModel)
96
+ self.assertIsInstance(instance, RevisableGrandChildModel)
97
+ self.assertEqual(Revision.objects.for_instance(instance).first(), revision)
98
+
99
+ # or the base instance
100
+ base_instance = RevisableModel.objects.get(pk=instance.pk)
101
+ self.assertIsInstance(base_instance, RevisableModel)
102
+ self.assertNotIsInstance(base_instance, RevisableGrandChildModel)
103
+ self.assertEqual(Revision.objects.for_instance(base_instance).first(), revision)
104
+
90
105
  def test_content_type_for_page_model(self):
91
106
  hello_page = self.create_page()
92
107
  hello_page.content = "Updated world"
@@ -104,6 +119,18 @@ class TestRevisableModel(TestCase):
104
119
  self.assertEqual(hello_page.get_base_content_type(), base_content_type)
105
120
  self.assertEqual(hello_page.get_content_type(), content_type)
106
121
 
122
+ # The for_instance() method should return the revision,
123
+ # whether we're using the specific instance
124
+ self.assertIsInstance(hello_page, SimplePage)
125
+ self.assertIsInstance(hello_page, Page)
126
+ self.assertEqual(Revision.objects.for_instance(hello_page).first(), revision)
127
+
128
+ # or the base instance
129
+ base_instance = Page.objects.get(pk=hello_page.pk)
130
+ self.assertIsInstance(base_instance, Page)
131
+ self.assertNotIsInstance(base_instance, SimplePage)
132
+ self.assertEqual(Revision.objects.for_instance(base_instance).first(), revision)
133
+
107
134
  def test_as_object(self):
108
135
  self.instance.text = "updated"
109
136
  self.instance.save_revision()
@@ -5,7 +5,7 @@ from django.test import TestCase
5
5
 
6
6
  from wagtail.models import Locale, Site
7
7
  from wagtail.signals import copy_for_translation_done, page_slug_changed
8
- from wagtail.test.testapp.models import SimplePage
8
+ from wagtail.test.testapp.models import EventCategory, SimplePage
9
9
  from wagtail.test.utils import WagtailTestUtils
10
10
 
11
11
 
@@ -128,7 +128,7 @@ class TestCopyForTranslationDoneSignal(WagtailTestUtils, TestCase):
128
128
 
129
129
  root_page.copy_for_translation(self.another_locale)
130
130
 
131
- def test_signal_emitted_on_copy_for_translation_done(self):
131
+ def test_signal_emitted_on_page_copy_for_translation_done(self):
132
132
  # Connect a mock signal handler to the signal
133
133
  handler = mock.MagicMock()
134
134
  copy_for_translation_done.connect(handler)
@@ -144,3 +144,22 @@ class TestCopyForTranslationDoneSignal(WagtailTestUtils, TestCase):
144
144
 
145
145
  # Check the signal was fired
146
146
  self.assertEqual(handler.call_count, 1)
147
+
148
+ def test_signal_emitted_on_translatable_model_copy_for_translation_done(self):
149
+ # Connect a mock signal handler to the signal
150
+ handler = mock.MagicMock()
151
+ copy_for_translation_done.connect(handler)
152
+
153
+ model_to_translate = EventCategory.objects.create(
154
+ name="Some category", locale=self.locale
155
+ )
156
+
157
+ try:
158
+ with self.captureOnCommitCallbacks(execute=True):
159
+ model_to_translate.copy_for_translation(self.another_locale)
160
+ finally:
161
+ # Disconnect mock handler to prevent cross-test pollution
162
+ copy_for_translation_done.disconnect(handler)
163
+
164
+ # Check the signal was fired
165
+ self.assertEqual(handler.call_count, 1)
@@ -1,6 +1,10 @@
1
1
  import json
2
+ import unittest
2
3
 
4
+ from django.conf import settings
5
+ from django.core.exceptions import ImproperlyConfigured
3
6
  from django.core.files.uploadedfile import SimpleUploadedFile
7
+ from django.template import Context, Template
4
8
  from django.test import TestCase
5
9
 
6
10
  from wagtail.admin.tests.test_contentstate import content_state_equal
@@ -13,6 +17,8 @@ from wagtail.test.testapp.models import (
13
17
  BusinessSubIndex,
14
18
  EventIndex,
15
19
  EventPage,
20
+ NoCreatableSubpageTypesPage,
21
+ NoSubpageTypesPage,
16
22
  SectionedRichTextPage,
17
23
  SimpleChildPage,
18
24
  SimplePage,
@@ -287,6 +293,8 @@ class TestWagtailPageTests(WagtailPageTests):
287
293
  BusinessSubIndex,
288
294
  BusinessChild,
289
295
  BusinessIndex,
296
+ NoCreatableSubpageTypesPage,
297
+ NoSubpageTypesPage,
290
298
  SimpleParentPage,
291
299
  }
292
300
  self.assertAllowedParentPageTypes(BusinessIndex, all_but_business)
@@ -456,3 +464,25 @@ class TestDummyExternalStorage(WagtailTestUtils, TestCase):
456
464
  "Content file pointer should be at 0 - got 70 instead",
457
465
  ):
458
466
  DummyExternalStorage().save("test.png", simple_png)
467
+
468
+
469
+ @unittest.skipUnless(
470
+ settings.WAGTAIL_CHECK_TEMPLATE_NUMBER_FORMAT,
471
+ "Number formatting functions have not been patched",
472
+ )
473
+ class TestPatchedNumberFormat(TestCase):
474
+ def test_outputting_number_directly_is_disallowed(self):
475
+ context = Context({"num": 42})
476
+ template = Template("the answer is {{ num }}")
477
+ with self.assertRaises(ImproperlyConfigured):
478
+ template.render(context)
479
+
480
+ def test_outputting_number_via_intcomma(self):
481
+ context = Context({"num": 9000})
482
+ template = Template("{% load wagtailadmin_tags %}It's over {{ num|intcomma }}!")
483
+ self.assertEqual(template.render(context), "It's over 9,000!")
484
+
485
+ def test_outputting_number_via_unlocalize(self):
486
+ context = Context({"num": 9000})
487
+ template = Template("{% load l10n %}It's over {{ num|unlocalize }}!")
488
+ self.assertEqual(template.render(context), "It's over 9000!")
@@ -5,13 +5,14 @@
5
5
  # Translators:
6
6
  # Philip Crisp, 2022
7
7
  # Philip Crisp, 2022
8
+ # Philip Lindsay-Crisp, 2024
8
9
  msgid ""
9
10
  msgstr ""
10
11
  "Project-Id-Version: Wagtail\n"
11
12
  "Report-Msgid-Bugs-To: \n"
12
13
  "POT-Creation-Date: 2024-08-07 10:06+0100\n"
13
14
  "PO-Revision-Date: 2014-02-19 11:54+0000\n"
14
- "Last-Translator: Philip Crisp, 2022\n"
15
+ "Last-Translator: Philip Lindsay-Crisp, 2024\n"
15
16
  "Language-Team: Welsh (http://app.transifex.com/torchbox/wagtail/language/"
16
17
  "cy/)\n"
17
18
  "MIME-Version: 1.0\n"
@@ -24,6 +25,9 @@ msgstr ""
24
25
  msgid "Wagtail users"
25
26
  msgstr "Defnyddiwr Wagtail"
26
27
 
28
+ msgid "Required. Letters, digits and @/./+/-/_ only."
29
+ msgstr "Angenrheidiol. Llythyrau, digidau a @/./+/-/_ yn unig."
30
+
27
31
  msgid "This value may contain only letters, numbers and @/./+/-/_ characters."
28
32
  msgstr ""
29
33
  "Gall y gwerth hwn gynnwys llythrennau, rhifau a nodau @/./+/-/_ yn unig."
@@ -110,15 +114,43 @@ msgstr "Dewiswch eich parth amser presennol"
110
114
  msgid "profile picture"
111
115
  msgstr "llun proffil"
112
116
 
117
+ msgid "System default"
118
+ msgstr "Diofyn i'r system"
119
+
120
+ msgid "Light"
121
+ msgstr "Golau"
122
+
123
+ msgid "Dark"
124
+ msgstr "Tywyll"
125
+
126
+ msgid "admin theme"
127
+ msgstr "thema weinyddol"
128
+
113
129
  msgid "Default"
114
130
  msgstr "Diofyn"
115
131
 
132
+ msgid "Snug"
133
+ msgstr "Glyd"
134
+
135
+ #. Translators: "Density" is the term used to describe the amount of space
136
+ #. between elements in the user interface
137
+ msgid "density"
138
+ msgstr "dwysedd"
139
+
116
140
  msgid "user profile"
117
141
  msgstr "proffil defnyddiwr"
118
142
 
119
143
  msgid "user profiles"
120
144
  msgstr "proffiliau defnyddwyr"
121
145
 
146
+ #, python-format
147
+ msgid "Assign role to 1 user"
148
+ msgid_plural "Assign role to %(counter)s users"
149
+ msgstr[0] "Neilltuo rôl i 1 defnyddiwr"
150
+ msgstr[1] "Neilltuo rôl i %(counter)s defnyddiwr"
151
+ msgstr[2] "Neilltuo rôl i %(counter)s defnyddiwr"
152
+ msgstr[3] "Neilltuo rôl i %(counter)s defnyddiwr"
153
+
122
154
  msgid "Assign role"
123
155
  msgstr "Neilltuo rôl"
124
156
 
@@ -138,6 +170,14 @@ msgstr "Ie, aseinio"
138
170
  msgid "No, don't assign"
139
171
  msgstr "Na, peidiwch ag aseinio"
140
172
 
173
+ #, python-format
174
+ msgid "Delete 1 user"
175
+ msgid_plural "Delete %(counter)s users"
176
+ msgstr[0] "Dileu 1 defnyddiwr"
177
+ msgstr[1] "Dileu %(counter)s defnyddiwr"
178
+ msgstr[2] "Dileu %(counter)s defnyddiwr"
179
+ msgstr[3] "Dileu %(counter)s defnyddiwr"
180
+
141
181
  msgid "Delete"
142
182
  msgstr "Dileu"
143
183
 
@@ -157,6 +197,14 @@ msgstr "Ia, dileu"
157
197
  msgid "No, don't delete"
158
198
  msgstr "Na, peidiwch a ddileu"
159
199
 
200
+ #, python-format
201
+ msgid "Change active state for 1 user"
202
+ msgid_plural "Change active state for %(counter)s users"
203
+ msgstr[0] "Newid cyflwr gweithredol ar gyfer 1 defnyddiwr"
204
+ msgstr[1] "Newid cyflwr gweithredol ar gyfer %(counter)s defnyddiwr"
205
+ msgstr[2] "Newid cyflwr gweithredol ar gyfer %(counter)s defnyddiwr"
206
+ msgstr[3] "Newid cyflwr gweithredol ar gyfer %(counter)s defnyddiwr"
207
+
160
208
  msgid "Set active state"
161
209
  msgstr "Gosod cyflwr gweithredol"
162
210
 
@@ -173,6 +221,20 @@ msgstr "Ia, newid cyflwr"
173
221
  msgid "No, don't change state"
174
222
  msgstr "Na, paid a newid cyflwr"
175
223
 
224
+ #, python-format
225
+ msgid ""
226
+ "The group '%(group_name)s' has <strong>%(group_user_count)s</strong> member."
227
+ msgid_plural ""
228
+ "The group '%(group_name)s' has <strong>%(group_user_count)s</strong> members."
229
+ msgstr[0] ""
230
+ "Mae grŵp '%(group_name)s' efo <strong>%(group_user_count)s</strong> aelod."
231
+ msgstr[1] ""
232
+ "Mae grŵp '%(group_name)s' efo <strong>%(group_user_count)s</strong> aelod."
233
+ msgstr[2] ""
234
+ "Mae grŵp '%(group_name)s' efo <strong>%(group_user_count)s</strong> aelod."
235
+ msgstr[3] ""
236
+ "Mae grŵp '%(group_name)s' efo <strong>%(group_user_count)s</strong> aelod."
237
+
176
238
  msgid ""
177
239
  "Deleting this group will revoke this group's permissions from all member "
178
240
  "users."
@@ -216,6 +278,30 @@ msgstr "Datgloi"
216
278
  msgid "Custom permissions"
217
279
  msgstr "Caniatadau personol"
218
280
 
281
+ msgid "Toggle all"
282
+ msgstr "Togl i gyd"
283
+
284
+ msgid "Toggle all add permissions"
285
+ msgstr "Toglo pob caniatâd i ychwanegu"
286
+
287
+ msgid "Toggle all change permissions"
288
+ msgstr "Toglo pob caniatâd i newid"
289
+
290
+ msgid "Toggle all delete permissions"
291
+ msgstr "Toglo pob caniatâd i dileu"
292
+
293
+ msgid "Toggle all publish permissions"
294
+ msgstr "Toglo pob caniatâd i cyhoeddi"
295
+
296
+ msgid "Toggle all lock permissions"
297
+ msgstr "Toglo pob caniatâd i gloi"
298
+
299
+ msgid "Toggle all unlock permissions"
300
+ msgstr "Toglo pob caniatâd i datgloi"
301
+
302
+ msgid "Toggle all custom permissions"
303
+ msgstr "Toglo pob caniatâd nghwstwm"
304
+
219
305
  msgid "Other permissions"
220
306
  msgstr "Caniatadau eraill"
221
307
 
@@ -258,6 +344,10 @@ msgstr "Dileu defnyddiwr"
258
344
  msgid "Select all users in listing"
259
345
  msgstr "Dewiswch yr holl ddefnyddwyr wrth restru"
260
346
 
347
+ msgid "Sorry, no users match your query"
348
+ msgstr ""
349
+ "Mae'n ddrwg gennym, nid oes unrhyw ddefnyddwyr yn cyfateb i'ch ymholiad"
350
+
261
351
  #, python-format
262
352
  msgid ""
263
353
  "There are no users configured. Why not <a "
@@ -266,6 +356,13 @@ msgstr ""
266
356
  "Nid oes unrhyw ddefnyddwyr wedi'u ffurfweddu. Pam ddim <a "
267
357
  "href=\"%(wagtailusers_add_url)s\">ychwanegu un</a>?"
268
358
 
359
+ msgid "Can view"
360
+ msgstr "Yn gallu gweld"
361
+
362
+ #, python-format
363
+ msgid "user %(id)s (deleted)"
364
+ msgstr "defnyddiwr %(id)s (wedi' dileu)"
365
+
269
366
  msgid "Assign role to selected users"
270
367
  msgstr "Neilltuo rôl i ddefnyddwyr dethol"
271
368
 
@@ -298,6 +395,9 @@ msgstr "Actif"
298
395
  msgid "Inactive"
299
396
  msgstr "Anactif"
300
397
 
398
+ msgid "Mark as active"
399
+ msgstr "Marciwch fel weithredol"
400
+
301
401
  msgid "Change the active state for selected users"
302
402
  msgstr "Newid y cyflwr gweithredol ar gyfer defnyddwyr dethol"
303
403
 
@@ -344,6 +444,12 @@ msgstr "Gweld defnyddwyr yn y grŵp hwn"
344
444
  msgid "Group '%(object)s' deleted."
345
445
  msgstr "Grwp '%(object)s' wedi'i dileu."
346
446
 
447
+ msgid "Last login"
448
+ msgstr "Mewngofnod diwethaf"
449
+
450
+ msgid "Group"
451
+ msgstr "Grŵp"
452
+
347
453
  msgid "Add a user"
348
454
  msgstr "Ychwanegu defnyddiwr"
349
455
 
@@ -356,9 +462,20 @@ msgstr "Enw defnyddiwr"
356
462
  msgid "Admin"
357
463
  msgstr "Gweinyddol"
358
464
 
465
+ msgid "Access level"
466
+ msgstr "Lefel mynediad"
467
+
359
468
  msgid "Status"
360
469
  msgstr "Statws"
361
470
 
471
+ #, python-format
472
+ msgid "More options for '%(title)s'"
473
+ msgstr "Fwy o opsiynau i '%(title)s'"
474
+
475
+ #, python-format
476
+ msgid "User '%(object)s' created."
477
+ msgstr "Defnyddiwr '%(object)s' wedi' greu"
478
+
362
479
  #, python-format
363
480
  msgid "User '%(object)s' updated."
364
481
  msgstr "Defnyddiwr '%(object)s' wedi'i diweddaru."
@@ -67,6 +67,9 @@ msgstr "ތި ނަން ކިޔާ ގްރޫޕެއް މިހާރުވެސް އެބަހ
67
67
  msgid "You cannot have multiple permission records for the same page."
68
68
  msgstr "އެއް ޞަފްޙާއަކަށް ތަފާތު ހުއްދަތަކުގެ ރެކޯޑެއް ނުބެހެއްޓޭނެ"
69
69
 
70
+ msgid "submitted notifications"
71
+ msgstr "ހުށަހެޅިފައިވާ އެންގުންތައް"
72
+
70
73
  msgid "Default"
71
74
  msgstr "ޑީފޯލްޓް"
72
75