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,6 +1,6 @@
1
1
  from django.contrib.auth.models import Group
2
2
  from django.core.files.base import ContentFile
3
- from django.test import TestCase
3
+ from django.test import TestCase, override_settings
4
4
  from django.urls import reverse
5
5
 
6
6
  from wagtail.documents.models import Document
@@ -19,6 +19,7 @@ class TestCollectionPrivacyDocument(WagtailTestUtils, TestCase):
19
19
  def setUp(self):
20
20
  self.fake_file = ContentFile(b"A boring example document")
21
21
  self.fake_file.name = "test.txt"
22
+ self.collection = Collection.objects.get(id=2)
22
23
  self.password_collection = Collection.objects.get(name="Password protected")
23
24
  self.login_collection = Collection.objects.get(name="Login protected")
24
25
  self.group_collection = Collection.objects.get(name="Group protected")
@@ -106,6 +107,28 @@ class TestCollectionPrivacyDocument(WagtailTestUtils, TestCase):
106
107
  )
107
108
  self.assertRedirects(response, "/")
108
109
 
110
+ @override_settings(
111
+ WAGTAILDOCS_PASSWORD_REQUIRED_TEMPLATE="tests/custom_docs_password_required.html"
112
+ )
113
+ def test_anonymous_user_must_authenticate_with_custom_password_required_template(
114
+ self
115
+ ):
116
+ secret_document = Document.objects.create(
117
+ title="Test document",
118
+ file=self.fake_file,
119
+ collection=self.password_collection,
120
+ )
121
+ doc_url = reverse(
122
+ "wagtaildocs_serve", args=(secret_document.id, secret_document.filename)
123
+ )
124
+ response = self.client.get(doc_url)
125
+ self.assertNotEqual(
126
+ response.templates[0].name, "wagtaildocs/password_required.html"
127
+ )
128
+ self.assertEqual(
129
+ response.templates[0].name, "tests/custom_docs_password_required.html"
130
+ )
131
+
109
132
  def test_group_restriction_with_anonymous_user(self):
110
133
  response, url = self.get_document(self.group_collection)
111
134
  self.assertRedirects(response, f"/_util/login/?next={url}")
@@ -133,3 +156,34 @@ class TestCollectionPrivacyDocument(WagtailTestUtils, TestCase):
133
156
  self.login(username="eventmoderator", password="password")
134
157
  response, url = self.get_document(self.login_collection)
135
158
  self.assertEqual(response.status_code, 200)
159
+
160
+ def test_set_shared_password_with_logged_in_user(self):
161
+ self.login()
162
+ response = self.client.get(
163
+ reverse("wagtailadmin_collections:set_privacy", args=(self.collection.id,)),
164
+ )
165
+
166
+ input_el = self.get_soup(response.content).select_one("[data-field-input]")
167
+ self.assertEqual(response.status_code, 200)
168
+
169
+ # check that input option for password is visible
170
+ self.assertIn("password", response.context["form"].fields)
171
+
172
+ # check that the option for password is visible
173
+ self.assertIsNotNone(input_el)
174
+
175
+ @override_settings(
176
+ WAGTAILDOCS_PRIVATE_COLLECTION_OPTIONS={"SHARED_PASSWORD": False}
177
+ )
178
+ def test_unset_shared_password_with_logged_in_user(self):
179
+ self.login()
180
+ response = self.client.get(
181
+ reverse("wagtailadmin_collections:set_privacy", args=(self.collection.id,)),
182
+ )
183
+ self.assertEqual(response.status_code, 200)
184
+ self.assertNotIn("password", response.context["form"].fields)
185
+ self.assertFalse(
186
+ response.context["form"]
187
+ .fields["restriction_type"]
188
+ .valid_value(CollectionViewRestriction.PASSWORD)
189
+ )
@@ -1,4 +1,5 @@
1
1
  from django.test import TestCase
2
+ from django.urls import reverse_lazy
2
3
 
3
4
  from wagtail.documents import get_document_model
