wagtail 6.3.1__py3-none-any.whl → 6.4rc1__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 (307) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/publish_revision.py +4 -5
  3. wagtail/admin/auth.py +0 -2
  4. wagtail/admin/checks.py +1 -1
  5. wagtail/admin/filters.py +3 -1
  6. wagtail/admin/forms/account.py +21 -11
  7. wagtail/admin/forms/collections.py +2 -9
  8. wagtail/admin/forms/formsets.py +32 -0
  9. wagtail/admin/forms/pages.py +5 -1
  10. wagtail/admin/forms/workflows.py +2 -13
  11. wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
  12. wagtail/admin/locale/ar/LC_MESSAGES/django.po +68 -1
  13. wagtail/admin/locale/ar/LC_MESSAGES/djangojs.mo +0 -0
  14. wagtail/admin/locale/ar/LC_MESSAGES/djangojs.po +5 -1
  15. wagtail/admin/locale/en/LC_MESSAGES/django.po +312 -356
  16. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -16
  17. wagtail/admin/locale/gl/LC_MESSAGES/djangojs.mo +0 -0
  18. wagtail/admin/locale/gl/LC_MESSAGES/djangojs.po +5 -5
  19. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  20. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +29 -0
  21. wagtail/admin/menu.py +0 -13
  22. wagtail/admin/panels/base.py +2 -2
  23. wagtail/admin/panels/group.py +4 -1
  24. wagtail/admin/panels/inline_panel.py +5 -2
  25. wagtail/admin/panels/model_utils.py +36 -0
  26. wagtail/admin/panels/page_utils.py +2 -40
  27. wagtail/admin/panels/signal_handlers.py +0 -2
  28. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  29. wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
  30. wagtail/admin/static/wagtailadmin/css/panels/streamfield.css +1 -1
  31. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  32. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  33. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -8
  34. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  35. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  36. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  37. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  38. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  39. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  40. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  41. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
  42. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  43. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +7 -0
  44. wagtail/admin/templates/wagtailadmin/404.html +4 -0
  45. wagtail/admin/templates/wagtailadmin/chooser/browse.html +2 -1
  46. wagtail/admin/templates/wagtailadmin/chooser/tables/parent_page_cell.html +1 -1
  47. wagtail/admin/templates/wagtailadmin/collections/_privacy_switch.html +8 -1
  48. wagtail/admin/templates/wagtailadmin/generic/confirm_delete.html +15 -9
  49. wagtail/admin/templates/wagtailadmin/generic/confirm_unpublish.html +21 -25
  50. wagtail/admin/templates/wagtailadmin/generic/form.html +1 -1
  51. wagtail/admin/templates/wagtailadmin/generic/preview_error.html +3 -0
  52. wagtail/admin/templates/wagtailadmin/generic/revisions/compare.html +63 -76
  53. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -2
  54. wagtail/admin/templates/wagtailadmin/pages/edit.html +1 -5
  55. wagtail/admin/templates/wagtailadmin/panels/inline_panel_child.html +1 -0
  56. wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_form.html +1 -1
  57. wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +6 -22
  58. wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +2 -2
  59. wagtail/admin/templates/wagtailadmin/shared/header.html +2 -2
  60. wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +32 -39
  61. wagtail/admin/templates/wagtailadmin/shared/revisions/confirm_unschedule.html +13 -17
  62. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +15 -3
  63. wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +1 -1
  64. wagtail/admin/templates/wagtailadmin/skeleton.html +4 -2
  65. wagtail/admin/templates/wagtailadmin/workflows/create.html +1 -1
  66. wagtail/admin/templates/wagtailadmin/workflows/edit.html +1 -1
  67. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_form.html +1 -1
  68. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_formset.html +6 -23
  69. wagtail/admin/templatetags/wagtailadmin_tags.py +12 -0
  70. wagtail/admin/templatetags/wagtailuserbar.py +2 -3
  71. wagtail/admin/tests/pages/test_create_page.py +110 -1
  72. wagtail/admin/tests/pages/test_edit_page.py +3 -2
  73. wagtail/admin/tests/pages/test_explorer_view.py +18 -0
  74. wagtail/admin/tests/pages/test_page_usage.py +24 -20
  75. wagtail/admin/tests/pages/test_preview.py +69 -1
  76. wagtail/admin/tests/pages/test_revisions.py +40 -6
  77. wagtail/admin/tests/test_account_management.py +39 -1
  78. wagtail/admin/tests/test_audit_log.py +4 -2
  79. wagtail/admin/tests/test_block_preview.py +224 -0
  80. wagtail/admin/tests/test_edit_handlers.py +23 -6
  81. wagtail/admin/tests/test_page_chooser.py +50 -3
  82. wagtail/admin/tests/test_privacy.py +49 -26
  83. wagtail/admin/tests/test_site_summary.py +15 -10
  84. wagtail/admin/tests/test_templatetags.py +19 -0
  85. wagtail/admin/tests/test_userbar.py +82 -1
  86. wagtail/admin/tests/test_views_generic.py +27 -12
  87. wagtail/admin/tests/test_workflows.py +69 -0
  88. wagtail/admin/tests/tests.py +23 -4
  89. wagtail/admin/tests/ui/test_sidebar.py +1 -1
  90. wagtail/admin/tests/viewsets/test_model_viewset.py +15 -13
  91. wagtail/admin/ui/side_panels.py +7 -4
  92. wagtail/admin/urls/__init__.py +6 -0
  93. wagtail/admin/urls/pages.py +1 -1
  94. wagtail/admin/userbar.py +21 -1
  95. wagtail/admin/views/account.py +5 -0
  96. wagtail/admin/views/chooser.py +5 -1
  97. wagtail/admin/views/collections.py +0 -2
  98. wagtail/admin/views/generic/base.py +20 -10
  99. wagtail/admin/views/generic/history.py +0 -1
  100. wagtail/admin/views/generic/models.py +79 -21
  101. wagtail/admin/views/generic/preview.py +50 -1
  102. wagtail/admin/views/mixins.py +4 -2
  103. wagtail/admin/views/pages/bulk_actions/delete.py +11 -23
  104. wagtail/admin/views/pages/bulk_actions/page_bulk_action.py +17 -0
  105. wagtail/admin/views/pages/bulk_actions/publish.py +11 -31
  106. wagtail/admin/views/pages/bulk_actions/unpublish.py +11 -31
  107. wagtail/admin/views/pages/create.py +1 -0
  108. wagtail/admin/views/pages/edit.py +38 -30
  109. wagtail/admin/views/pages/revisions.py +43 -114
  110. wagtail/admin/views/pages/utils.py +0 -1
  111. wagtail/admin/views/tags.py +6 -2
  112. wagtail/admin/views/workflows.py +8 -6
  113. wagtail/admin/viewsets/model.py +0 -4
  114. wagtail/admin/viewsets/pages.py +0 -1
  115. wagtail/admin/widgets/tags.py +1 -0
  116. wagtail/api/v2/tests/test_documents.py +4 -2
  117. wagtail/api/v2/tests/test_images.py +4 -2
  118. wagtail/api/v2/tests/test_pages.py +8 -4
  119. wagtail/blocks/base.py +59 -1
  120. wagtail/blocks/field_block.py +6 -0
  121. wagtail/blocks/list_block.py +4 -0
  122. wagtail/blocks/static_block.py +3 -0
  123. wagtail/blocks/stream_block.py +5 -1
  124. wagtail/blocks/struct_block.py +6 -0
  125. wagtail/compat.py +16 -0
  126. wagtail/contrib/forms/forms.py +27 -7
  127. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +2 -2
  128. wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.mo +0 -0
  129. wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.po +4 -4
  130. wagtail/contrib/forms/tests/test_models.py +7 -5
  131. wagtail/contrib/forms/tests/test_views.py +75 -0
  132. wagtail/contrib/frontend_cache/backends/cloudfront.py +1 -1
  133. wagtail/contrib/frontend_cache/tasks.py +83 -0
  134. wagtail/contrib/frontend_cache/tests.py +48 -33
  135. wagtail/contrib/frontend_cache/utils.py +2 -70
  136. wagtail/contrib/redirects/base_formats.py +2 -2
  137. wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.mo +0 -0
  138. wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +3 -0
  139. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +24 -37
  140. wagtail/contrib/redirects/templates/wagtailredirects/add.html +1 -24
  141. wagtail/contrib/redirects/templates/wagtailredirects/confirm_delete.html +3 -13
  142. wagtail/contrib/redirects/tests/test_redirects.py +122 -110
  143. wagtail/contrib/redirects/tests/test_signal_handlers.py +75 -69
  144. wagtail/contrib/redirects/urls.py +2 -2
  145. wagtail/contrib/redirects/views.py +35 -73
  146. wagtail/contrib/search_promotions/admin_urls.py +10 -3
  147. wagtail/contrib/search_promotions/forms.py +55 -26
  148. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +44 -54
  149. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/add.html +21 -31
  150. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/confirm_delete.html +3 -12
  151. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/edit.html +11 -34
  152. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotion_form.html +1 -0
  153. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js +2 -1
  154. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +0 -1
  155. wagtail/contrib/search_promotions/tests.py +814 -13
  156. wagtail/contrib/search_promotions/views/__init__.py +1 -0
  157. wagtail/contrib/search_promotions/views/reports.py +56 -0
  158. wagtail/contrib/search_promotions/views/settings.py +258 -0
  159. wagtail/contrib/search_promotions/wagtail_hooks.py +12 -1
  160. wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.mo +0 -0
  161. wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.po +6 -1
  162. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
  163. wagtail/contrib/settings/templates/wagtailsettings/edit.html +1 -5
  164. wagtail/contrib/settings/tests/generic/test_admin.py +2 -5
  165. wagtail/contrib/settings/tests/generic/test_register.py +1 -1
  166. wagtail/contrib/settings/tests/site_specific/test_admin.py +2 -5
  167. wagtail/contrib/settings/tests/site_specific/test_register.py +1 -1
  168. wagtail/contrib/settings/views.py +9 -23
  169. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  170. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
  171. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  172. wagtail/contrib/table_block/tests.py +4 -1
  173. wagtail/contrib/typed_table_block/blocks.py +3 -0
  174. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  175. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  176. wagtail/contrib/typed_table_block/tests.py +33 -0
  177. wagtail/documents/locale/en/LC_MESSAGES/django.po +26 -26
  178. wagtail/documents/migrations/0011_add_choose_permissions.py +1 -0
  179. wagtail/documents/models.py +1 -0
  180. wagtail/documents/signal_handlers.py +6 -2
  181. wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
  182. wagtail/documents/templates/wagtaildocs/documents/edit.html +1 -3
  183. wagtail/documents/templates/wagtaildocs/multiple/add.html +7 -1
  184. wagtail/documents/tests/test_admin_views.py +74 -33
  185. wagtail/documents/tests/test_views.py +21 -12
  186. wagtail/documents/views/chooser.py +1 -0
  187. wagtail/documents/views/documents.py +1 -2
  188. wagtail/documents/views/multiple.py +0 -1
  189. wagtail/documents/views/serve.py +9 -2
  190. wagtail/documents/wagtail_hooks.py +6 -1
  191. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  192. wagtail/embeds/oembed_providers.py +0 -64
  193. wagtail/fields.py +3 -0
  194. wagtail/images/apps.py +2 -1
  195. wagtail/images/blocks.py +14 -2
  196. wagtail/images/forms.py +40 -3
  197. wagtail/images/locale/ar/LC_MESSAGES/django.mo +0 -0
  198. wagtail/images/locale/ar/LC_MESSAGES/django.po +4 -0
  199. wagtail/images/locale/en/LC_MESSAGES/django.po +49 -49
  200. wagtail/images/migrations/0023_add_choose_permissions.py +1 -0
  201. wagtail/images/rich_text/contentstate.py +1 -0
  202. wagtail/images/rich_text/editor_html.py +1 -0
  203. wagtail/images/signal_handlers.py +17 -10
  204. wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
  205. wagtail/images/static/wagtailimages/js/image-block.js +1 -1
  206. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  207. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  208. wagtail/images/static/wagtailimages/js/image-url-generator.js +1 -1
  209. wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
  210. wagtail/images/tasks.py +18 -0
  211. wagtail/images/templates/wagtailimages/images/edit.html +1 -3
  212. wagtail/images/templates/wagtailimages/images/url_generator.html +1 -1
  213. wagtail/images/templates/wagtailimages/multiple/add.html +7 -2
  214. wagtail/images/templates/wagtailimages/widgets/image_chooser.html +1 -1
  215. wagtail/images/tests/test_admin_views.py +53 -29
  216. wagtail/images/tests/test_blocks.py +34 -2
  217. wagtail/images/tests/test_models.py +12 -10
  218. wagtail/images/tests/tests.py +10 -0
  219. wagtail/images/views/chooser.py +1 -0
  220. wagtail/images/views/images.py +1 -3
  221. wagtail/images/views/multiple.py +0 -1
  222. wagtail/images/views/serve.py +18 -2
  223. wagtail/images/widgets.py +3 -0
  224. wagtail/locale/en/LC_MESSAGES/django.po +228 -216
  225. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  226. wagtail/management/commands/publish_scheduled.py +1 -1
  227. wagtail/migrations/0087_alter_grouppagepermission_unique_together_and_more.py +16 -8
  228. wagtail/models/__init__.py +300 -119
  229. wagtail/models/i18n.py +2 -2
  230. wagtail/models/panels.py +37 -0
  231. wagtail/models/sites.py +7 -6
  232. wagtail/permission_policies/pages.py +2 -2
  233. wagtail/project_template/project_name/settings/base.py +4 -0
  234. wagtail/project_template/requirements.txt +1 -1
  235. wagtail/query.py +145 -0
  236. wagtail/search/backends/database/mysql/mysql.py +25 -17
  237. wagtail/search/backends/database/postgres/postgres.py +44 -83
  238. wagtail/search/backends/database/sqlite/sqlite.py +25 -17
  239. wagtail/search/backends/elasticsearch7.py +4 -0
  240. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  241. wagtail/search/query.py +8 -2
  242. wagtail/search/signal_handlers.py +6 -9
  243. wagtail/search/tasks.py +10 -0
  244. wagtail/search/tests/test_elasticsearch7_backend.py +21 -0
  245. wagtail/search/tests/test_index_functions.py +10 -6
  246. wagtail/search/tests/test_postgres_backend.py +0 -14
  247. wagtail/signal_handlers.py +5 -20
  248. wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
  249. wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -13
  250. wagtail/snippets/locale/sv/LC_MESSAGES/django.mo +0 -0
  251. wagtail/snippets/locale/sv/LC_MESSAGES/django.po +4 -3
  252. wagtail/snippets/tests/test_preview.py +5 -0
  253. wagtail/snippets/tests/test_snippets.py +100 -45
  254. wagtail/snippets/tests/test_usage.py +29 -24
  255. wagtail/snippets/tests/test_viewset.py +1 -1
  256. wagtail/snippets/views/snippets.py +0 -12
  257. wagtail/tasks.py +41 -0
  258. wagtail/templates/wagtailcore/shared/block_preview.html +29 -0
  259. wagtail/test/earlypage/__init__.py +0 -0
  260. wagtail/test/earlypage/migrations/0001_initial.py +37 -0
  261. wagtail/test/earlypage/migrations/__init__.py +0 -0
  262. wagtail/test/earlypage/models.py +14 -0
  263. wagtail/test/settings.py +3 -0
  264. wagtail/test/testapp/fixtures/test.json +7 -0
  265. wagtail/test/testapp/fixtures/test_specific.json +6 -3
  266. wagtail/test/testapp/models.py +58 -44
  267. wagtail/test/testapp/templates/tests/custom_block_preview.html +16 -0
  268. wagtail/test/testapp/templates/tests/static_block_preview.html +5 -0
  269. wagtail/test/testapp/wagtail_hooks.py +9 -0
  270. wagtail/tests/test_blocks.py +189 -2
  271. wagtail/tests/test_hooks.py +166 -1
  272. wagtail/tests/test_management_commands.py +54 -13
  273. wagtail/tests/test_page_allowed_http_methods.py +32 -0
  274. wagtail/tests/test_page_model.py +68 -0
  275. wagtail/tests/test_page_privacy.py +10 -0
  276. wagtail/tests/test_page_queryset.py +79 -0
  277. wagtail/tests/test_reference_index.py +84 -75
  278. wagtail/tests/test_streamfield.py +30 -0
  279. wagtail/tests/test_utils.py +61 -0
  280. wagtail/users/forms.py +2 -9
  281. wagtail/users/locale/en/LC_MESSAGES/django.po +17 -17
  282. wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
  283. wagtail/users/locale/nl/LC_MESSAGES/django.po +4 -3
  284. wagtail/users/templates/wagtailusers/groups/create.html +0 -5
  285. wagtail/users/templates/wagtailusers/groups/includes/page_permissions_form.html +1 -1
  286. wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.html +6 -6
  287. wagtail/users/tests/test_admin_views.py +96 -4
  288. wagtail/users/tests/test_utils.py +76 -0
  289. wagtail/users/utils.py +43 -11
  290. wagtail/utils/setup.py +2 -2
  291. wagtail/utils/templates.py +26 -0
  292. wagtail/utils/widgets.py +1 -0
  293. wagtail/views.py +9 -1
  294. wagtail/wagtail_hooks.py +67 -29
  295. {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/METADATA +2 -2
  296. {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/RECORD +300 -287
  297. wagtail/admin/static/wagtailadmin/js/expanding-formset.js +0 -1
  298. wagtail/admin/static/wagtailadmin/js/vendor/rangy-core.js +0 -1
  299. wagtail/admin/static/wagtailadmin/js/vendor/uuidv4.min.js +0 -1
  300. wagtail/contrib/search_promotions/views.py +0 -323
  301. wagtail/images/static/wagtailimages/js/vendor/canvas-to-blob.min.js +0 -1
  302. wagtail/users/static/wagtailusers/js/group-form.js +0 -1
  303. wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
  304. {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/LICENSE +0 -0
  305. {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/WHEEL +0 -0
  306. {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/entry_points.txt +0 -0
  307. {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/top_level.txt +0 -0
wagtail/__init__.py CHANGED
@@ -6,7 +6,7 @@ from wagtail.utils.version import get_semver_version, get_version
6
6
 
7
7
  # major.minor.patch.release.number
8
8
  # release must be one of alpha, beta, rc, or final
9
- VERSION = (6, 3, 1, "final", 1)
9
+ VERSION = (6, 4, 0, "rc", 1)
10
10
 
11
11
  __version__ = get_version(VERSION)
12
12
 
@@ -94,9 +94,8 @@ class PublishRevisionAction:
94
94
  )
95
95
 
96
96
  if isinstance(self.object, WorkflowMixin):
97
- workflow_state = self.object.current_workflow_state
98
- if workflow_state and getattr(
99
- settings, "WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH", True
97
+ if getattr(settings, "WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH", True) and (
98
+ workflow_state := self.object.current_workflow_state
100
99
  ):
101
100
  workflow_state.cancel(user=self.user)
102
101
 
@@ -115,11 +114,11 @@ class PublishRevisionAction:
115
114
  object.has_unpublished_changes = True
116
115
  # Instead set the approved_go_live_at of this revision
117
116
  revision.approved_go_live_at = object.go_live_at
118
- revision.save()
117
+ revision.save(update_fields=["approved_go_live_at"])
119
118
  # And clear the approved_go_live_at of any other revisions
120
119
  object.revisions.exclude(id=revision.id).update(approved_go_live_at=None)
121
120
  # if we are updating a currently live object skip the rest
122
- if object.live_revision:
121
+ if object.live_revision_id:
123
122
  # Log scheduled publishing
124
123
  if log_action:
125
124
  self.log_scheduling_action()
wagtail/admin/auth.py CHANGED
@@ -1,7 +1,6 @@
1
1
  import types
2
2
  from functools import wraps
3
3
 
4
- import l18n
5
4
  from django.conf import settings
6
5
  from django.core.exceptions import PermissionDenied
7
6
  from django.shortcuts import redirect
@@ -141,7 +140,6 @@ def require_admin_access(view_func):
141
140
  preferred_language = (
142
141
  user.wagtail_userprofile.get_preferred_language()
143
142
  )
144
- l18n.set_language(preferred_language)
145
143
  time_zone = user.wagtail_userprofile.get_current_time_zone()
146
144
  else:
147
145
  time_zone = settings.TIME_ZONE
wagtail/admin/checks.py CHANGED
@@ -152,7 +152,7 @@ There are no tabs on non-Page model editing within InlinePanels.""".format(
152
152
  class_name, panel_name
153
153
  )
154
154
  else:
155
- error_hint = """Ensure that {} uses `panels` instead of `{}`\
155
+ error_hint = """Ensure that {} uses `panels` instead of `{}` \
156
156
  or set up an `edit_handler` if you want a tabbed editing interface.
157
157
  There are no default tabs on non-Page models so there will be no \
158
158
  {} tab for the {} to render in.""".format(
wagtail/admin/filters.py CHANGED
@@ -10,6 +10,7 @@ from wagtail.admin.models import popular_tags_for_model
10
10
  from wagtail.admin.utils import get_user_display_name
11
11
  from wagtail.admin.widgets import AdminDateInput, BooleanRadioSelect, FilteredSelect
12
12
  from wagtail.coreutils import get_content_languages, get_content_type_label
13
+ from wagtail.models import Locale
13
14
 
14
15
 
15
16
  class DateRangePickerWidget(SuffixedMultiWidget):
@@ -93,7 +94,8 @@ class FilteredModelChoiceFilter(django_filters.ModelChoiceFilter):
93
94
  class LocaleFilter(django_filters.ChoiceFilter):
94
95
  def filter(self, qs, language_code):
95
96
  if language_code:
96
- return qs.filter(locale__language_code=language_code)
97
+ locale = Locale.objects.filter(language_code=language_code)
98
+ return qs.filter(locale_id=locale.values_list("pk", flat=True)[:1])
97
99
  return qs
98
100
 
99
101
 
@@ -1,10 +1,8 @@
1
1
  import warnings
2
- from operator import itemgetter
3
2
 
4
- import l18n
5
3
  from django import forms
4
+ from django.conf import settings
6
5
  from django.contrib.auth import get_user_model
7
- from django.db.models.fields import BLANK_CHOICE_DASH
8
6
  from django.utils.translation import get_language_info
9
7
  from django.utils.translation import gettext_lazy as _
10
8
 
@@ -52,19 +50,22 @@ def _get_language_choices():
52
50
  (lang_code, get_language_info(lang_code)["name_local"])
53
51
  for lang_code, lang_name in get_available_admin_languages()
54
52
  ]
55
- return sorted(
56
- BLANK_CHOICE_DASH + language_choices,
53
+ server_language = get_language_info(settings.LANGUAGE_CODE)["name_local"]
54
+ default = (
55
+ "",
56
+ _("Use server language: %(language_name)s")
57
+ % {"language_name": server_language},
58
+ )
59
+ return [default] + sorted(
60
+ language_choices,
57
61
  key=lambda language_choice: language_choice[1].lower(),
58
62
  )
59
63
 
60
64
 
61
65
  def _get_time_zone_choices():
62
- time_zones = [
63
- (tz, str(l18n.tz_fullnames.get(tz, tz)))
64
- for tz in get_available_admin_time_zones()
66
+ return [("", _("Use server time zone"))] + [
67
+ (tz, tz) for tz in get_available_admin_time_zones()
65
68
  ]
66
- time_zones.sort(key=itemgetter(1))
67
- return BLANK_CHOICE_DASH + time_zones
68
69
 
69
70
 
70
71
  class LocalePreferencesForm(forms.ModelForm):
@@ -82,7 +83,16 @@ class LocalePreferencesForm(forms.ModelForm):
82
83
  )
83
84
 
84
85
  current_time_zone = forms.ChoiceField(
85
- required=False, choices=_get_time_zone_choices, label=_("Current time zone")
86
+ required=False,
87
+ choices=_get_time_zone_choices,
88
+ label=_("Current time zone"),
89
+ widget=forms.Select(
90
+ attrs={
91
+ "data-controller": "w-init w-locale",
92
+ "data-action": "w-init:ready->w-locale#localizeTimeZoneOptions",
93
+ "data-w-locale-server-time-zone-param": settings.TIME_ZONE,
94
+ },
95
+ ),
86
96
  )
87
97
 
88
98
  class Meta:
@@ -10,6 +10,7 @@ from django.template.loader import render_to_string
10
10
  from django.utils.translation import gettext as _
11
11
  from django.utils.translation import gettext_lazy
12
12
 
13
+ from wagtail.admin.forms.formsets import BaseFormSetMixin
13
14
  from wagtail.models import (
14
15
  Collection,
15
16
  CollectionViewRestriction,
@@ -178,7 +179,7 @@ class BaseCollectionMemberForm(forms.ModelForm):
178
179
  return super().save(commit=commit)
179
180
 
180
181
 
181
- class BaseGroupCollectionMemberPermissionFormSet(forms.BaseFormSet):
182
+ class BaseGroupCollectionMemberPermissionFormSet(BaseFormSetMixin, forms.BaseFormSet):
182
183
  """
183
184
  A base formset class for managing GroupCollectionPermissions for a
184
185
  model with CollectionMember behaviour. Subclasses should provide attributes:
@@ -223,14 +224,6 @@ class BaseGroupCollectionMemberPermissionFormSet(forms.BaseFormSet):
223
224
  )
224
225
 
225
226
  super().__init__(data, files, initial=initial_data, prefix=prefix)
226
- for form in self.forms:
227
- form.fields["DELETE"].widget = forms.HiddenInput()
228
-
229
- @property
230
- def empty_form(self):
231
- empty_form = super().empty_form
232
- empty_form.fields["DELETE"].widget = forms.HiddenInput()
233
- return empty_form
234
227
 
235
228
  def clean(self):
236
229
  """Checks that no two forms refer to the same collection object"""
@@ -0,0 +1,32 @@
1
+ from django import forms
2
+
3
+
4
+ class BaseFormSetMixin:
5
+ """
6
+ A mixin for formsets that adds the necessary attributes for the w-formset controller.
7
+ So that JavaScript behavior can be added to the formset for dynamic addition and deletion of child forms.
8
+ See client/src/controllers/FormsetController.ts
9
+ """
10
+
11
+ deletion_widget = forms.HiddenInput(attrs={"data-w-formset-target": "deleteInput"})
12
+
13
+ @property
14
+ def attrs(self):
15
+ return {
16
+ "data-controller": "w-formset",
17
+ "data-w-formset-deleted-class": "w-transition-opacity w-duration-300 w-ease-out w-opacity-0",
18
+ }
19
+
20
+ @property
21
+ def management_form(self):
22
+ form = super().management_form
23
+
24
+ for field in form:
25
+ if field.name.endswith(forms.formsets.TOTAL_FORM_COUNT):
26
+ field.field.widget.attrs["data-w-formset-target"] = "totalFormsInput"
27
+ if field.name.endswith(forms.formsets.MIN_NUM_FORM_COUNT):
28
+ field.field.widget.attrs["data-w-formset-target"] = "minFormsInput"
29
+ if field.name.endswith(forms.formsets.MAX_NUM_FORM_COUNT):
30
+ field.field.widget.attrs["data-w-formset-target"] = "maxFormsInput"
31
+
32
+ return form
@@ -30,7 +30,11 @@ class CopyForm(forms.Form):
30
30
  self.fields["new_parent_page"] = forms.ModelChoiceField(
31
31
  initial=self.page.get_parent(),
32
32
  queryset=Page.objects.all(),
33
- widget=widgets.AdminPageChooser(can_choose_root=True, user_perms="copy_to"),
33
+ widget=widgets.AdminPageChooser(
34
+ target_models=self.page.specific_class.allowed_parent_page_models(),
35
+ can_choose_root=True,
36
+ user_perms="copy_to",
37
+ ),
34
38
  label=_("New parent page"),
35
39
  help_text=_("This copy will be a child of this given parent page."),
36
40
  )
@@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy
10
10
 
11
11
  from wagtail.admin import widgets
12
12
  from wagtail.admin.forms import WagtailAdminModelForm
13
+ from wagtail.admin.forms.formsets import BaseFormSetMixin
13
14
  from wagtail.admin.panels import FieldPanel, InlinePanel, ObjectList
14
15
  from wagtail.admin.widgets.workflows import AdminTaskChooser
15
16
  from wagtail.coreutils import get_content_type_label, get_model_string
@@ -121,19 +122,7 @@ class WorkflowPageForm(forms.ModelForm):
121
122
  )
122
123
 
123
124
 
124
- class BaseWorkflowPagesFormSet(forms.BaseInlineFormSet):
125
- def __init__(self, *args, **kwargs):
126
- super().__init__(*args, **kwargs)
127
-
128
- for form in self.forms:
129
- form.fields["DELETE"].widget = forms.HiddenInput()
130
-
131
- @property
132
- def empty_form(self):
133
- empty_form = super().empty_form
134
- empty_form.fields["DELETE"].widget = forms.HiddenInput()
135
- return empty_form
136
-
125
+ class BaseWorkflowPagesFormSet(BaseFormSetMixin, forms.BaseInlineFormSet):
137
126
  def clean(self):
138
127
  """Checks that no two forms refer to the same page object"""
139
128
  if any(self.errors):
@@ -13,6 +13,7 @@
13
13
  # Mohamed Mayla <mohamed.mayla@gmail.com>, 2015
14
14
  # Mohammed Abdul gadir <weekmo@aol.com>, 2019
15
15
  # ROGER MICHAEL ASHLEY ALLEN <rogermaallen@gmail.com>, 2015
16
+ # Tarek Berkane, 2025
16
17
  # ultraify media <ultraify@gmail.com>, 2018
17
18
  # Waseem Kntar, 2023
18
19
  # Younes Oumakhou, 2022
@@ -23,7 +24,7 @@ msgstr ""
23
24
  "Report-Msgid-Bugs-To: \n"
24
25
  "POT-Creation-Date: 2024-10-21 17:53+0100\n"
25
26
  "PO-Revision-Date: 2014-02-21 15:50+0000\n"
26
- "Last-Translator: Mahmoud Marayef, 2023\n"
27
+ "Last-Translator: Tarek Berkane, 2025\n"
27
28
  "Language-Team: Arabic (http://app.transifex.com/torchbox/wagtail/language/"
28
29
  "ar/)\n"
29
30
  "MIME-Version: 1.0\n"
@@ -84,6 +85,9 @@ msgstr "التاريخ من"
84
85
  msgid "Date to"
85
86
  msgstr "تاريخ لـ"
86
87
 
88
+ msgid "Locale"
89
+ msgstr "الإعدادات المحلية"
90
+
87
91
  msgid "All"
88
92
  msgstr "الكل"
89
93
 
@@ -352,6 +356,12 @@ msgstr "أكملت إعادة تثبيت كلمة السر"
352
356
  msgid "Reset your password"
353
357
  msgstr "أعد تثبيت كلمةتك السرية"
354
358
 
359
+ msgid "Reset to default"
360
+ msgstr "إعادة التعيين إلى الوضع الافتراضي"
361
+
362
+ msgid "Default avatar"
363
+ msgstr "الصورة الرمزية الافتراضية"
364
+
355
365
  msgid "Upload a profile picture:"
356
366
  msgstr "رَفع صورة الملف الشخصي"
357
367
 
@@ -361,6 +371,9 @@ msgstr "الشريط الجانبي"
361
371
  msgid "Go back"
362
372
  msgstr "رجوع"
363
373
 
374
+ msgid "Select"
375
+ msgstr "إختر"
376
+
364
377
  msgid "Select row"
365
378
  msgstr "تحديد صف"
366
379
 
@@ -395,6 +408,15 @@ msgstr "اختر"
395
408
  msgid "Choose a page"
396
409
  msgstr "اختر صفحة"
397
410
 
411
+ msgid "Confirm selection"
412
+ msgstr "تأكيد الاختيار"
413
+
414
+ msgid "Convert to internal link"
415
+ msgstr "حول إلى رابط داخلي"
416
+
417
+ msgid "Use external link"
418
+ msgstr "إستعمل رابط خارجي"
419
+
398
420
  msgid "Add an email link"
399
421
  msgstr "أضف حلقة إلكترونية"
400
422
 
@@ -404,6 +426,13 @@ msgstr "أدخل حلقة"
404
426
  msgid "Add an external link"
405
427
  msgstr "أضف حلقة خارجية"
406
428
 
429
+ msgid "Add a phone link"
430
+ msgstr "أضف رابط الهاتف"
431
+
432
+ #, python-format
433
+ msgid "Select %(title)s"
434
+ msgstr "إختر %(title)s"
435
+
407
436
  #, python-format
408
437
  msgid "Explore subpages of '%(title)s'"
409
438
  msgstr "استكشف الصفحات الفرعية %(title)s"
@@ -420,6 +449,9 @@ msgstr "يمكنك تحرير إعدادات الخصوصية على:"
420
449
  msgid "Save"
421
450
  msgstr "احفظ"
422
451
 
452
+ msgid "Change privacy"
453
+ msgstr "تغيير إعدادات الخصوصية"
454
+
423
455
  msgid ""
424
456
  "Privacy settings determine who is able to view documents in this collection."
425
457
  msgstr "تحدد إعدادات الخصوصية من يمكنه عرض المستندات في هذه المجموعة."
@@ -445,6 +477,9 @@ msgstr ""
445
477
  "لم يتم إنشاء أي مجموعات. لماذا لا <a href=\"%(add_collection_url)s\">تضيف "
446
478
  "واحدة</a>؟"
447
479
 
480
+ msgid "There are no results."
481
+ msgstr "لا توجد نتائج."
482
+
448
483
  msgid "Yes, delete"
449
484
  msgstr "نعم احذف"
450
485
 
@@ -461,6 +496,13 @@ msgstr "نعك ألغ نشره"
461
496
  msgid "No, don't unpublish"
462
497
  msgstr "لا ,ألغ النشر"
463
498
 
499
+ #, python-format
500
+ msgid "Would you still like to publish this %(model_name)s?"
501
+ msgstr "هل مازلت تود نشر %(model_name)s ؟"
502
+
503
+ msgid "Cancel"
504
+ msgstr "إلغاء"
505
+
464
506
  msgid "Actions"
465
507
  msgstr "النشاطات"
466
508
 
@@ -499,6 +541,9 @@ msgstr "صفحاتُك المقفلة"
499
541
  msgid "Status"
500
542
  msgstr "رتبة"
501
543
 
544
+ msgid "Locked at"
545
+ msgstr "تم الغلق في"
546
+
502
547
  msgid "Edit this page"
503
548
  msgstr "حرر هذه الصفحة"
504
549
 
@@ -877,6 +922,15 @@ msgstr "Bold"
877
922
  msgid "Italic"
878
923
  msgstr "Italic"
879
924
 
925
+ msgid "Profile"
926
+ msgstr "الملف الشخصي"
927
+
928
+ msgid "Name and Email"
929
+ msgstr "الإسم و البريد الإلكتروني"
930
+
931
+ msgid "Profile picture"
932
+ msgstr "صورة الملف الشخصي"
933
+
880
934
  msgid "Password"
881
935
  msgstr "كلمة السر"
882
936
 
@@ -1096,6 +1150,19 @@ msgstr "كود"
1096
1150
  msgid "Reports"
1097
1151
  msgstr "التقارير"
1098
1152
 
1153
+ #, python-format
1154
+ msgid "What's new in Wagtail %(version)s"
1155
+ msgstr "ما الجديد في Wagtail %(version)s"
1156
+
1157
+ msgid "Editor Guide"
1158
+ msgstr "دليل المحرر"
1159
+
1160
+ msgid "Shortcuts"
1161
+ msgstr "إختصارات"
1162
+
1163
+ msgid "Help"
1164
+ msgstr "المساعدة"
1165
+
1099
1166
  msgid "Choose an item"
1100
1167
  msgstr "اختيار عنصر"
1101
1168
 
@@ -6,10 +6,11 @@
6
6
  # ultraify media <ultraify@gmail.com>, 2022
7
7
  # Younes Oumakhou, 2022
8
8
  # Loic Teixeira, 2024
9
+ # Tarek Berkane, 2025
9
10
  #
10
11
  msgid ""
11
12
  msgstr ""
12
- "Last-Translator: Loic Teixeira, 2024\n"
13
+ "Last-Translator: Tarek Berkane, 2025\n"
13
14
  "Language-Team: Arabic (https://app.transifex.com/torchbox/teams/8009/ar/)\n"
14
15
  "Content-Type: text/plain; charset=UTF-8\n"
15
16
  "Language: ar\n"
@@ -22,6 +23,9 @@ msgstr "نص للمساعدة"
22
23
  msgid "Broken link"
23
24
  msgstr "رابط معطوب"
24
25
 
26
+ msgid "Cancel"
27
+ msgstr "إلغاء"
28
+
25
29
  msgid "Close"
26
30
  msgstr "اغلاق"
27
31