wagtail 6.0.1__py3-none-any.whl → 6.1rc1__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 (512) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/admin/checks.py +51 -0
  3. wagtail/admin/compare.py +1 -1
  4. wagtail/admin/filters.py +70 -1
  5. wagtail/admin/forms/account.py +1 -1
  6. wagtail/admin/forms/collections.py +15 -0
  7. wagtail/admin/forms/pages.py +49 -0
  8. wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
  9. wagtail/admin/locale/ca/LC_MESSAGES/django.po +122 -0
  10. wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
  11. wagtail/admin/locale/de/LC_MESSAGES/django.po +5 -5
  12. wagtail/admin/locale/en/LC_MESSAGES/django.po +474 -385
  13. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +3 -3
  14. wagtail/admin/locale/es/LC_MESSAGES/django.mo +0 -0
  15. wagtail/admin/locale/es/LC_MESSAGES/django.po +6 -6
  16. wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
  17. wagtail/admin/locale/fr/LC_MESSAGES/django.po +70 -3
  18. wagtail/admin/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  19. wagtail/admin/locale/he_IL/LC_MESSAGES/django.po +2 -6
  20. wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.mo +0 -0
  21. wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.po +2 -2
  22. wagtail/admin/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  23. wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +4 -0
  24. wagtail/admin/locale/hu/LC_MESSAGES/django.mo +0 -0
  25. wagtail/admin/locale/hu/LC_MESSAGES/django.po +142 -2
  26. wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
  27. wagtail/admin/locale/it/LC_MESSAGES/django.po +80 -8
  28. wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
  29. wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +14 -2
  30. wagtail/admin/locale/lv/LC_MESSAGES/django.mo +0 -0
  31. wagtail/admin/locale/lv/LC_MESSAGES/django.po +154 -1
  32. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  33. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +73 -2
  34. wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
  35. wagtail/admin/locale/ro/LC_MESSAGES/django.po +3 -3
  36. wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
  37. wagtail/admin/locale/sl/LC_MESSAGES/django.po +145 -2
  38. wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
  39. wagtail/admin/locale/sv/LC_MESSAGES/django.po +77 -3
  40. wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
  41. wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +17 -1
  42. wagtail/admin/panels/comment_panel.py +1 -1
  43. wagtail/admin/panels/field_panel.py +1 -1
  44. wagtail/admin/rich_text/converters/editor_html.py +3 -1
  45. wagtail/admin/rich_text/editors/draftail/__init__.py +28 -2
  46. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  47. wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
  48. wagtail/admin/static/wagtailadmin/images/favicon.ico +0 -0
  49. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  50. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  51. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  52. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  53. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  54. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  55. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -1
  56. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  57. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  58. wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
  59. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  60. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  61. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  62. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  63. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  64. wagtail/admin/static/wagtailadmin/js/preview-panel.js +1 -1
  65. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  66. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  67. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  68. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  69. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  70. wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
  71. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  72. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  73. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  74. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +4 -4
  75. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  76. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  77. wagtail/admin/staticfiles.py +1 -0
  78. wagtail/admin/templates/wagtailadmin/admin_base.html +1 -0
  79. wagtail/admin/templates/wagtailadmin/base.html +1 -0
  80. wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +3 -1
  81. wagtail/admin/templates/wagtailadmin/collections/edit.html +0 -1
  82. wagtail/admin/templates/wagtailadmin/collections/index_results.html +10 -0
  83. wagtail/admin/templates/wagtailadmin/generic/base.html +1 -9
  84. wagtail/admin/templates/wagtailadmin/generic/form.html +4 -2
  85. wagtail/admin/templates/wagtailadmin/generic/history/action_cell.html +27 -0
  86. wagtail/admin/templates/wagtailadmin/generic/index_results.html +8 -0
  87. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +3 -4
  88. wagtail/admin/templates/wagtailadmin/icons/keyboard.svg +1 -0
  89. wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +3 -1
  90. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -15
  91. wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +3 -1
  92. wagtail/admin/templates/wagtailadmin/pages/choose_parent.html +17 -0
  93. wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +8 -0
  94. wagtail/admin/templates/wagtailadmin/pages/history.html +1 -61
  95. wagtail/admin/templates/wagtailadmin/pages/index.html +1 -5
  96. wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +2 -2
  97. wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +25 -27
  98. wagtail/admin/templates/wagtailadmin/pages/page_listing_header.html +2 -1
  99. wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
  100. wagtail/admin/templates/wagtailadmin/panels/publishing/schedule_publishing_panel.html +3 -1
  101. wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +1 -1
  102. wagtail/admin/templates/wagtailadmin/shared/active_filters.html +2 -1
  103. wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +8 -0
  104. wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
  105. wagtail/admin/templates/wagtailadmin/shared/headers/page_edit_header.html +1 -1
  106. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +21 -9
  107. wagtail/admin/templates/wagtailadmin/shared/human_readable_date.html +1 -1
  108. wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +29 -0
  109. wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +2 -1
  110. wagtail/admin/templates/wagtailadmin/skeleton.html +2 -1
  111. wagtail/admin/templates/wagtailadmin/tables/related_objects_cell.html +9 -0
  112. wagtail/admin/templates/wagtailadmin/tables/title_cell.html +9 -7
  113. wagtail/admin/templates/wagtailadmin/widgets/draftail_rich_text_area.html +1 -1
  114. wagtail/admin/templates/wagtailadmin/workflows/create.html +6 -23
  115. wagtail/admin/templates/wagtailadmin/workflows/create_task.html +6 -15
  116. wagtail/admin/templates/wagtailadmin/workflows/edit.html +6 -23
  117. wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +6 -13
  118. wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -4
  119. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +18 -0
  120. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_title_cell.html +7 -0
  121. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +25 -0
  122. wagtail/admin/templates/wagtailadmin/workflows/index.html +0 -99
  123. wagtail/admin/templates/wagtailadmin/workflows/index_results.html +10 -0
  124. wagtail/admin/templates/wagtailadmin/workflows/task_index.html +0 -30
  125. wagtail/admin/templates/wagtailadmin/workflows/task_index_results.html +10 -0
  126. wagtail/admin/templates/wagtailadmin/workflows/usage.html +1 -1
  127. wagtail/admin/templatetags/wagtailadmin_tags.py +116 -39
  128. wagtail/admin/tests/api/test_pages.py +26 -10
  129. wagtail/admin/tests/pages/test_create_page.py +10 -4
  130. wagtail/admin/tests/pages/test_custom_listing.py +37 -0
  131. wagtail/admin/tests/pages/test_edit_page.py +6 -6
  132. wagtail/admin/tests/pages/test_explorer_view.py +19 -18
  133. wagtail/admin/tests/pages/test_move_page.py +1 -1
  134. wagtail/admin/tests/pages/test_page_usage.py +50 -2
  135. wagtail/admin/tests/pages/test_parent_page_chooser_view.py +119 -0
  136. wagtail/admin/tests/pages/test_preview.py +18 -4
  137. wagtail/admin/tests/test_account_management.py +20 -1
  138. wagtail/admin/tests/test_audit_log.py +172 -5
  139. wagtail/admin/tests/test_checks.py +92 -0
  140. wagtail/admin/tests/test_collections_views.py +19 -5
  141. wagtail/admin/tests/test_compare.py +6 -6
  142. wagtail/admin/tests/test_dashboard.py +404 -0
  143. wagtail/admin/tests/test_dbwhitelister.py +4 -5
  144. wagtail/admin/tests/test_edit_handlers.py +2 -2
  145. wagtail/admin/tests/test_keyboard_shortcuts.py +84 -0
  146. wagtail/admin/tests/test_page_chooser.py +31 -18
  147. wagtail/admin/tests/test_privacy.py +36 -2
  148. wagtail/admin/tests/test_rich_text.py +168 -23
  149. wagtail/admin/tests/test_templatetags.py +411 -43
  150. wagtail/admin/tests/test_views.py +4 -2
  151. wagtail/admin/tests/test_workflows.py +531 -9
  152. wagtail/admin/tests/tests.py +3 -1
  153. wagtail/admin/tests/ui/test_tables.py +48 -1
  154. wagtail/admin/tests/viewsets/test_model_viewset.py +130 -23
  155. wagtail/admin/ui/side_panels.py +3 -1
  156. wagtail/admin/ui/tables/__init__.py +13 -1
  157. wagtail/admin/ui/tables/pages.py +17 -6
  158. wagtail/admin/urls/__init__.py +8 -3
  159. wagtail/admin/urls/pages.py +5 -0
  160. wagtail/admin/urls/workflows.py +10 -0
  161. wagtail/admin/views/chooser.py +20 -24
  162. wagtail/admin/views/collections.py +17 -1
  163. wagtail/admin/views/generic/base.py +34 -4
  164. wagtail/admin/views/generic/history.py +220 -51
  165. wagtail/admin/views/generic/mixins.py +7 -4
  166. wagtail/admin/views/generic/models.py +54 -47
  167. wagtail/admin/views/generic/multiple_upload.py +17 -8
  168. wagtail/admin/views/generic/usage.py +17 -11
  169. wagtail/admin/views/home.py +15 -12
  170. wagtail/admin/views/mixins.py +30 -0
  171. wagtail/admin/views/pages/choose_parent.py +73 -0
  172. wagtail/admin/views/pages/history.py +54 -66
  173. wagtail/admin/views/pages/listing.py +187 -106
  174. wagtail/admin/views/pages/usage.py +6 -1
  175. wagtail/admin/views/pages/utils.py +70 -1
  176. wagtail/admin/views/workflows.py +150 -21
  177. wagtail/admin/viewsets/model.py +2 -2
  178. wagtail/admin/viewsets/pages.py +77 -0
  179. wagtail/admin/wagtail_hooks.py +40 -2
  180. wagtail/admin/widgets/button.py +10 -10
  181. wagtail/api/v2/filters.py +1 -1
  182. wagtail/api/v2/tests/test_pages.py +1 -1
  183. wagtail/blocks/base.py +18 -9
  184. wagtail/blocks/field_block.py +9 -7
  185. wagtail/blocks/list_block.py +16 -6
  186. wagtail/blocks/static_block.py +3 -0
  187. wagtail/blocks/stream_block.py +58 -23
  188. wagtail/blocks/struct_block.py +15 -9
  189. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +39 -47
  190. wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  191. wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.po +2 -2
  192. wagtail/contrib/forms/models.py +5 -5
  193. wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +44 -33
  194. wagtail/contrib/forms/templates/wagtailforms/submissions_index.html +2 -63
  195. wagtail/contrib/forms/tests/test_models.py +26 -0
  196. wagtail/contrib/forms/urls.py +6 -0
  197. wagtail/contrib/forms/views.py +52 -49
  198. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
  199. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +3 -3
  200. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +34 -42
  201. wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +2 -2
  202. wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  203. wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.po +2 -2
  204. wagtail/contrib/redirects/signal_handlers.py +1 -1
  205. wagtail/contrib/redirects/templates/wagtailredirects/index.html +1 -36
  206. wagtail/contrib/redirects/templates/wagtailredirects/index_results.html +18 -0
  207. wagtail/contrib/redirects/templates/wagtailredirects/redirect_target_cell.html +8 -0
  208. wagtail/contrib/redirects/tests/test_import_command.py +1 -1
  209. wagtail/contrib/redirects/tests/test_redirects.py +79 -8
  210. wagtail/contrib/redirects/urls.py +2 -1
  211. wagtail/contrib/redirects/views.py +85 -55
  212. wagtail/contrib/search_promotions/admin_urls.py +2 -1
  213. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +41 -64
  214. wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +2 -2
  215. wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  216. wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.po +2 -2
  217. wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  218. wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +41 -2
  219. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
  220. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +9 -3
  221. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +1 -16
  222. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index_results.html +11 -0
  223. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/list.html +0 -51
  224. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/results.html +3 -16
  225. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/search_promotion_column.html +15 -0
  226. wagtail/contrib/search_promotions/tests.py +122 -9
  227. wagtail/contrib/search_promotions/views.py +66 -65
  228. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
  229. wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  230. wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.po +2 -2
  231. wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.mo +0 -0
  232. wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.po +6 -2
  233. wagtail/contrib/settings/registry.py +10 -5
  234. wagtail/contrib/settings/tests/generic/test_admin.py +9 -0
  235. wagtail/contrib/settings/tests/site_specific/test_admin.py +10 -1
  236. wagtail/contrib/settings/tests/site_specific/test_model.py +3 -3
  237. wagtail/contrib/settings/tests/site_specific/test_templates.py +1 -1
  238. wagtail/contrib/settings/views.py +3 -1
  239. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  240. wagtail/contrib/simple_translation/tests/test_wagtail_hooks.py +2 -2
  241. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  242. wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  243. wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.po +2 -2
  244. wagtail/contrib/table_block/blocks.py +2 -2
  245. wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
  246. wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.po +27 -2
  247. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  248. wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
  249. wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.po +27 -2
  250. wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.mo +0 -0
  251. wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +27 -2
  252. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  253. wagtail/contrib/table_block/tests.py +6 -0
  254. wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
  255. wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.po +12 -2
  256. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
  257. wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
  258. wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.po +12 -2
  259. wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.mo +0 -0
  260. wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.po +12 -2
  261. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  262. wagtail/coreutils.py +3 -2
  263. wagtail/documents/admin_urls.py +2 -2
  264. wagtail/documents/locale/en/LC_MESSAGES/django.po +22 -22
  265. wagtail/documents/locale/fr/LC_MESSAGES/django.po +2 -2
  266. wagtail/documents/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  267. wagtail/documents/locale/he_IL/LC_MESSAGES/django.po +2 -2
  268. wagtail/documents/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  269. wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +19 -2
  270. wagtail/documents/locale/hu/LC_MESSAGES/django.mo +0 -0
  271. wagtail/documents/locale/hu/LC_MESSAGES/django.po +16 -2
  272. wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
  273. wagtail/documents/locale/it/LC_MESSAGES/django.po +19 -2
  274. wagtail/documents/migrations/0013_delete_uploadeddocument.py +16 -0
  275. wagtail/documents/models.py +1 -20
  276. wagtail/documents/rich_text/__init__.py +11 -7
  277. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  278. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  279. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  280. wagtail/documents/templates/wagtaildocs/documents/index.html +0 -16
  281. wagtail/documents/tests/test_admin_views.py +155 -23
  282. wagtail/documents/tests/test_collection_privacy.py +55 -1
  283. wagtail/documents/tests/test_rich_text.py +14 -0
  284. wagtail/documents/views/documents.py +25 -22
  285. wagtail/documents/views/multiple.py +6 -7
  286. wagtail/documents/views/serve.py +16 -1
  287. wagtail/documents/wagtail_hooks.py +20 -15
  288. wagtail/embeds/blocks.py +5 -0
  289. wagtail/embeds/locale/en/LC_MESSAGES/django.po +2 -2
  290. wagtail/embeds/locale/fr/LC_MESSAGES/django.po +2 -2
  291. wagtail/embeds/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  292. wagtail/embeds/locale/he_IL/LC_MESSAGES/django.po +2 -2
  293. wagtail/embeds/rich_text/__init__.py +1 -1
  294. wagtail/embeds/tests/test_rich_text.py +14 -0
  295. wagtail/embeds/wagtail_hooks.py +4 -14
  296. wagtail/fields.py +3 -48
  297. wagtail/images/admin_urls.py +2 -2
  298. wagtail/images/check_files/wagtail.jpg +0 -0
  299. wagtail/images/check_files/wagtail.png +0 -0
  300. wagtail/images/fields.py +2 -0
  301. wagtail/images/image_operations.py +1 -1
  302. wagtail/images/locale/ca/LC_MESSAGES/django.mo +0 -0
  303. wagtail/images/locale/ca/LC_MESSAGES/django.po +12 -0
  304. wagtail/images/locale/en/LC_MESSAGES/django.po +33 -45
  305. wagtail/images/locale/fr/LC_MESSAGES/django.po +2 -2
  306. wagtail/images/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  307. wagtail/images/locale/he_IL/LC_MESSAGES/django.po +2 -2
  308. wagtail/images/locale/hu/LC_MESSAGES/django.mo +0 -0
  309. wagtail/images/locale/hu/LC_MESSAGES/django.po +28 -2
  310. wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
  311. wagtail/images/locale/it/LC_MESSAGES/django.po +14 -2
  312. wagtail/images/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  313. wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +4 -0
  314. wagtail/images/migrations/0026_delete_uploadedimage.py +16 -0
  315. wagtail/images/models.py +49 -43
  316. wagtail/images/rich_text/__init__.py +18 -8
  317. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  318. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  319. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  320. wagtail/images/templates/wagtailimages/images/image_listing_header.html +6 -0
  321. wagtail/images/templates/wagtailimages/images/index.html +11 -51
  322. wagtail/images/tests/test_admin_views.py +119 -62
  323. wagtail/images/tests/test_image_operations.py +10 -0
  324. wagtail/images/tests/test_models.py +35 -33
  325. wagtail/images/tests/test_rich_text.py +14 -0
  326. wagtail/images/tests/utils.py +1 -1
  327. wagtail/images/views/images.py +35 -64
  328. wagtail/images/views/multiple.py +6 -7
  329. wagtail/images/wagtail_hooks.py +4 -14
  330. wagtail/locale/en/LC_MESSAGES/django.po +150 -136
  331. wagtail/locale/es/LC_MESSAGES/django.mo +0 -0
  332. wagtail/locale/es/LC_MESSAGES/django.po +3 -2
  333. wagtail/locale/fr/LC_MESSAGES/django.po +2 -2
  334. wagtail/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  335. wagtail/locale/he_IL/LC_MESSAGES/django.po +2 -2
  336. wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
  337. wagtail/locale/it/LC_MESSAGES/django.po +5 -5
  338. wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
  339. wagtail/locale/sl/LC_MESSAGES/django.po +27 -2
  340. wagtail/locales/locale/ar/LC_MESSAGES/django.po +1 -1
  341. wagtail/locales/locale/be/LC_MESSAGES/django.po +1 -1
  342. wagtail/locales/locale/bg/LC_MESSAGES/django.po +1 -1
  343. wagtail/locales/locale/ca/LC_MESSAGES/django.po +1 -1
  344. wagtail/locales/locale/cs/LC_MESSAGES/django.po +1 -1
  345. wagtail/locales/locale/cy/LC_MESSAGES/django.po +1 -1
  346. wagtail/locales/locale/da/LC_MESSAGES/django.po +1 -1
  347. wagtail/locales/locale/de/LC_MESSAGES/django.po +1 -1
  348. wagtail/locales/locale/el/LC_MESSAGES/django.po +1 -1
  349. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  350. wagtail/locales/locale/es/LC_MESSAGES/django.po +1 -1
  351. wagtail/locales/locale/et/LC_MESSAGES/django.po +2 -2
  352. wagtail/locales/locale/fa/LC_MESSAGES/django.po +1 -1
  353. wagtail/locales/locale/fi/LC_MESSAGES/django.po +1 -1
  354. wagtail/locales/locale/fr/LC_MESSAGES/django.po +1 -1
  355. wagtail/locales/locale/gl/LC_MESSAGES/django.po +1 -1
  356. wagtail/locales/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  357. wagtail/locales/locale/he_IL/LC_MESSAGES/django.po +3 -3
  358. wagtail/locales/locale/hr_HR/LC_MESSAGES/django.po +1 -1
  359. wagtail/locales/locale/hu/LC_MESSAGES/django.po +1 -1
  360. wagtail/locales/locale/id_ID/LC_MESSAGES/django.po +1 -1
  361. wagtail/locales/locale/is_IS/LC_MESSAGES/django.po +1 -1
  362. wagtail/locales/locale/it/LC_MESSAGES/django.po +1 -1
  363. wagtail/locales/locale/ja/LC_MESSAGES/django.po +1 -1
  364. wagtail/locales/locale/ko/LC_MESSAGES/django.po +1 -1
  365. wagtail/locales/locale/lt/LC_MESSAGES/django.po +1 -1
  366. wagtail/locales/locale/lv/LC_MESSAGES/django.po +1 -1
  367. wagtail/locales/locale/mi/LC_MESSAGES/django.po +1 -1
  368. wagtail/locales/locale/mn/LC_MESSAGES/django.po +1 -1
  369. wagtail/locales/locale/my/LC_MESSAGES/django.po +1 -1
  370. wagtail/locales/locale/nb/LC_MESSAGES/django.po +1 -1
  371. wagtail/locales/locale/nl/LC_MESSAGES/django.po +1 -1
  372. wagtail/locales/locale/pl/LC_MESSAGES/django.po +1 -1
  373. wagtail/locales/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  374. wagtail/locales/locale/pt_PT/LC_MESSAGES/django.po +1 -1
  375. wagtail/locales/locale/ro/LC_MESSAGES/django.po +1 -1
  376. wagtail/locales/locale/ru/LC_MESSAGES/django.po +1 -1
  377. wagtail/locales/locale/sk_SK/LC_MESSAGES/django.po +1 -1
  378. wagtail/locales/locale/sl/LC_MESSAGES/django.po +1 -1
  379. wagtail/locales/locale/sv/LC_MESSAGES/django.po +1 -1
  380. wagtail/locales/locale/tet/LC_MESSAGES/django.po +1 -1
  381. wagtail/locales/locale/th/LC_MESSAGES/django.po +1 -1
  382. wagtail/locales/locale/tr/LC_MESSAGES/django.po +1 -1
  383. wagtail/locales/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  384. wagtail/locales/locale/uk/LC_MESSAGES/django.po +1 -1
  385. wagtail/locales/locale/vi/LC_MESSAGES/django.po +1 -1
  386. wagtail/locales/locale/zh/LC_MESSAGES/django.po +1 -1
  387. wagtail/locales/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
  388. wagtail/locales/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  389. wagtail/locales/tests.py +18 -3
  390. wagtail/locales/views.py +0 -1
  391. wagtail/management/commands/rebuild_references_index.py +3 -1
  392. wagtail/migrations/0092_alter_collectionviewrestriction_password_and_more.py +33 -0
  393. wagtail/migrations/0093_uploadedfile.py +53 -0
  394. wagtail/models/__init__.py +147 -32
  395. wagtail/models/i18n.py +1 -1
  396. wagtail/models/{collections.py → media.py} +33 -2
  397. wagtail/models/reference_index.py +1 -1
  398. wagtail/models/view_restrictions.py +10 -3
  399. wagtail/project_template/project_name/settings/base.py +6 -0
  400. wagtail/project_template/requirements.txt +1 -1
  401. wagtail/rich_text/__init__.py +25 -8
  402. wagtail/rich_text/pages.py +19 -8
  403. wagtail/rich_text/rewriters.py +140 -68
  404. wagtail/search/backends/database/mysql/mysql.py +3 -3
  405. wagtail/search/backends/database/postgres/postgres.py +3 -3
  406. wagtail/search/backends/database/sqlite/sqlite.py +2 -2
  407. wagtail/search/backends/elasticsearch7.py +4 -0
  408. wagtail/search/locale/en/LC_MESSAGES/django.po +3 -3
  409. wagtail/search/tests/test_postgres_backend.py +50 -0
  410. wagtail/sites/locale/en/LC_MESSAGES/django.po +8 -8
  411. wagtail/sites/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  412. wagtail/sites/locale/he_IL/LC_MESSAGES/django.po +2 -2
  413. wagtail/sites/locale/ro/LC_MESSAGES/django.mo +0 -0
  414. wagtail/sites/locale/ro/LC_MESSAGES/django.po +3 -2
  415. wagtail/sites/tests.py +35 -9
  416. wagtail/sites/views.py +3 -1
  417. wagtail/snippets/locale/de/LC_MESSAGES/django.mo +0 -0
  418. wagtail/snippets/locale/de/LC_MESSAGES/django.po +7 -8
  419. wagtail/snippets/locale/en/LC_MESSAGES/django.po +16 -56
  420. wagtail/snippets/locale/fr/LC_MESSAGES/django.po +2 -2
  421. wagtail/snippets/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  422. wagtail/snippets/locale/he_IL/LC_MESSAGES/django.po +2 -2
  423. wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  424. wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +6 -2
  425. wagtail/snippets/locale/lv/LC_MESSAGES/django.mo +0 -0
  426. wagtail/snippets/locale/lv/LC_MESSAGES/django.po +12 -0
  427. wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
  428. wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.po +4 -0
  429. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  430. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  431. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +3 -1
  432. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +3 -1
  433. wagtail/snippets/templates/wagtailsnippets/snippets/create.html +2 -3
  434. wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +2 -3
  435. wagtail/snippets/tests/test_preview.py +13 -2
  436. wagtail/snippets/tests/test_snippets.py +41 -16
  437. wagtail/snippets/tests/test_viewset.py +95 -18
  438. wagtail/snippets/tests/test_workflows.py +12 -0
  439. wagtail/snippets/views/snippets.py +1 -40
  440. wagtail/templatetags/wagtailcore_tags.py +1 -1
  441. wagtail/test/demosite/models.py +1 -1
  442. wagtail/test/middleware.py +14 -1
  443. wagtail/test/testapp/fixtures/test.json +20 -0
  444. wagtail/test/testapp/migrations/0001_squashed_0073_revisablechildmodel_secret_text.py +8 -8
  445. wagtail/test/testapp/migrations/0023_snippetchoosermodel_full_featured.py +1 -0
  446. wagtail/test/testapp/migrations/0034_custompermissionmodel.py +44 -0
  447. wagtail/test/testapp/migrations/0035_modelwithcustommanager.py +30 -0
  448. wagtail/test/testapp/migrations/0036_complexdefaultstreampage.py +28 -0
  449. wagtail/test/testapp/models.py +79 -2
  450. wagtail/test/testapp/templates/tests/custom_docs_password_required.html +10 -0
  451. wagtail/test/testapp/templates/tests/custom_page_password_required.html +10 -0
  452. wagtail/test/testapp/views.py +24 -2
  453. wagtail/test/testapp/wagtail_hooks.py +19 -0
  454. wagtail/test/utils/wagtail_tests.py +2 -2
  455. wagtail/tests/test_blocks.py +262 -1
  456. wagtail/tests/test_migrations.py +1 -1
  457. wagtail/tests/test_page_model.py +77 -0
  458. wagtail/tests/test_page_privacy.py +18 -1
  459. wagtail/tests/test_rich_text.py +95 -5
  460. wagtail/tests/test_streamfield.py +43 -0
  461. wagtail/tests/test_utils.py +8 -2
  462. wagtail/tests/test_views.py +52 -1
  463. wagtail/tests/test_whitelist.py +7 -7
  464. wagtail/users/forms.py +3 -1
  465. wagtail/users/locale/en/LC_MESSAGES/django.po +124 -96
  466. wagtail/users/locale/fr/LC_MESSAGES/django.po +2 -2
  467. wagtail/users/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  468. wagtail/users/locale/he_IL/LC_MESSAGES/django.po +2 -2
  469. wagtail/users/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  470. wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +13 -2
  471. wagtail/users/migrations/0013_userprofile_density.py +23 -0
  472. wagtail/users/models.py +14 -3
  473. wagtail/users/templates/wagtailusers/groups/create.html +1 -7
  474. wagtail/users/templates/wagtailusers/groups/edit.html +1 -13
  475. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +46 -2
  476. wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
  477. wagtail/users/templates/wagtailusers/users/create.html +1 -14
  478. wagtail/users/templates/wagtailusers/users/edit.html +1 -14
  479. wagtail/users/templates/wagtailusers/users/index.html +2 -5
  480. wagtail/users/templates/wagtailusers/users/index_results.html +3 -13
  481. wagtail/users/templates/wagtailusers/users/user_cell.html +9 -0
  482. wagtail/users/templatetags/wagtailusers_tags.py +107 -20
  483. wagtail/users/tests/test_admin_views.py +669 -90
  484. wagtail/users/views/groups.py +58 -61
  485. wagtail/users/views/users.py +211 -92
  486. wagtail/users/wagtail_hooks.py +6 -38
  487. wagtail/users/widgets.py +3 -5
  488. wagtail/utils/text.py +1 -1
  489. wagtail/views.py +5 -9
  490. wagtail/whitelist.py +1 -1
  491. {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/METADATA +5 -6
  492. {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/RECORD +496 -477
  493. wagtail/admin/static/wagtailadmin/js/page-editor.js +0 -1
  494. wagtail/admin/static/wagtailadmin/js/vendor/mousetrap.min.js +0 -1
  495. wagtail/admin/static/wagtailadmin/js/vendor/urlify.js +0 -1
  496. wagtail/admin/static/wagtailadmin/js/vendor/xregexp.min.js +0 -1
  497. wagtail/admin/templates/wagtailadmin/collections/index.html +0 -34
  498. wagtail/admin/templates/wagtailadmin/pages/revisions/_actions.html +0 -22
  499. wagtail/admin/templates/wagtailadmin/shared/page_breadcrumbs.html +0 -55
  500. wagtail/admin/tests/pages/test_dashboard.py +0 -172
  501. wagtail/contrib/redirects/templates/wagtailredirects/results.html +0 -23
  502. wagtail/documents/templates/wagtaildocs/documents/list.html +0 -2
  503. wagtail/search/tests/test_postgres_stemming.py +0 -40
  504. wagtail/sites/templates/wagtailsites/create.html +0 -7
  505. wagtail/sites/templates/wagtailsites/edit.html +0 -7
  506. wagtail/snippets/templates/wagtailsnippets/snippets/revisions/_actions.html +0 -36
  507. wagtail/users/templates/wagtailusers/users/list.html +0 -62
  508. wagtail/users/urls/users.py +0 -12
  509. {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/LICENSE +0 -0
  510. {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/WHEEL +0 -0
  511. {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/entry_points.txt +0 -0
  512. {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
+ import datetime
1
2
  import json
2
- from datetime import datetime
3
+ import re
3
4
  from urllib.parse import urljoin
4
5
  from warnings import warn
5
6
 
@@ -40,6 +41,7 @@ from wagtail.admin.utils import (
40
41
  get_valid_next_url_from_request,
41
42
  )
42
43
  from wagtail.admin.views.bulk_action.registry import bulk_action_registry
44
+ from wagtail.admin.views.pages.utils import get_breadcrumbs_items_for_page
43
45
  from wagtail.admin.widgets import Button, ButtonWithDropdown, PageListingButton
44
46
  from wagtail.coreutils import (
45
47
  accepts_kwarg,
@@ -55,7 +57,6 @@ from wagtail.models import (
55
57
  Page,
56
58
  PageViewRestriction,
57
59
  )
58
- from wagtail.permissions import page_permission_policy
59
60
  from wagtail.telepath import JSContext
60
61
  from wagtail.users.utils import get_gravatar_url
61
62
  from wagtail.utils.deprecation import RemovedInWagtail70Warning
@@ -67,11 +68,16 @@ register.filter("naturaltime", naturaltime)
67
68
 
68
69
 
69
70
  @register.inclusion_tag("wagtailadmin/shared/breadcrumbs.html")
70
- def breadcrumbs(items, is_expanded=False, classname=None):
71
- return {"items": items, "is_expanded": is_expanded, "classname": classname}
71
+ def breadcrumbs(items, is_expanded=False, classname=None, icon_name=None):
72
+ return {
73
+ "items": items,
74
+ "is_expanded": is_expanded or len(items) == 1,
75
+ "classname": classname,
76
+ "icon_name": icon_name,
77
+ }
72
78
 
73
79
 
74
- @register.inclusion_tag("wagtailadmin/shared/page_breadcrumbs.html", takes_context=True)
80
+ @register.inclusion_tag("wagtailadmin/shared/breadcrumbs.html", takes_context=True)
75
81
  def page_breadcrumbs(
76
82
  context,
77
83
  page,
@@ -79,38 +85,33 @@ def page_breadcrumbs(
79
85
  url_root_name=None,
80
86
  include_self=True,
81
87
  is_expanded=False,
82
- page_perms=None,
83
- querystring_value=None,
88
+ querystring_value="",
84
89
  trailing_breadcrumb_title=None,
85
90
  classname=None,
91
+ icon_name=None,
86
92
  ):
87
93
  user = context["request"].user
88
94
 
89
- # find the closest common ancestor of the pages that this user has direct explore permission
90
- # (i.e. add/edit/publish/lock) over; this will be the root of the breadcrumb
91
- cca = page_permission_policy.explorable_root_instance(user)
92
- if not cca:
93
- return {"items": Page.objects.none()}
94
-
95
- items = (
96
- page.get_ancestors(inclusive=include_self)
97
- .descendant_of(cca, inclusive=True)
98
- .specific()
95
+ items = get_breadcrumbs_items_for_page(
96
+ page,
97
+ user,
98
+ url_name,
99
+ url_root_name,
100
+ include_self,
101
+ querystring_value,
99
102
  )
100
103
 
104
+ if trailing_breadcrumb_title:
105
+ items.append({"label": trailing_breadcrumb_title})
106
+
101
107
  if len(items) == 1:
102
108
  is_expanded = True
103
109
 
104
110
  return {
105
111
  "items": items,
106
- "current_page": page,
107
112
  "is_expanded": is_expanded,
108
- "page_perms": page_perms,
109
- "querystring_value": querystring_value or "",
110
- "trailing_breadcrumb_title": trailing_breadcrumb_title, # Only used in collapsible breadcrumb templates
111
- "url_name": url_name,
112
- "url_root_name": url_root_name,
113
113
  "classname": classname,
114
+ "icon_name": icon_name,
114
115
  }
115
116
 
116
117
 
@@ -223,7 +224,15 @@ def classnames(*classes):
223
224
  Usage <div class="{% classnames "w-base" classname active|yesno:"w-base--active," any_other_var %}"></div>
224
225
  Returns any args as a space-separated joined string for using in HTML class names.
225
226
  """
226
- return " ".join([classname.strip() for classname in classes if classname])
227
+
228
+ flattened = []
229
+ for classname in classes:
230
+ if isinstance(classname, str):
231
+ flattened.append(classname)
232
+ elif hasattr(classname, "__iter__"):
233
+ flattened.extend(classname)
234
+
235
+ return " ".join([classname.strip() for classname in flattened if classname])
227
236
 
228
237
 
229
238
  @register.simple_tag(takes_context=True)
@@ -657,7 +666,12 @@ def admin_theme_classname(context):
657
666
  if hasattr(user, "wagtail_userprofile")
658
667
  else "system"
659
668
  )
660
- return f"w-theme-{theme_name}"
669
+ density_name = (
670
+ user.wagtail_userprofile.density
671
+ if hasattr(user, "wagtail_userprofile")
672
+ else "default"
673
+ )
674
+ return f"w-theme-{theme_name} w-density-{density_name}"
661
675
 
662
676
 
663
677
  @register.simple_tag
@@ -752,7 +766,6 @@ def timesince_simple(d):
752
766
  1 week, 1 day ago -> 1 week ago
753
767
  0 minutes ago -> just now
754
768
  """
755
- # Note: Duplicate code in timesince_last_update()
756
769
  time_period = timesince(d).split(",")[0]
757
770
  if time_period == avoid_wrapping(_("0 minutes")):
758
771
  return _("just now")
@@ -771,11 +784,25 @@ def timesince_last_update(
771
784
  """
772
785
  # translation usage below is intentionally verbose to be easier to work with translations
773
786
 
774
- if last_update.date() == datetime.today().date():
787
+ current_datetime = timezone.now()
788
+ if timezone.is_aware(current_datetime):
789
+ # timezone support is enabled - make last_update timezone-aware and set to the user's
790
+ # timezone
791
+ current_datetime = timezone.localtime(current_datetime)
775
792
  if timezone.is_aware(last_update):
776
- time_str = timezone.localtime(last_update).strftime("%H:%M")
793
+ local_datetime = timezone.localtime(last_update)
777
794
  else:
778
- time_str = last_update.strftime("%H:%M")
795
+ local_datetime = timezone.make_aware(last_update)
796
+ else:
797
+ # timezone support is disabled - use naive datetimes
798
+ if timezone.is_aware(last_update):
799
+ local_datetime = timezone.make_naive(last_update)
800
+ else:
801
+ local_datetime = last_update
802
+
803
+ # Use an explicit timestamp if last_update is today as seen in the current user's time zone
804
+ if local_datetime.date() == current_datetime.date():
805
+ time_str = local_datetime.strftime("%H:%M")
779
806
 
780
807
  if show_time_prefix:
781
808
  if user_display_name:
@@ -795,17 +822,9 @@ def timesince_last_update(
795
822
  return time_str
796
823
  else:
797
824
  if use_shorthand:
798
- # Note: Duplicate code in timesince_simple()
799
- time_period = timesince(last_update).split(",")[0]
800
- if time_period == avoid_wrapping(_("0 minutes")):
801
- if user_display_name:
802
- return _("just now by %(user_display_name)s") % {
803
- "user_display_name": user_display_name
804
- }
805
- else:
806
- return _("just now")
825
+ time_period = timesince(local_datetime, now=current_datetime).split(",")[0]
807
826
  else:
808
- time_period = timesince(last_update)
827
+ time_period = timesince(local_datetime, now=current_datetime)
809
828
 
810
829
  if user_display_name:
811
830
  return _("%(time_period)s ago by %(user_display_name)s") % {
@@ -1288,12 +1307,70 @@ def workflow_status_with_date(workflow_state):
1288
1307
  return _("%(status_display)s %(task_name)s %(started_at)s") % translation_context
1289
1308
 
1290
1309
 
1310
+ @register.inclusion_tag(
1311
+ "wagtailadmin/shared/keyboard_shortcuts_dialog.html",
1312
+ takes_context=True,
1313
+ )
1314
+ def keyboard_shortcuts_dialog(context):
1315
+ """
1316
+ Renders the keyboard shortcuts dialog content with the
1317
+ appropriate shortcuts for the user's platform.
1318
+ Note: Shortcut keys are intentionally not translated.
1319
+ """
1320
+
1321
+ user_agent = context["request"].headers.get("User-Agent", "")
1322
+ is_mac = re.search(r"Mac|iPod|iPhone|iPad", user_agent)
1323
+ modifier = "⌘" if is_mac else "Ctrl"
1324
+
1325
+ return {
1326
+ "shortcuts": {
1327
+ ("actions-common", _("Common actions")): [
1328
+ (_("Copy"), f"{modifier} + c"),
1329
+ (_("Cut"), f"{modifier} + x"),
1330
+ (_("Paste"), f"{modifier} + v"),
1331
+ (
1332
+ _("Paste and match style")
1333
+ if is_mac
1334
+ else _("Paste without formatting"),
1335
+ f"{modifier} + Shift + v",
1336
+ ),
1337
+ (_("Undo"), f"{modifier} + z"),
1338
+ (
1339
+ _("Redo"),
1340
+ f"{modifier} + Shift + z" if is_mac else f"{modifier} + y",
1341
+ ),
1342
+ ],
1343
+ ("actions-model", _("Actions")): [
1344
+ (_("Save changes"), f"{modifier} + s"),
1345
+ (_("Preview"), f"{modifier} + p"),
1346
+ ],
1347
+ ("rich-text-content", _("Text content")): [
1348
+ (_("Insert or edit a link"), f"{modifier} + k")
1349
+ ],
1350
+ ("rich-text-formatting", _("Text formatting")): [
1351
+ (_("Bold"), f"{modifier} + b"),
1352
+ (_("Italic"), f"{modifier} + i"),
1353
+ (_("Underline"), f"{modifier} + u"),
1354
+ (_("Monospace (code)"), f"{modifier} + j"),
1355
+ (_("Strike-through"), f"{modifier} + x"),
1356
+ (_("Superscript"), f"{modifier} + ."),
1357
+ (_("Subscript"), f"{modifier} + ,"),
1358
+ ],
1359
+ }
1360
+ }
1361
+
1362
+
1291
1363
  @register.inclusion_tag("wagtailadmin/shared/human_readable_date.html")
1292
1364
  def human_readable_date(date, description=None, placement="top"):
1365
+ if isinstance(date, datetime.datetime):
1366
+ tooltip_format = getattr(settings, "DATETIME_FORMAT", "N j, Y, P")
1367
+ elif isinstance(date, datetime.date):
1368
+ tooltip_format = getattr(settings, "DATE_FORMAT", "N j, Y")
1293
1369
  return {
1294
1370
  "date": date,
1295
1371
  "description": description,
1296
1372
  "placement": placement,
1373
+ "tooltip_format": tooltip_format,
1297
1374
  }
1298
1375
 
1299
1376
 
@@ -1310,7 +1310,7 @@ class TestCopyPageAction(AdminAPITestCase, TestCase):
1310
1310
  self.assertEqual(response.status_code, 403)
1311
1311
  content = json.loads(response.content.decode("utf-8"))
1312
1312
  self.assertEqual(
1313
- content, {"detail": "You do not have permission to perform this action."}
1313
+ content, {"detail": "You do not have permission to copy this page"}
1314
1314
  )
1315
1315
 
1316
1316
  def test_recursively_copy_into_self(self):
@@ -1348,7 +1348,7 @@ class TestCopyPageAction(AdminAPITestCase, TestCase):
1348
1348
  self.assertEqual(response.status_code, 403)
1349
1349
  content = json.loads(response.content.decode("utf-8"))
1350
1350
  self.assertEqual(
1351
- content, {"detail": "You do not have permission to perform this action."}
1351
+ content, {"detail": "You do not have permission to copy this page"}
1352
1352
  )
1353
1353
 
1354
1354
  def test_without_publish_permissions_at_destination_with_keep_live(self):
@@ -1375,7 +1375,12 @@ class TestCopyPageAction(AdminAPITestCase, TestCase):
1375
1375
  self.assertEqual(response.status_code, 403)
1376
1376
  content = json.loads(response.content.decode("utf-8"))
1377
1377
  self.assertEqual(
1378
- content, {"detail": "You do not have permission to perform this action."}
1378
+ content,
1379
+ {
1380
+ "detail": (
1381
+ "You do not have permission to publish a page at the destination"
1382
+ )
1383
+ },
1379
1384
  )
1380
1385
 
1381
1386
  def test_respects_page_creation_rules(self):
@@ -1385,7 +1390,7 @@ class TestCopyPageAction(AdminAPITestCase, TestCase):
1385
1390
  self.assertEqual(response.status_code, 403)
1386
1391
  content = json.loads(response.content.decode("utf-8"))
1387
1392
  self.assertEqual(
1388
- content, {"detail": "You do not have permission to perform this action."}
1393
+ content, {"detail": "You do not have permission to copy this page"}
1389
1394
  )
1390
1395
 
1391
1396
  def test_copy_page_slug_in_use(self):
@@ -1512,7 +1517,7 @@ class TestDeletePageAction(AdminAPITestCase, TestCase):
1512
1517
  self.assertEqual(response.status_code, 403)
1513
1518
  content = json.loads(response.content.decode("utf-8"))
1514
1519
  self.assertEqual(
1515
- content, {"detail": "You do not have permission to perform this action."}
1520
+ content, {"detail": "You do not have permission to delete this page"}
1516
1521
  )
1517
1522
 
1518
1523
  # Page is still there
@@ -1560,7 +1565,7 @@ class TestPublishPageAction(AdminAPITestCase, TestCase):
1560
1565
  self.assertEqual(response.status_code, 403)
1561
1566
  content = json.loads(response.content.decode("utf-8"))
1562
1567
  self.assertEqual(
1563
- content, {"detail": "You do not have permission to perform this action."}
1568
+ content, {"detail": "You do not have permission to publish this page"}
1564
1569
  )
1565
1570
 
1566
1571
  def test_publish_alias_page(self):
@@ -1650,7 +1655,7 @@ class TestUnpublishPageAction(AdminAPITestCase, TestCase):
1650
1655
  self.assertEqual(response.status_code, 403)
1651
1656
  content = json.loads(response.content.decode("utf-8"))
1652
1657
  self.assertEqual(
1653
- content, {"detail": "You do not have permission to perform this action."}
1658
+ content, {"detail": "You do not have permission to unpublish this page"}
1654
1659
  )
1655
1660
 
1656
1661
 
@@ -1682,7 +1687,13 @@ class TestMovePageAction(AdminAPITestCase, TestCase):
1682
1687
 
1683
1688
  content = json.loads(response.content.decode("utf-8"))
1684
1689
  self.assertEqual(
1685
- content, {"detail": "You do not have permission to perform this action."}
1690
+ content,
1691
+ {
1692
+ "detail": (
1693
+ "You do not have permission to move the page to the "
1694
+ "target specified."
1695
+ ),
1696
+ },
1686
1697
  )
1687
1698
 
1688
1699
  def test_move_page_without_destination_page_id(self):
@@ -1955,7 +1966,12 @@ class TestCreatePageAliasAction(AdminAPITestCase, TestCase):
1955
1966
 
1956
1967
  content = json.loads(response.content.decode("utf-8"))
1957
1968
  self.assertEqual(
1958
- content, {"detail": "You do not have permission to perform this action."}
1969
+ content,
1970
+ {
1971
+ "detail": (
1972
+ "You do not have permission to publish a page at the destination"
1973
+ ),
1974
+ },
1959
1975
  )
1960
1976
 
1961
1977
 
@@ -2012,7 +2028,7 @@ class TestRevertToPageRevisionAction(AdminAPITestCase, TestCase):
2012
2028
 
2013
2029
  content = json.loads(response.content.decode("utf-8"))
2014
2030
  self.assertEqual(
2015
- content, {"detail": "You do not have permission to perform this action."}
2031
+ content, {"detail": "You do not have permission to edit this page"}
2016
2032
  )
2017
2033
 
2018
2034
  def test_revert_to_page_revision_without_revision_id(self):
@@ -1494,7 +1494,13 @@ class TestInlineStreamField(WagtailTestUtils, TestCase):
1494
1494
  self.assertEqual(response.status_code, 200)
1495
1495
 
1496
1496
  # response should include HTML declarations for streamfield child blocks
1497
- self.assertContains(response, '<div id="sections-__prefix__-body" data-block="')
1497
+ self.assertContains(response, '<div id="sections-__prefix__-body" data-block')
1498
+ soup = self.get_soup(response.content)
1499
+ blockDiv = soup.find("div", {"data-controller": "w-block"})
1500
+ self.assertIsNotNone(blockDiv)
1501
+ # block div should contain this attributes
1502
+ self.assertTrue(blockDiv.has_attr("data-w-block-arguments-value"))
1503
+ self.assertTrue(blockDiv.has_attr("data-w-block-data-value"))
1498
1504
 
1499
1505
 
1500
1506
  class TestIssue2994(WagtailTestUtils, TestCase):
@@ -1806,7 +1812,7 @@ class TestPageSubscriptionSettings(WagtailTestUtils, TestCase):
1806
1812
  # Login
1807
1813
  self.user = self.login()
1808
1814
 
1809
- def test_commment_notifications_switched_on_by_default(self):
1815
+ def test_comment_notifications_switched_on_by_default(self):
1810
1816
  response = self.client.get(
1811
1817
  reverse(
1812
1818
  "wagtailadmin_pages:add",
@@ -1890,7 +1896,7 @@ class TestCommenting(WagtailTestUtils, TestCase):
1890
1896
  # Login
1891
1897
  self.user = self.login()
1892
1898
 
1893
- def test_commments_enabled_by_default(self):
1899
+ def test_comments_enabled_by_default(self):
1894
1900
  response = self.client.get(
1895
1901
  reverse(
1896
1902
  "wagtailadmin_pages:add",
@@ -1907,7 +1913,7 @@ class TestCommenting(WagtailTestUtils, TestCase):
1907
1913
  self.assertEqual("w-comments:init", form["data-w-init-event-value"])
1908
1914
 
1909
1915
  @override_settings(WAGTAILADMIN_COMMENTS_ENABLED=False)
1910
- def test_commments_disabled(self):
1916
+ def test_comments_disabled(self):
1911
1917
  response = self.client.get(
1912
1918
  reverse(
1913
1919
  "wagtailadmin_pages:add",
@@ -0,0 +1,37 @@
1
+ from django.test import TestCase
2
+
3
+ from wagtail.test.utils import WagtailTestUtils
4
+ from wagtail.test.utils.template_tests import AdminTemplateTestUtils
5
+
6
+
7
+ class TestCustomListing(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
8
+ fixtures = ["test.json"]
9
+
10
+ def test_get(self):
11
+ self.login()
12
+ response = self.client.get("/admin/event_pages/")
13
+ self.assertEqual(response.status_code, 200)
14
+ self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
15
+ self.assertContains(response, "Event pages")
16
+ self.assertContains(response, "Christmas")
17
+ self.assertContains(response, "Saint Patrick")
18
+ self.assertNotContains(response, "Welcome to the Wagtail test site!")
19
+ self.assertBreadcrumbsItemsRendered(
20
+ [{"url": "", "label": "Event pages"}],
21
+ response.content,
22
+ )
23
+ soup = self.get_soup(response.content)
24
+ breadcrumbs_icon = soup.select_one(".w-breadcrumbs__icon")
25
+ self.assertIsNotNone(breadcrumbs_icon)
26
+ use = breadcrumbs_icon.select_one("use")
27
+ self.assertIsNotNone(use)
28
+ self.assertEqual(use["href"], "#icon-calendar")
29
+
30
+ def test_filter(self):
31
+ self.login()
32
+ response = self.client.get("/admin/event_pages/", {"audience": "private"})
33
+ self.assertEqual(response.status_code, 200)
34
+ self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
35
+ self.assertContains(response, "Event pages")
36
+ self.assertNotContains(response, "Christmas")
37
+ self.assertContains(response, "Saint Patrick")
@@ -2067,7 +2067,7 @@ class TestPageEdit(WagtailTestUtils, TestCase):
2067
2067
  # as when running it within the full test suite
2068
2068
  self.client.get(reverse("wagtailadmin_pages:edit", args=(self.event_page.id,)))
2069
2069
 
2070
- with self.assertNumQueries(35):
2070
+ with self.assertNumQueries(33):
2071
2071
  self.client.get(
2072
2072
  reverse("wagtailadmin_pages:edit", args=(self.event_page.id,))
2073
2073
  )
@@ -2080,7 +2080,7 @@ class TestPageEdit(WagtailTestUtils, TestCase):
2080
2080
  # Warm up the cache as above.
2081
2081
  self.client.get(reverse("wagtailadmin_pages:edit", args=(self.event_page.id,)))
2082
2082
 
2083
- with self.assertNumQueries(39):
2083
+ with self.assertNumQueries(37):
2084
2084
  self.client.get(
2085
2085
  reverse("wagtailadmin_pages:edit", args=(self.event_page.id,))
2086
2086
  )
@@ -3088,7 +3088,7 @@ class TestPageSubscriptionSettings(WagtailTestUtils, TestCase):
3088
3088
  # Login
3089
3089
  self.user = self.login()
3090
3090
 
3091
- def test_commment_notifications_switched_off(self):
3091
+ def test_comment_notifications_switched_off(self):
3092
3092
  response = self.client.get(
3093
3093
  reverse("wagtailadmin_pages:edit", args=[self.child_page.id])
3094
3094
  )
@@ -3104,7 +3104,7 @@ class TestPageSubscriptionSettings(WagtailTestUtils, TestCase):
3104
3104
  ).exists()
3105
3105
  )
3106
3106
 
3107
- def test_commment_notifications_switched_on(self):
3107
+ def test_comment_notifications_switched_on(self):
3108
3108
  PageSubscription.objects.create(
3109
3109
  page=self.child_page, user=self.user, comment_notifications=True
3110
3110
  )
@@ -3247,7 +3247,7 @@ class TestCommenting(WagtailTestUtils, TestCase):
3247
3247
  [to for email in mail.outbox for to in email.to],
3248
3248
  )
3249
3249
 
3250
- def test_commments_enabled_by_default(self):
3250
+ def test_comments_enabled_by_default(self):
3251
3251
  response = self.client.get(
3252
3252
  reverse("wagtailadmin_pages:edit", args=[self.child_page.id])
3253
3253
  )
@@ -3261,7 +3261,7 @@ class TestCommenting(WagtailTestUtils, TestCase):
3261
3261
  self.assertEqual("w-comments:init", form["data-w-init-event-value"])
3262
3262
 
3263
3263
  @override_settings(WAGTAILADMIN_COMMENTS_ENABLED=False)
3264
- def test_commments_disabled(self):
3264
+ def test_comments_disabled(self):
3265
3265
  response = self.client.get(
3266
3266
  reverse("wagtailadmin_pages:edit", args=[self.child_page.id])
3267
3267
  )
@@ -59,12 +59,13 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
59
59
  self.assertEqual(active_filter.get_text(separator=" ", strip=True), text)
60
60
  self.assertIsNotNone(clear_button)
61
61
  self.assertNotIn(param, clear_button.attrs.get("data-w-swap-src-value"))
62
+ self.assertEqual(clear_button.attrs.get("data-w-swap-reflect-value"), "true")
62
63
 
63
64
  def test_explore(self):
64
65
  explore_url = reverse("wagtailadmin_explore", args=(self.root_page.id,))
65
66
  response = self.client.get(explore_url)
66
67
  self.assertEqual(response.status_code, 200)
67
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
68
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
68
69
  self.assertEqual(self.root_page, response.context["parent_page"])
69
70
 
70
71
  # child pages should be most recent first
@@ -120,7 +121,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
120
121
  def test_explore_root(self):
121
122
  response = self.client.get(reverse("wagtailadmin_explore_root"))
122
123
  self.assertEqual(response.status_code, 200)
123
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
124
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
124
125
  self.assertEqual(Page.objects.get(id=1), response.context["parent_page"])
125
126
  self.assertIn(self.root_page, response.context["pages"])
126
127
  # Should not contain a link to the history view
@@ -146,7 +147,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
146
147
  {"ordering": "title"},
147
148
  )
148
149
  self.assertEqual(response.status_code, 200)
149
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
150
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
150
151
  self.assertEqual(response.context["ordering"], "title")
151
152
 
152
153
  # child pages should be ordered by title
@@ -212,7 +213,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
212
213
  reverse("wagtailadmin_explore", args=(self.root_page.id,))
213
214
  )
214
215
  self.assertEqual(response.status_code, 200)
215
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
216
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
216
217
 
217
218
  # child pages should be ordered by title
218
219
  page_ids = [page.id for page in response.context["pages"]]
@@ -231,7 +232,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
231
232
  {"ordering": "-title"},
232
233
  )
233
234
  self.assertEqual(response.status_code, 200)
234
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
235
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
235
236
  self.assertEqual(response.context["ordering"], "-title")
236
237
 
237
238
  # child pages should be ordered by title
@@ -246,7 +247,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
246
247
  {"ordering": "latest_revision_created_at"},
247
248
  )
248
249
  self.assertEqual(response.status_code, 200)
249
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
250
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
250
251
  self.assertEqual(response.context["ordering"], "latest_revision_created_at")
251
252
 
252
253
  # child pages should be oldest revision first
@@ -262,7 +263,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
262
263
  {"ordering": "invalid_order"},
263
264
  )
264
265
  self.assertEqual(response.status_code, 200)
265
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
266
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
266
267
  self.assertEqual(response.context["ordering"], "-latest_revision_created_at")
267
268
 
268
269
  def test_reordering(self):
@@ -271,7 +272,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
271
272
  {"ordering": "ord"},
272
273
  )
273
274
  self.assertEqual(response.status_code, 200)
274
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
275
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
275
276
  self.assertEqual(response.context["ordering"], "ord")
276
277
 
277
278
  # child pages should be ordered by native tree order (i.e. by creation time)
@@ -292,7 +293,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
292
293
  {"polite_pages_only": "yes_please"},
293
294
  )
294
295
  self.assertEqual(response.status_code, 200)
295
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
296
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
296
297
  page_ids = [page.id for page in response.context["pages"]]
297
298
  self.assertEqual(page_ids, [self.child_page.id])
298
299
 
@@ -333,7 +334,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
333
334
  reverse("wagtailadmin_explore", args=(self.root_page.id,))
334
335
  )
335
336
  self.assertEqual(response.status_code, 200)
336
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
337
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
337
338
  self.assertContains(response, "Dummy Button")
338
339
  self.assertContains(response, "/dummy-button")
339
340
 
@@ -355,7 +356,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
355
356
  reverse("wagtailadmin_explore", args=(self.root_page.id,))
356
357
  )
357
358
  self.assertEqual(response.status_code, 200)
358
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
359
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
359
360
  self.assertContains(response, "Dummy Button")
360
361
  self.assertContains(response, "/dummy-button")
361
362
 
@@ -378,7 +379,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
378
379
 
379
380
  # Check response
380
381
  self.assertEqual(response.status_code, 200)
381
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
382
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
382
383
 
383
384
  # Check that we got the correct page
384
385
  self.assertEqual(response.context["page_obj"].number, 2)
@@ -534,14 +535,14 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
534
535
  reverse("wagtailadmin_explore", args=(self.root_page.id,))
535
536
  )
536
537
  self.assertEqual(response.status_code, 200)
537
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
538
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
538
539
 
539
540
  # try to browse into the page itself
540
541
  response = self.client.get(
541
542
  reverse("wagtailadmin_explore", args=(self.old_page.id,))
542
543
  )
543
544
  self.assertEqual(response.status_code, 200)
544
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
545
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
545
546
 
546
547
  def test_search(self):
547
548
  response = self.client.get(
@@ -549,7 +550,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
549
550
  {"q": "old"},
550
551
  )
551
552
  self.assertEqual(response.status_code, 200)
552
- self.assertTemplateUsed(response, "wagtailadmin/pages/index.html")
553
+ self.assertTemplateUsed(response, "wagtailadmin/pages/explorable_index.html")
553
554
 
554
555
  page_ids = [page.id for page in response.context["pages"]]
555
556
  self.assertEqual(page_ids, [self.old_page.id])
@@ -642,7 +643,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
642
643
 
643
644
  response = self.client.get(
644
645
  reverse("wagtailadmin_explore", args=(self.root_page.id,)),
645
- {"latest_revision_created_at_after": "2015-01-01"},
646
+ {"latest_revision_created_at_from": "2015-01-01"},
646
647
  )
647
648
  self.assertEqual(response.status_code, 200)
648
649
  page_ids = {page.id for page in response.context["pages"]}
@@ -650,7 +651,7 @@ class TestPageExplorer(WagtailTestUtils, TestCase):
650
651
  self.assertContainsActiveFilter(
651
652
  response,
652
653
  "Date updated: Jan. 1, 2015 -",
653
- "latest_revision_created_at_after=2015-01-01",
654
+ "latest_revision_created_at_from=2015-01-01",
654
655
  )
655
656
 
656
657
  def test_filter_by_owner(self):
@@ -1270,7 +1271,7 @@ class TestInWorkflowStatus(WagtailTestUtils, TestCase):
1270
1271
  # Warm up cache
1271
1272
  self.client.get(self.url)
1272
1273
 
1273
- with self.assertNumQueries(51):
1274
+ with self.assertNumQueries(47):
1274
1275
  response = self.client.get(self.url)
1275
1276
 
1276
1277
  self.assertEqual(response.status_code, 200)
@@ -243,7 +243,7 @@ class TestPageMove(WagtailTestUtils, TestCase):
243
243
 
244
244
  def test_page_move_after_parent_page_types_changes_to_different_parent_model(self):
245
245
  # Test for issue #10348
246
- # While BusinesSubIndex cannot be created under a SimplePage, we can
246
+ # While BusinessSubIndex cannot be created under a SimplePage, we can
247
247
  # still create it under a SimplePage invoking django-treebeard's add_child
248
248
  # which works great for our purposes.
249
249
  self.assertFalse(BusinessSubIndex.can_exist_under(self.section_a))