4
5
  from wagtail.documents.rich_text import (
@@ -8,6 +9,7 @@ from wagtail.documents.rich_text.editor_html import (
8
9
  DocumentLinkHandler as EditorHtmlDocumentLinkHandler,
9
10
  )
10
11
  from wagtail.fields import RichTextField
12
+ from wagtail.rich_text.feature_registry import FeatureRegistry
11
13
  from wagtail.test.utils import WagtailTestUtils
12
14
 
13
15
 
@@ -60,3 +62,15 @@ class TestFrontendDocumentLinkHandler(TestCase):
60
62
  ),
61
63
  [(get_document_model(), "1", "", "")],
62
64
  )
65
+
66
+
67
+ class TestEntityFeatureChooserUrls(TestCase):
68
+ def test_chooser_urls_exist(self):
69
+ features = FeatureRegistry()
70
+ document = features.get_editor_plugin("draftail", "document-link")
71
+
72
+ self.assertIsNotNone(document.data.get("chooserUrls"))
73
+ self.assertEqual(
74
+ document.data["chooserUrls"]["documentChooser"],
75
+ reverse_lazy("wagtaildocs_chooser:choose"),
76
+ )
@@ -12,6 +12,7 @@ from django.utils.translation import gettext_lazy, ngettext
12
12
 
13
13
  from wagtail.admin import messages
14
14
  from wagtail.admin.auth import PermissionPolicyChecker
15
+ from wagtail.admin.filters import BaseMediaFilterSet
15
16
  from wagtail.admin.ui.tables import (
16
17
  BulkActionsCheckboxColumn,
17
18
  Column,
@@ -25,9 +26,9 @@ from wagtail.admin.views import generic
25
26
  from wagtail.documents import get_document_model
26
27
  from wagtail.documents.forms import get_document_form
27
28
  from wagtail.documents.permissions import permission_policy
28
- from wagtail.models import Collection
29
29
 
30
30
  permission_checker = PermissionPolicyChecker(permission_policy)
31
+ Document = get_document_model()
31
32
 
32
33
 
33
34
  class BulkActionsColumn(BulkActionsCheckboxColumn):
@@ -49,6 +50,14 @@ class DocumentTable(Table):
49
50
  return context
50
51
 
51
52
 
53
+ class DocumentsFilterSet(BaseMediaFilterSet):
54
+ permission_policy = permission_policy
55
+
56
+ class Meta:
57
+ model = Document
58
+ fields = []
59
+
60
+
52
61
  class IndexView(generic.IndexView):
53
62
  permission_policy = permission_policy
54
63
  any_permission_required = ["add", "change", "delete"]
@@ -65,9 +74,11 @@ class IndexView(generic.IndexView):
65
74
  results_template_name = "wagtaildocs/documents/index_results.html"
66
75
  default_ordering = "title"
67
76
  table_class = DocumentTable
77
+ filterset_class = DocumentsFilterSet
68
78
  model = get_document_model()
69
79
  add_item_label = gettext_lazy("Add a document")
70
80
  show_other_searches = True
81
+ _show_breadcrumbs = True
71
82
 
72
83
  def get_base_queryset(self):
73
84
  # Get documents (filtered by user permission)
@@ -75,17 +86,10 @@ class IndexView(generic.IndexView):
75
86
  self.request.user, ["change", "delete"]
76
87
  ).select_related("collection")
77
88
 
78
- def filter_queryset(self, queryset):
79
- self.current_collection = None
80
- collection_id = self.request.GET.get("collection_id")
81
- if collection_id:
82
- try:
83
- self.current_collection = Collection.objects.get(id=collection_id)
84
- queryset = queryset.filter(collection=self.current_collection)
85
- except (ValueError, Collection.DoesNotExist):
86
- pass
87
-
88
- return queryset
89
+ @cached_property
90
+ def current_collection(self):
91
+ # Upon validation, the cleaned data is a Collection instance
92
+ return self.filters and self.filters.form.cleaned_data.get("collection_id")
89
93
 
90
94
  @cached_property
91
95
  def columns(self):
@@ -106,7 +110,7 @@ class IndexView(generic.IndexView):
106
110
  width="16%",
107
111
  ),
108
112
  ]
109
- if self.collections:
113
+ if self.filters and "collection_id" in self.filters.filters:
110
114
  columns.insert(
111
115
  3,
112
116
  Column("collection", label=_("Collection"), accessor="collection.name"),
@@ -130,10 +134,10 @@ class IndexView(generic.IndexView):
130
134
  return next_url
131
135
 
132
136
  def get_add_url(self):
133
- # Pass the query string so that the collection filter is preserved
137
+ # Pass the collection filter to prefill the add form's collection field
134
138
  return set_query_params(
135
139
  super().get_add_url(),
136
- self.request.GET.copy(),
140
+ {"collection_id": self.current_collection and self.current_collection.pk},
137
141
  )
138
142
 
139
143
  def get_edit_url(self, instance):
@@ -142,15 +146,14 @@ class IndexView(generic.IndexView):
142
146
  {"next": self.get_next_url()},
143
147
  )
144
148
 
149
+ def get_filterset_kwargs(self):
150
+ kwargs = super().get_filterset_kwargs()
151
+ kwargs["is_searching"] = self.is_searching
152
+ return kwargs
153
+
145
154
  def get_context_data(self, **kwargs):
146
155
  context = super().get_context_data(**kwargs)
147
-
148
- context.update(
149
- {
150
- "collections": self.collections,
151
- "current_collection": self.current_collection,
152
- }
153
- )
156
+ context["current_collection"] = self.current_collection
154
157
  return context
155
158
 
156
159
 
@@ -12,14 +12,12 @@ from wagtail.admin.views.generic.multiple_upload import EditView as BaseEditView
12
12
 
13
13
  from .. import get_document_model
14
14
  from ..forms import get_document_form, get_document_multi_form
15
- from ..models import UploadedDocument
16
15
  from ..permissions import permission_policy
17
16
 
18
17
 
19
18
  class AddView(BaseAddView):
20
19
  permission_policy = permission_policy
21
20
  template_name = "wagtaildocs/multiple/add.html"
22
- upload_model = UploadedDocument
23
21
 
24
22
  edit_object_url_name = "wagtaildocs:edit_multiple"
25
23
  delete_object_url_name = "wagtaildocs:delete_multiple"
@@ -31,7 +29,7 @@ class AddView(BaseAddView):
31
29
  delete_upload_url_name = "wagtaildocs:delete_upload_multiple"
32
30
  edit_upload_form_prefix = "uploaded-document"
33
31
  context_upload_name = "uploaded_document"
34
- context_upload_id_name = "uploaded_document_id"
32
+ context_upload_id_name = "uploaded_file_id"
35
33
 
36
34
  def get_model(self):
37
35
  return get_document_model()
@@ -90,8 +88,7 @@ class DeleteView(BaseDeleteView):
90
88
  class CreateFromUploadedDocumentView(BaseCreateFromUploadView):
91
89
  edit_upload_url_name = "wagtaildocs:create_multiple_from_uploaded_document"
92
90
  delete_upload_url_name = "wagtaildocs:delete_upload_multiple"
93
- upload_model = UploadedDocument
94
- upload_pk_url_kwarg = "uploaded_document_id"
91
+ upload_pk_url_kwarg = "uploaded_file_id"
95
92
  edit_upload_form_prefix = "uploaded-document"
96
93
  context_object_id_name = "doc_id"
97
94
  context_upload_name = "uploaded_document"
@@ -118,5 +115,7 @@ class CreateFromUploadedDocumentView(BaseCreateFromUploadView):
118
115
 
119
116
 
120
117
  class DeleteUploadView(BaseDeleteUploadView):
121
- upload_model = UploadedDocument
122
- upload_pk_url_kwarg = "uploaded_document_id"
118
+ upload_pk_url_kwarg = "uploaded_file_id"
119
+
120
+ def get_model(self):
121
+ return get_document_model()
@@ -1,3 +1,5 @@
1
+ from warnings import warn
2
+
1
3
  from django.conf import settings
2
4
  from django.http import FileResponse, Http404, HttpResponse
3
5
  from django.shortcuts import get_object_or_404, redirect
@@ -12,6 +14,7 @@ from wagtail.documents.models import document_served
12
14
  from wagtail.forms import PasswordViewRestrictionForm
13
15
  from wagtail.models import CollectionViewRestriction
14
16
  from wagtail.utils import sendfile_streaming_backend
17
+ from wagtail.utils.deprecation import RemovedInWagtail70Warning
15
18
  from wagtail.utils.sendfile import sendfile
16
19
 
17
20
 
@@ -135,9 +138,21 @@ def authenticate_with_password(request, restriction_id):
135
138
 
136
139
  password_required_template = getattr(
137
140
  settings,
138
- "DOCUMENT_PASSWORD_REQUIRED_TEMPLATE",
141
+ "WAGTAILDOCS_PASSWORD_REQUIRED_TEMPLATE",
139
142
  "wagtaildocs/password_required.html",
140
143
  )
141
144
 
145
+ if hasattr(settings, "DOCUMENT_PASSWORD_REQUIRED_TEMPLATE"):
146
+ warn(
147
+ "The `DOCUMENT_PASSWORD_REQUIRED_TEMPLATE` setting is deprecated - use `WAGTAILDOCS_PASSWORD_REQUIRED_TEMPLATE` instead.",
148
+ category=RemovedInWagtail70Warning,
149
+ )
150
+
151
+ password_required_template = getattr(
152
+ settings,
153
+ "DOCUMENT_PASSWORD_REQUIRED_TEMPLATE",
154
+ password_required_template,
155
+ )
156
+
142
157
  context = {"form": form, "action_url": action_url}
143
158
  return TemplateResponse(request, password_required_template, context)
@@ -1,7 +1,8 @@
1
+ from warnings import warn
2
+
1
3
  from django.conf import settings
2
4
  from django.template.response import TemplateResponse
3
- from django.urls import include, path, reverse
4
- from django.utils.html import format_html
5
+ from django.urls import include, path, reverse, reverse_lazy
5
6
  from django.utils.translation import gettext, ngettext
6
7
  from django.utils.translation import gettext_lazy as _
7
8
 
@@ -31,6 +32,7 @@ from wagtail.documents.views.bulk_actions import (
31
32
  )
32
33
  from wagtail.documents.views.chooser import viewset as chooser_viewset
33
34
  from wagtail.models import BaseViewRestriction
35
+ from wagtail.utils.deprecation import RemovedInWagtail70Warning
34
36
  from wagtail.wagtail_hooks import require_wagtail_login
35
37
 
36
38
 
@@ -64,18 +66,6 @@ def register_documents_menu_item():
64
66
  )
65
67
 
66
68
 
67
- @hooks.register("insert_editor_js")
68
- def editor_js():
69
- return format_html(
70
- """
71
- <script>
72
- window.chooserUrls.documentChooser = '{0}';
73
- </script>
74
- """,
75
- reverse("wagtaildocs_chooser:choose"),
76
- )
77
-
78
-
79
69
  @hooks.register("register_rich_text_features")
80
70
  def register_document_feature(features):
81
71
  features.register_link_type(DocumentLinkHandler)
@@ -88,6 +78,9 @@ def register_document_feature(features):
88
78
  "type": "DOCUMENT",
89
79
  "icon": "doc-full-inverse",
90
80
  "description": gettext("Document"),
81
+ "chooserUrls": {
82
+ "documentChooser": reverse_lazy("wagtaildocs_chooser:choose")
83
+ },
91
84
  },
92
85
  js=["wagtaildocs/js/document-chooser-modal.js"],
93
86
  ),
@@ -190,10 +183,22 @@ def check_view_restrictions(document, request):
190
183
 
191
184
  password_required_template = getattr(
192
185
  settings,
193
- "DOCUMENT_PASSWORD_REQUIRED_TEMPLATE",
186
+ "WAGTAILDOCS_PASSWORD_REQUIRED_TEMPLATE",
194
187
  "wagtaildocs/password_required.html",
195
188
  )
196
189
 
190
+ if hasattr(settings, "DOCUMENT_PASSWORD_REQUIRED_TEMPLATE"):
191
+ warn(
192
+ "The `DOCUMENT_PASSWORD_REQUIRED_TEMPLATE` setting is deprecated - use `WAGTAILDOCS_PASSWORD_REQUIRED_TEMPLATE` instead.",
193
+ category=RemovedInWagtail70Warning,
194
+ )
195
+
196
+ password_required_template = getattr(
197
+ settings,
198
+ "DOCUMENT_PASSWORD_REQUIRED_TEMPLATE",
199
+ password_required_template,
200
+ )
201
+
197
202
  context = {"form": form, "action_url": action_url}
198
203
  return TemplateResponse(request, password_required_template, context)
199
204
 
wagtail/embeds/blocks.py CHANGED
@@ -85,5 +85,10 @@ class EmbedBlock(blocks.URLBlock):
85
85
  raise ValidationError(_("Cannot find an embed for this URL."))
86
86
  return super().clean(value)
87
87
 
88
+ def normalize(self, value):
89
+ if isinstance(value, EmbedValue):
90
+ return value
91
+ return EmbedValue(value)
92
+
88
93
  class Meta:
89
94
  icon = "media"
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2024-01-24 13:51+0000\n"
11
+ "POT-Creation-Date: 2024-04-18 17:28+0100\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -62,6 +62,6 @@ msgid ""
62
62
  "Please try again later."
63
63
  msgstr ""
64
64
 
65
- #: wagtail_hooks.py:51
65
+ #: wagtail_hooks.py:38
66
66
  msgid "Embed"
67
67
  msgstr ""
@@ -4,8 +4,8 @@
4
4
  #
5
5
  # Translators:
6
6
  # Bertrand Bordage <bordage.bertrand@gmail.com>, 2015,2018
7
- # fpoulain <fpoulain@metrodore.fr>, 2018
8
- # fpoulain <fpoulain@metrodore.fr>, 2018
7
+ # 69c761fa404d2f74d5a7a2904d9e6f47_dc2dbc9 <f37077798760362881f9d396b6e22ec7_1878>, 2018
8
+ # 69c761fa404d2f74d5a7a2904d9e6f47_dc2dbc9 <f37077798760362881f9d396b6e22ec7_1878>, 2018
9
9
  # Léo <leo@naeka.fr>, 2016
10
10
  # Loic Teixeira, 2018,2020
11
11
  # Loic Teixeira, 2020
@@ -17,8 +17,8 @@ msgstr ""
17
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
18
  "Content-Transfer-Encoding: 8bit\n"
19
19
  "Language: he_IL\n"
20
- "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % "
21
- "1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n"
20
+ "Plural-Forms: nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % "
21
+ "1 == 0) ? 1: 2;\n"
22
22
 
23
23
  msgid "Cannot find an embed for this URL."
24
24
  msgstr "לא ניתן למצוא הטמעה לקישור זה "
@@ -18,7 +18,7 @@ class MediaEmbedHandler(EmbedHandler):
18
18
  return get_embed(attrs["url"])
19
19
 
20
20
  @staticmethod
21
- def expand_db_attributes(attrs):
21
+ def expand_db_attributes(attrs: dict) -> str:
22
22
  """
23
23
  Given a dict of attributes from the <embed> tag, return the real HTML
24
24
  representation for use on the front-end.
@@ -1,6 +1,7 @@
1
1
  from unittest.mock import patch
2
2
 
3
3
  from django.test import TestCase, override_settings
4
+ from django.urls import reverse_lazy
4
5
 
5
6
  from wagtail.embeds.exceptions import EmbedNotFoundException
6
7
  from wagtail.embeds.models import Embed
@@ -9,6 +10,7 @@ from wagtail.embeds.rich_text.editor_html import (
9
10
  MediaEmbedHandler as EditorHtmlMediaEmbedHandler,
10
11
  )
11
12
  from wagtail.rich_text import expand_db_html
13
+ from wagtail.rich_text.feature_registry import FeatureRegistry
12
14
  from wagtail.test.utils import WagtailTestUtils
13
15
 
14
16
 
@@ -143,3 +145,15 @@ class TestFrontendMediaEmbedHandler(TestCase):
143
145
  get_embed.assert_called_with(
144
146
  "https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25", None, None
145
147
  )
148
+
149
+
150
+ class TestEntityFeatureChooserUrls(TestCase):
151
+ def test_chooser_urls_exist(self):
152
+ features = FeatureRegistry()
153
+ embed = features.get_editor_plugin("draftail", "embed")
154
+
155
+ self.assertIsNotNone(embed.data.get("chooserUrls"))
156
+ self.assertEqual(
157
+ embed.data["chooserUrls"]["embedsChooser"],
158
+ reverse_lazy("wagtailembeds:chooser"),
159
+ )
@@ -1,5 +1,4 @@
1
- from django.urls import include, path, reverse
2
- from django.utils.html import format_html
1
+ from django.urls import include, path, reverse_lazy
3
2
  from django.utils.translation import gettext as _
4
3
 
5
4
  import wagtail.admin.rich_text.editors.draftail.features as draftail_features
@@ -17,18 +16,6 @@ def register_admin_urls():
17
16
  ]
18
17
 
19
18
 
20
- @hooks.register("insert_editor_js")
21
- def editor_js():
22
- return format_html(
23
- """
24
- <script>
25
- window.chooserUrls.embedsChooser = '{0}';
26
- </script>
27
- """,
28
- reverse("wagtailembeds:chooser"),
29
- )
30
-
31
-
32
19
  @hooks.register("register_rich_text_features")
33
20
  def register_embed_feature(features):
34
21
  # define a handler for converting <embed embedtype="media"> tags into frontend HTML
@@ -49,6 +36,9 @@ def register_embed_feature(features):
49
36
  "type": "EMBED",
50
37
  "icon": "media",
51
38
  "description": _("Embed"),
39
+ "chooserUrls": {
40
+ "embedsChooser": reverse_lazy("wagtailembeds:chooser"),
41
+ },
52
42
  },
53
43
  js=["wagtailembeds/js/embed-chooser-modal.js"],
54
44
  ),
wagtail/fields.py CHANGED
@@ -131,59 +131,14 @@ class StreamField(models.Field):
131
131
  return name, path, args, kwargs
132
132
 
133
133
  def to_python(self, value):
134
- value = self._to_python(value)
134
+ result = self.stream_block.to_python(value)
135
135
 
136
136
  # The top-level StreamValue is passed a reference to the StreamField, to support
137
137
  # pickling. This is necessary because unpickling needs access to the StreamBlock
138
138
  # definition, which cannot itself be pickled; instead we store a pointer to the
139
139
  # field within the model, which gives us a path to retrieve the StreamBlock definition.
140
-
141
- value._stream_field = self
142
- return value
143
-
144
- def _to_python(self, value):
145
- if value is None or value == "":
146
- return StreamValue(self.stream_block, [])
147
- elif isinstance(value, StreamValue):
148
- return value
149
- elif isinstance(value, str):
150
- try:
151
- unpacked_value = json.loads(value)
152
- except ValueError:
153
- # value is not valid JSON; most likely, this field was previously a
154
- # rich text field before being migrated to StreamField, and the data
155
- # was left intact in the migration. Return an empty stream instead
156
- # (but keep the raw text available as an attribute, so that it can be
157
- # used to migrate that data to StreamField)
158
- return StreamValue(self.stream_block, [], raw_text=value)
159
-
160
- if unpacked_value is None:
161
- # we get here if value is the literal string 'null'. This should probably
162
- # never happen if the rest of the (de)serialization code is working properly,
163
- # but better to handle it just in case...
164
- return StreamValue(self.stream_block, [])
165
-
166
- return self.stream_block.to_python(unpacked_value)
167
- elif value and isinstance(value, list) and isinstance(value[0], dict):
168
- # The value is already unpacked since JSONField-based StreamField should
169
- # accept deserialised values (no need to call json.dumps() first).
170
- # In addition, the value is not a list of (block_name, value) tuples
171
- # handled in the `else` block.
172
- return self.stream_block.to_python(value)
173
- else:
174
- # See if it looks like the standard non-smart representation of a
175
- # StreamField value: a list of (block_name, value) tuples
176
- try:
177
- [None for (x, y) in value]
178
- except (TypeError, ValueError):
179
- # Give up trying to make sense of the value
180
- raise TypeError(
181
- "Cannot handle %r (type %r) as a value of StreamField"
182
- % (value, type(value))
183
- )
184
-
185
- # Test succeeded, so return as a StreamValue-ified version of that value
186
- return StreamValue(self.stream_block, value)
140
+ result._stream_field = self
141
+ return result
187
142
 
188
143
  def get_prep_value(self, value):
189
144
  if (
@@ -24,7 +24,7 @@ urlpatterns = [
24
24
  path("multiple/add/", multiple.AddView.as_view(), name="add_multiple"),
25
25
  path("multiple/<int:image_id>/", multiple.EditView.as_view(), name="edit_multiple"),
26
26
  path(
27
- "multiple/create_from_uploaded_image/<int:uploaded_image_id>/",
27
+ "multiple/create_from_uploaded_image/<int:uploaded_file_id>/",
28
28
  multiple.CreateFromUploadedImageView.as_view(),
29
29
  name="create_multiple_from_uploaded_image",
30
30
  ),
@@ -34,7 +34,7 @@ urlpatterns = [
34
34
  name="delete_multiple",
35
35
  ),
36
36
  path(
37
- "multiple/delete_upload/<int:uploaded_image_id>/",
37
+ "multiple/delete_upload/<int:uploaded_file_id>/",
38
38
  multiple.DeleteUploadView.as_view(),
39
39
  name="delete_upload_multiple",
40
40
  ),
Binary file
Binary file
wagtail/images/fields.py CHANGED
@@ -205,5 +205,7 @@ def image_format_name_to_content_type(image_format_name):
205
205
  return "image/webp"
206
206
  elif image_format_name == "avif":
207
207
  return "image/avif"
208
+ elif image_format_name == "ico":
209
+ return "image/x-icon"
208
210
  else:
209
211
  raise ValueError("Unknown image format name")
@@ -409,7 +409,7 @@ class WebPQualityOperation(FilterOperation):
409
409
 
410
410
 
411
411
  class FormatOperation(FilterOperation):
412
- supported_formats = ["jpeg", "png", "gif", "webp", "avif"]
412
+ supported_formats = ["jpeg", "png", "gif", "webp", "avif", "ico"]
413
413
 
414
414
  def construct(self, format, *options):
415
415
  self.format = format
@@ -416,6 +416,18 @@ msgstr "Previsualització"
416
416
  msgid "URL"
417
417
  msgstr "URL"
418
418
 
419
+ msgid "Image URL"
420
+ msgstr "URL d'imatge"
421
+
422
+ msgid "Copy URL"
423
+ msgstr "Copiar URL"
424
+
425
+ msgid "Copied to clipboard"
426
+ msgstr "S'ha copiat al porta-retalls"
427
+
428
+ msgid "Copying to clipboard failed"
429
+ msgstr "Ha fallat la còpia al porta-retalls"
430
+
419
431
  msgid "Add multiple images"
420
432
  msgstr "Afegir diverses imatges"
421
433