wagtail 6.1.2__py3-none-any.whl → 6.2rc1__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 (644) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_for_translation.py +15 -1
  3. wagtail/admin/checks.py +20 -30
  4. wagtail/admin/forms/pages.py +10 -0
  5. wagtail/admin/icons.py +43 -0
  6. wagtail/admin/locale/ar/LC_MESSAGES/django.po +2 -2
  7. wagtail/admin/locale/be/LC_MESSAGES/django.po +7 -7
  8. wagtail/admin/locale/be/LC_MESSAGES/djangojs.po +3 -3
  9. wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
  10. wagtail/admin/locale/ca/LC_MESSAGES/django.po +51 -50
  11. wagtail/admin/locale/cs/LC_MESSAGES/django.po +10 -8
  12. wagtail/admin/locale/de/LC_MESSAGES/django.po +49 -47
  13. wagtail/admin/locale/dv/LC_MESSAGES/django.po +8 -8
  14. wagtail/admin/locale/el/LC_MESSAGES/django.po +4 -4
  15. wagtail/admin/locale/en/LC_MESSAGES/django.po +405 -295
  16. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -3
  17. wagtail/admin/locale/es/LC_MESSAGES/django.po +40 -39
  18. wagtail/admin/locale/es_419/LC_MESSAGES/django.po +8 -8
  19. wagtail/admin/locale/et/LC_MESSAGES/django.po +14 -12
  20. wagtail/admin/locale/fa/LC_MESSAGES/django.mo +0 -0
  21. wagtail/admin/locale/fa/LC_MESSAGES/django.po +93 -19
  22. wagtail/admin/locale/fa/LC_MESSAGES/djangojs.mo +0 -0
  23. wagtail/admin/locale/fa/LC_MESSAGES/djangojs.po +5 -1
  24. wagtail/admin/locale/fi/LC_MESSAGES/django.po +18 -18
  25. wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
  26. wagtail/admin/locale/fr/LC_MESSAGES/django.po +134 -46
  27. wagtail/admin/locale/gl/LC_MESSAGES/django.po +55 -54
  28. wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +13 -12
  29. wagtail/admin/locale/hr_HR/LC_MESSAGES/djangojs.po +2 -2
  30. wagtail/admin/locale/hu/LC_MESSAGES/django.po +45 -42
  31. wagtail/admin/locale/id_ID/LC_MESSAGES/django.po +6 -6
  32. wagtail/admin/locale/is_IS/LC_MESSAGES/django.po +53 -51
  33. wagtail/admin/locale/it/LC_MESSAGES/django.po +56 -55
  34. wagtail/admin/locale/ja/LC_MESSAGES/django.po +2 -2
  35. wagtail/admin/locale/ko/LC_MESSAGES/django.po +18 -17
  36. wagtail/admin/locale/lt/LC_MESSAGES/django.po +4 -4
  37. wagtail/admin/locale/nb/LC_MESSAGES/django.po +22 -22
  38. wagtail/admin/locale/nl/LC_MESSAGES/django.po +44 -41
  39. wagtail/admin/locale/pl/LC_MESSAGES/django.po +49 -47
  40. wagtail/admin/locale/pl/LC_MESSAGES/djangojs.po +3 -3
  41. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  42. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +46 -26
  43. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +21 -20
  44. wagtail/admin/locale/ro/LC_MESSAGES/django.po +51 -50
  45. wagtail/admin/locale/ru/LC_MESSAGES/django.po +60 -59
  46. wagtail/admin/locale/ru/LC_MESSAGES/djangojs.po +3 -3
  47. wagtail/admin/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  48. wagtail/admin/locale/sk_SK/LC_MESSAGES/django.po +15 -5
  49. wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
  50. wagtail/admin/locale/sl/LC_MESSAGES/django.po +86 -39
  51. wagtail/admin/locale/sl/LC_MESSAGES/djangojs.po +2 -2
  52. wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
  53. wagtail/admin/locale/sv/LC_MESSAGES/django.po +117 -41
  54. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.mo +0 -0
  55. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.po +5 -2
  56. wagtail/admin/locale/tet/LC_MESSAGES/django.po +2 -2
  57. wagtail/admin/locale/th/LC_MESSAGES/django.po +4 -4
  58. wagtail/admin/locale/tr/LC_MESSAGES/django.po +4 -4
  59. wagtail/admin/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  60. wagtail/admin/locale/uk/LC_MESSAGES/django.po +11 -10
  61. wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  62. wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.po +84 -13
  63. wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +2 -2
  64. wagtail/admin/menu.py +2 -2
  65. wagtail/admin/migrations/0004_editingsession.py +57 -0
  66. wagtail/admin/migrations/0005_editingsession_is_editing.py +18 -0
  67. wagtail/admin/models.py +36 -3
  68. wagtail/admin/rich_text/editors/draftail/__init__.py +2 -20
  69. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  70. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  71. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  72. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  73. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  74. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  75. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  76. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  77. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  78. wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
  79. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  80. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  81. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  82. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  83. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  84. wagtail/admin/static/wagtailadmin/js/preview-panel.js +2 -1
  85. wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +11 -0
  86. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  87. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  88. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  89. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  90. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  91. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  92. wagtail/admin/static/wagtailadmin/js/userbar.js +2 -1
  93. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +11 -0
  94. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  95. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +0 -12
  96. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  97. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  98. wagtail/admin/templates/wagtailadmin/collection_privacy/ancestor_privacy.html +2 -6
  99. wagtail/admin/templates/wagtailadmin/generic/index_results.html +1 -17
  100. wagtail/admin/templates/wagtailadmin/generic/listing_results.html +20 -1
  101. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +2 -11
  102. wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +2 -6
  103. wagtail/admin/templates/wagtailadmin/page_privacy/no_privacy.html +2 -0
  104. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
  105. wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -1
  106. wagtail/admin/templates/wagtailadmin/reports/aging_pages_results.html +54 -0
  107. wagtail/admin/templates/wagtailadmin/reports/base_page_report.html +1 -17
  108. wagtail/admin/templates/wagtailadmin/reports/base_page_report_results.html +10 -0
  109. wagtail/admin/templates/wagtailadmin/reports/base_report.html +1 -40
  110. wagtail/admin/templates/wagtailadmin/reports/base_report_results.html +1 -0
  111. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +21 -27
  112. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +48 -54
  113. wagtail/admin/templates/wagtailadmin/reports/{locked_pages.html → locked_pages_results.html} +3 -3
  114. wagtail/admin/templates/wagtailadmin/reports/page_types_usage_results.html +10 -0
  115. wagtail/admin/templates/wagtailadmin/reports/site_history_results.html +53 -0
  116. wagtail/admin/templates/wagtailadmin/reports/workflow_results.html +74 -0
  117. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +56 -0
  118. wagtail/admin/templates/wagtailadmin/shared/_workflow_init.html +8 -44
  119. wagtail/admin/templates/wagtailadmin/shared/avatar.html +11 -1
  120. wagtail/admin/templates/wagtailadmin/shared/dialog/dialog.html +5 -4
  121. wagtail/admin/templates/wagtailadmin/shared/dropdown/dropdown_button.html +2 -1
  122. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +132 -0
  123. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +44 -0
  124. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +7 -1
  125. wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +1 -1
  126. wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +32 -16
  127. wagtail/admin/templates/wagtailadmin/skeleton.html +1 -1
  128. wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +9 -11
  129. wagtail/admin/templatetags/wagtailadmin_tags.py +13 -2
  130. wagtail/admin/tests/formats/en/__init__.py +0 -0
  131. wagtail/admin/tests/formats/en/formats.py +1 -0
  132. wagtail/admin/tests/pages/test_create_page.py +47 -0
  133. wagtail/admin/tests/pages/test_edit_page.py +10 -8
  134. wagtail/admin/tests/pages/test_parent_page_chooser_view.py +45 -1
  135. wagtail/admin/tests/test_checks.py +53 -3
  136. wagtail/admin/tests/test_collections_views.py +62 -1
  137. wagtail/admin/tests/test_edit_handlers.py +37 -0
  138. wagtail/admin/tests/test_editing_sessions.py +1336 -0
  139. wagtail/admin/tests/test_icon_sprite.py +12 -21
  140. wagtail/admin/tests/test_page_chooser.py +309 -7
  141. wagtail/admin/tests/test_privacy.py +82 -0
  142. wagtail/admin/tests/test_reports_views.py +464 -70
  143. wagtail/admin/tests/test_userbar.py +93 -6
  144. wagtail/admin/tests/test_workflows.py +223 -33
  145. wagtail/admin/tests/viewsets/test_model_viewset.py +151 -2
  146. wagtail/admin/ui/editing_sessions.py +57 -0
  147. wagtail/admin/urls/__init__.py +9 -15
  148. wagtail/admin/urls/editing_sessions.py +17 -0
  149. wagtail/admin/urls/reports.py +33 -1
  150. wagtail/admin/userbar.py +77 -20
  151. wagtail/admin/views/chooser.py +49 -22
  152. wagtail/admin/views/collections.py +0 -11
  153. wagtail/admin/views/editing_sessions.py +193 -0
  154. wagtail/admin/views/generic/__init__.py +1 -0
  155. wagtail/admin/views/generic/base.py +3 -2
  156. wagtail/admin/views/generic/history.py +9 -3
  157. wagtail/admin/views/generic/mixins.py +44 -3
  158. wagtail/admin/views/generic/models.py +46 -72
  159. wagtail/admin/views/generic/permissions.py +20 -10
  160. wagtail/admin/views/home.py +2 -31
  161. wagtail/admin/views/page_privacy.py +20 -5
  162. wagtail/admin/views/pages/choose_parent.py +62 -0
  163. wagtail/admin/views/pages/edit.py +28 -0
  164. wagtail/admin/views/reports/aging_pages.py +6 -10
  165. wagtail/admin/views/reports/audit_logging.py +13 -42
  166. wagtail/admin/views/reports/base.py +31 -4
  167. wagtail/admin/views/reports/locked_pages.py +5 -8
  168. wagtail/admin/views/reports/page_types_usage.py +6 -10
  169. wagtail/admin/views/reports/workflows.py +36 -12
  170. wagtail/admin/viewsets/base.py +8 -3
  171. wagtail/admin/viewsets/chooser.py +1 -1
  172. wagtail/admin/viewsets/model.py +26 -1
  173. wagtail/admin/wagtail_hooks.py +2 -1
  174. wagtail/api/v2/filters.py +6 -0
  175. wagtail/api/v2/tests/test_documents.py +1 -1
  176. wagtail/api/v2/tests/test_images.py +1 -1
  177. wagtail/api/v2/tests/test_pages.py +11 -1
  178. wagtail/api/v2/utils.py +2 -2
  179. wagtail/blocks/base.py +35 -12
  180. wagtail/blocks/definition_lookup.py +85 -0
  181. wagtail/blocks/list_block.py +12 -0
  182. wagtail/blocks/migrations/migrate_operation.py +2 -0
  183. wagtail/blocks/stream_block.py +19 -0
  184. wagtail/blocks/struct_block.py +19 -0
  185. wagtail/contrib/forms/locale/be/LC_MESSAGES/django.po +3 -3
  186. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
  187. wagtail/contrib/forms/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  188. wagtail/contrib/forms/locale/pl/LC_MESSAGES/django.po +3 -3
  189. wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  190. wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.po +2 -2
  191. wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +3 -3
  192. wagtail/contrib/forms/locale/sl/LC_MESSAGES/django.po +2 -2
  193. wagtail/contrib/frontend_cache/backends/__init__.py +5 -0
  194. wagtail/contrib/frontend_cache/backends/azure.py +179 -0
  195. wagtail/contrib/frontend_cache/backends/base.py +28 -0
  196. wagtail/contrib/frontend_cache/backends/cloudflare.py +114 -0
  197. wagtail/contrib/frontend_cache/backends/cloudfront.py +99 -0
  198. wagtail/contrib/frontend_cache/backends/http.py +64 -0
  199. wagtail/contrib/frontend_cache/tests.py +59 -17
  200. wagtail/contrib/frontend_cache/utils.py +26 -8
  201. wagtail/contrib/redirects/filters.py +15 -1
  202. wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +4 -4
  203. wagtail/contrib/redirects/locale/be/LC_MESSAGES/django.po +3 -3
  204. wagtail/contrib/redirects/locale/bg/LC_MESSAGES/django.po +4 -4
  205. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +4 -4
  206. wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.po +4 -4
  207. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +6 -6
  208. wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.po +5 -4
  209. wagtail/contrib/redirects/locale/el/LC_MESSAGES/django.po +7 -7
  210. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +37 -72
  211. wagtail/contrib/redirects/locale/es/LC_MESSAGES/django.po +6 -6
  212. wagtail/contrib/redirects/locale/et/LC_MESSAGES/django.po +4 -4
  213. wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.mo +0 -0
  214. wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.po +18 -5
  215. wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.po +6 -6
  216. wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +4 -4
  217. wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.po +4 -4
  218. wagtail/contrib/redirects/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  219. wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.po +6 -6
  220. wagtail/contrib/redirects/locale/id_ID/LC_MESSAGES/django.po +4 -4
  221. wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.po +6 -6
  222. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +4 -4
  223. wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.po +2 -2
  224. wagtail/contrib/redirects/locale/ko/LC_MESSAGES/django.po +4 -4
  225. wagtail/contrib/redirects/locale/lt/LC_MESSAGES/django.po +4 -4
  226. wagtail/contrib/redirects/locale/mn/LC_MESSAGES/django.po +4 -4
  227. wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.po +4 -4
  228. wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.po +4 -4
  229. wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.po +9 -9
  230. wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.po +5 -5
  231. wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.po +4 -4
  232. wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.po +4 -4
  233. wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.po +7 -7
  234. wagtail/contrib/redirects/locale/sk_SK/LC_MESSAGES/django.po +4 -4
  235. wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.po +6 -6
  236. wagtail/contrib/redirects/locale/sr/LC_MESSAGES/django.po +2 -2
  237. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.po +4 -4
  238. wagtail/contrib/redirects/locale/tet/LC_MESSAGES/django.po +4 -4
  239. wagtail/contrib/redirects/locale/th/LC_MESSAGES/django.po +4 -4
  240. wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.po +4 -4
  241. wagtail/contrib/redirects/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  242. wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.po +4 -4
  243. wagtail/contrib/redirects/locale/zh/LC_MESSAGES/django.po +4 -4
  244. wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.po +4 -4
  245. wagtail/contrib/redirects/locale/zh_Hant/LC_MESSAGES/django.po +4 -4
  246. wagtail/contrib/redirects/models.py +6 -5
  247. wagtail/contrib/redirects/templates/wagtailredirects/edit.html +1 -38
  248. wagtail/contrib/redirects/tests/test_redirects.py +141 -1
  249. wagtail/contrib/redirects/urls.py +1 -2
  250. wagtail/contrib/redirects/views.py +39 -80
  251. wagtail/contrib/routable_page/models.py +6 -4
  252. wagtail/contrib/routable_page/tests.py +11 -0
  253. wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.po +4 -4
  254. wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.po +7 -7
  255. wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.po +8 -8
  256. wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.po +2 -2
  257. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +4 -4
  258. wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.po +6 -6
  259. wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.po +4 -4
  260. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +1 -1
  261. wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.po +6 -6
  262. wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.po +4 -4
  263. wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.po +4 -4
  264. wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.po +6 -6
  265. wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.mo +0 -0
  266. wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +9 -6
  267. wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.po +6 -6
  268. wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  269. wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.po +4 -4
  270. wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.po +4 -4
  271. wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.po +8 -8
  272. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +6 -6
  273. wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.po +4 -4
  274. wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.po +4 -4
  275. wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.po +6 -6
  276. wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.po +4 -4
  277. wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.po +6 -6
  278. wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.po +9 -9
  279. wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.po +4 -4
  280. wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.po +4 -4
  281. wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.po +4 -4
  282. wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.po +9 -9
  283. wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.po +4 -4
  284. wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.mo +0 -0
  285. wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.po +62 -8
  286. wagtail/contrib/search_promotions/locale/sr/LC_MESSAGES/django.po +2 -2
  287. wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.mo +0 -0
  288. wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.po +9 -6
  289. wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.po +4 -4
  290. wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +4 -4
  291. wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  292. wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.po +4 -4
  293. wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.po +2 -2
  294. wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.po +2 -2
  295. wagtail/contrib/settings/locale/be/LC_MESSAGES/django.po +3 -3
  296. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +4 -4
  297. wagtail/contrib/settings/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  298. wagtail/contrib/settings/locale/pl/LC_MESSAGES/django.po +3 -3
  299. wagtail/contrib/settings/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  300. wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +3 -3
  301. wagtail/contrib/settings/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  302. wagtail/contrib/settings/locale/sk_SK/LC_MESSAGES/django.po +10 -1
  303. wagtail/contrib/settings/locale/sl/LC_MESSAGES/django.po +2 -2
  304. wagtail/contrib/settings/locale/sr/LC_MESSAGES/django.po +2 -2
  305. wagtail/contrib/simple_translation/locale/be/LC_MESSAGES/django.po +3 -3
  306. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +5 -1
  307. wagtail/contrib/simple_translation/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  308. wagtail/contrib/simple_translation/locale/pl/LC_MESSAGES/django.po +3 -3
  309. wagtail/contrib/simple_translation/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  310. wagtail/contrib/simple_translation/locale/ru/LC_MESSAGES/django.po +3 -3
  311. wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.po +2 -2
  312. wagtail/contrib/simple_translation/models.py +2 -1
  313. wagtail/contrib/styleguide/locale/be/LC_MESSAGES/django.po +3 -3
  314. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  315. wagtail/contrib/styleguide/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  316. wagtail/contrib/styleguide/locale/pl/LC_MESSAGES/django.po +3 -3
  317. wagtail/contrib/styleguide/locale/ru/LC_MESSAGES/django.po +3 -3
  318. wagtail/contrib/styleguide/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  319. wagtail/contrib/styleguide/locale/sk_SK/LC_MESSAGES/django.po +5 -1
  320. wagtail/contrib/styleguide/locale/sl/LC_MESSAGES/django.po +2 -2
  321. wagtail/contrib/styleguide/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  322. wagtail/contrib/styleguide/locale/zh_Hans/LC_MESSAGES/django.po +3 -0
  323. wagtail/contrib/table_block/locale/be/LC_MESSAGES/django.po +3 -3
  324. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  325. wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.mo +0 -0
  326. wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.po +27 -1
  327. wagtail/contrib/table_block/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  328. wagtail/contrib/table_block/locale/pl/LC_MESSAGES/django.po +3 -3
  329. wagtail/contrib/table_block/locale/ru/LC_MESSAGES/django.po +3 -3
  330. wagtail/contrib/table_block/locale/sl/LC_MESSAGES/django.mo +0 -0
  331. wagtail/contrib/table_block/locale/sl/LC_MESSAGES/django.po +29 -3
  332. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  333. wagtail/contrib/typed_table_block/blocks.py +19 -0
  334. wagtail/contrib/typed_table_block/locale/be/LC_MESSAGES/django.po +3 -3
  335. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  336. wagtail/contrib/typed_table_block/locale/fr/LC_MESSAGES/django.mo +0 -0
  337. wagtail/contrib/typed_table_block/locale/fr/LC_MESSAGES/django.po +12 -1
  338. wagtail/contrib/typed_table_block/locale/pl/LC_MESSAGES/django.po +3 -3
  339. wagtail/contrib/typed_table_block/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  340. wagtail/contrib/typed_table_block/locale/ru/LC_MESSAGES/django.po +3 -3
  341. wagtail/contrib/typed_table_block/locale/sl/LC_MESSAGES/django.mo +0 -0
  342. wagtail/contrib/typed_table_block/locale/sl/LC_MESSAGES/django.po +14 -4
  343. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  344. wagtail/contrib/typed_table_block/tests.py +38 -0
  345. wagtail/coreutils.py +1 -1
  346. wagtail/documents/__init__.py +1 -1
  347. wagtail/documents/locale/ar/LC_MESSAGES/django.po +8 -8
  348. wagtail/documents/locale/be/LC_MESSAGES/django.po +11 -11
  349. wagtail/documents/locale/bg/LC_MESSAGES/django.po +4 -4
  350. wagtail/documents/locale/ca/LC_MESSAGES/django.mo +0 -0
  351. wagtail/documents/locale/ca/LC_MESSAGES/django.po +12 -11
  352. wagtail/documents/locale/cs/LC_MESSAGES/django.po +6 -6
  353. wagtail/documents/locale/de/LC_MESSAGES/django.po +10 -8
  354. wagtail/documents/locale/el/LC_MESSAGES/django.po +8 -8
  355. wagtail/documents/locale/en/LC_MESSAGES/django.po +8 -8
  356. wagtail/documents/locale/es/LC_MESSAGES/django.po +8 -8
  357. wagtail/documents/locale/et/LC_MESSAGES/django.po +6 -6
  358. wagtail/documents/locale/fa/LC_MESSAGES/django.mo +0 -0
  359. wagtail/documents/locale/fa/LC_MESSAGES/django.po +17 -8
  360. wagtail/documents/locale/fi/LC_MESSAGES/django.po +10 -10
  361. wagtail/documents/locale/fr/LC_MESSAGES/django.po +6 -6
  362. wagtail/documents/locale/gl/LC_MESSAGES/django.po +8 -8
  363. wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +14 -14
  364. wagtail/documents/locale/hu/LC_MESSAGES/django.po +12 -12
  365. wagtail/documents/locale/id_ID/LC_MESSAGES/django.po +6 -6
  366. wagtail/documents/locale/is_IS/LC_MESSAGES/django.po +8 -8
  367. wagtail/documents/locale/it/LC_MESSAGES/django.po +8 -8
  368. wagtail/documents/locale/ja/LC_MESSAGES/django.po +8 -8
  369. wagtail/documents/locale/ko/LC_MESSAGES/django.po +8 -8
  370. wagtail/documents/locale/lt/LC_MESSAGES/django.po +8 -8
  371. wagtail/documents/locale/mi/LC_MESSAGES/django.po +10 -10
  372. wagtail/documents/locale/mn/LC_MESSAGES/django.po +5 -4
  373. wagtail/documents/locale/nb/LC_MESSAGES/django.po +6 -6
  374. wagtail/documents/locale/nl/LC_MESSAGES/django.po +8 -8
  375. wagtail/documents/locale/pl/LC_MESSAGES/django.po +11 -11
  376. wagtail/documents/locale/pt_BR/LC_MESSAGES/django.po +8 -8
  377. wagtail/documents/locale/pt_PT/LC_MESSAGES/django.po +8 -8
  378. wagtail/documents/locale/ro/LC_MESSAGES/django.po +8 -8
  379. wagtail/documents/locale/ru/LC_MESSAGES/django.po +9 -9
  380. wagtail/documents/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  381. wagtail/documents/locale/sk_SK/LC_MESSAGES/django.po +55 -12
  382. wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
  383. wagtail/documents/locale/sl/LC_MESSAGES/django.po +30 -10
  384. wagtail/documents/locale/sr/LC_MESSAGES/django.po +2 -2
  385. wagtail/documents/locale/sv/LC_MESSAGES/django.po +6 -6
  386. wagtail/documents/locale/th/LC_MESSAGES/django.po +8 -8
  387. wagtail/documents/locale/tr/LC_MESSAGES/django.po +8 -8
  388. wagtail/documents/locale/tr_TR/LC_MESSAGES/django.po +8 -8
  389. wagtail/documents/locale/uk/LC_MESSAGES/django.po +8 -8
  390. wagtail/documents/locale/zh/LC_MESSAGES/django.po +2 -2
  391. wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  392. wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.po +11 -5
  393. wagtail/documents/locale/zh_Hant/LC_MESSAGES/django.po +4 -4
  394. wagtail/documents/models.py +5 -1
  395. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  396. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  397. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  398. wagtail/documents/tests/test_models.py +5 -1
  399. wagtail/embeds/apps.py +2 -0
  400. wagtail/embeds/embeds.py +12 -14
  401. wagtail/embeds/finders/__init__.py +2 -0
  402. wagtail/embeds/finders/facebook.py +17 -33
  403. wagtail/embeds/finders/instagram.py +19 -16
  404. wagtail/embeds/locale/be/LC_MESSAGES/django.po +3 -3
  405. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  406. wagtail/embeds/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  407. wagtail/embeds/locale/pl/LC_MESSAGES/django.po +3 -3
  408. wagtail/embeds/locale/ru/LC_MESSAGES/django.po +3 -3
  409. wagtail/embeds/locale/sl/LC_MESSAGES/django.po +2 -2
  410. wagtail/embeds/signal_handlers.py +13 -0
  411. wagtail/embeds/tests/test_embeds.py +7 -7
  412. wagtail/fields.py +58 -14
  413. wagtail/images/__init__.py +1 -1
  414. wagtail/images/locale/ar/LC_MESSAGES/django.po +6 -6
  415. wagtail/images/locale/be/LC_MESSAGES/django.po +3 -3
  416. wagtail/images/locale/ca/LC_MESSAGES/django.po +8 -8
  417. wagtail/images/locale/cs/LC_MESSAGES/django.po +8 -8
  418. wagtail/images/locale/cy/LC_MESSAGES/django.po +8 -8
  419. wagtail/images/locale/de/LC_MESSAGES/django.po +6 -6
  420. wagtail/images/locale/el/LC_MESSAGES/django.po +8 -8
  421. wagtail/images/locale/en/LC_MESSAGES/django.po +34 -34
  422. wagtail/images/locale/es/LC_MESSAGES/django.po +10 -10
  423. wagtail/images/locale/et/LC_MESSAGES/django.po +8 -8
  424. wagtail/images/locale/fa/LC_MESSAGES/django.mo +0 -0
  425. wagtail/images/locale/fa/LC_MESSAGES/django.po +28 -9
  426. wagtail/images/locale/fi/LC_MESSAGES/django.po +8 -8
  427. wagtail/images/locale/fr/LC_MESSAGES/django.po +6 -6
  428. wagtail/images/locale/gl/LC_MESSAGES/django.po +8 -8
  429. wagtail/images/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  430. wagtail/images/locale/hu/LC_MESSAGES/django.po +8 -8
  431. wagtail/images/locale/id_ID/LC_MESSAGES/django.po +6 -6
  432. wagtail/images/locale/is_IS/LC_MESSAGES/django.po +8 -8
  433. wagtail/images/locale/it/LC_MESSAGES/django.po +8 -8
  434. wagtail/images/locale/ja/LC_MESSAGES/django.po +8 -8
  435. wagtail/images/locale/ko/LC_MESSAGES/django.po +6 -6
  436. wagtail/images/locale/lt/LC_MESSAGES/django.po +8 -8
  437. wagtail/images/locale/nb/LC_MESSAGES/django.po +8 -8
  438. wagtail/images/locale/nl/LC_MESSAGES/django.po +8 -8
  439. wagtail/images/locale/pl/LC_MESSAGES/django.po +11 -11
  440. wagtail/images/locale/pt_BR/LC_MESSAGES/django.po +8 -8
  441. wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +8 -8
  442. wagtail/images/locale/ro/LC_MESSAGES/django.po +8 -8
  443. wagtail/images/locale/ru/LC_MESSAGES/django.po +11 -11
  444. wagtail/images/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  445. wagtail/images/locale/sk_SK/LC_MESSAGES/django.po +23 -8
  446. wagtail/images/locale/sl/LC_MESSAGES/django.mo +0 -0
  447. wagtail/images/locale/sl/LC_MESSAGES/django.po +44 -12
  448. wagtail/images/locale/sv/LC_MESSAGES/django.mo +0 -0
  449. wagtail/images/locale/sv/LC_MESSAGES/django.po +20 -8
  450. wagtail/images/locale/tet/LC_MESSAGES/django.po +4 -4
  451. wagtail/images/locale/th/LC_MESSAGES/django.po +8 -8
  452. wagtail/images/locale/tr/LC_MESSAGES/django.po +6 -6
  453. wagtail/images/locale/tr_TR/LC_MESSAGES/django.po +6 -6
  454. wagtail/images/locale/uk/LC_MESSAGES/django.po +8 -8
  455. wagtail/images/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  456. wagtail/images/locale/zh_Hans/LC_MESSAGES/django.po +49 -5
  457. wagtail/images/locale/zh_Hant/LC_MESSAGES/django.po +4 -4
  458. wagtail/images/models.py +3 -0
  459. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  460. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  461. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  462. wagtail/images/templates/wagtailimages/images/edit.html +4 -4
  463. wagtail/images/tests/test_admin_views.py +58 -2
  464. wagtail/images/tests/test_image_operations.py +12 -0
  465. wagtail/images/tests/tests.py +27 -2
  466. wagtail/images/views/chooser.py +6 -1
  467. wagtail/images/views/images.py +7 -3
  468. wagtail/images/views/serve.py +1 -0
  469. wagtail/locale/be/LC_MESSAGES/django.po +3 -3
  470. wagtail/locale/en/LC_MESSAGES/django.po +84 -80
  471. wagtail/locale/fa/LC_MESSAGES/django.mo +0 -0
  472. wagtail/locale/fa/LC_MESSAGES/django.po +3 -0
  473. wagtail/locale/fr/LC_MESSAGES/django.mo +0 -0
  474. wagtail/locale/fr/LC_MESSAGES/django.po +23 -4
  475. wagtail/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  476. wagtail/locale/pl/LC_MESSAGES/django.po +3 -3
  477. wagtail/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  478. wagtail/locale/ru/LC_MESSAGES/django.po +3 -3
  479. wagtail/locale/sl/LC_MESSAGES/django.po +2 -2
  480. wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
  481. wagtail/locale/sv/LC_MESSAGES/django.po +11 -2
  482. wagtail/locales/locale/be/LC_MESSAGES/django.po +3 -3
  483. wagtail/locales/locale/en/LC_MESSAGES/django.po +2 -2
  484. wagtail/locales/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  485. wagtail/locales/locale/pl/LC_MESSAGES/django.po +3 -3
  486. wagtail/locales/locale/ru/LC_MESSAGES/django.po +3 -3
  487. wagtail/locales/locale/sl/LC_MESSAGES/django.po +2 -2
  488. wagtail/locales/tests.py +16 -0
  489. wagtail/locales/wagtail_hooks.py +0 -9
  490. wagtail/migrations/0094_alter_page_locale.py +19 -0
  491. wagtail/models/__init__.py +11 -5
  492. wagtail/models/i18n.py +6 -1
  493. wagtail/project_template/requirements.txt +1 -1
  494. wagtail/search/locale/be/LC_MESSAGES/django.po +3 -3
  495. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  496. wagtail/search/locale/fa/LC_MESSAGES/django.mo +0 -0
  497. wagtail/search/locale/fa/LC_MESSAGES/django.po +24 -0
  498. wagtail/search/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  499. wagtail/search/locale/pl/LC_MESSAGES/django.po +3 -3
  500. wagtail/search/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  501. wagtail/search/locale/pt_BR/LC_MESSAGES/django.po +2 -2
  502. wagtail/search/locale/ru/LC_MESSAGES/django.po +3 -3
  503. wagtail/search/locale/sl/LC_MESSAGES/django.po +2 -2
  504. wagtail/search/tests/test_queries.py +24 -0
  505. wagtail/search/utils.py +6 -12
  506. wagtail/signals.py +4 -0
  507. wagtail/sites/locale/be/LC_MESSAGES/django.po +3 -3
  508. wagtail/sites/locale/en/LC_MESSAGES/django.po +2 -2
  509. wagtail/sites/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  510. wagtail/sites/locale/pl/LC_MESSAGES/django.po +3 -3
  511. wagtail/sites/locale/ru/LC_MESSAGES/django.po +3 -3
  512. wagtail/sites/locale/sl/LC_MESSAGES/django.po +2 -2
  513. wagtail/sites/locale/sr/LC_MESSAGES/django.po +2 -2
  514. wagtail/sites/tests.py +15 -0
  515. wagtail/sites/wagtail_hooks.py +0 -9
  516. wagtail/snippets/locale/be/LC_MESSAGES/django.po +3 -3
  517. wagtail/snippets/locale/ca/LC_MESSAGES/django.po +6 -6
  518. wagtail/snippets/locale/de/LC_MESSAGES/django.po +5 -5
  519. wagtail/snippets/locale/en/LC_MESSAGES/django.po +9 -9
  520. wagtail/snippets/locale/es/LC_MESSAGES/django.po +6 -6
  521. wagtail/snippets/locale/fa/LC_MESSAGES/django.mo +0 -0
  522. wagtail/snippets/locale/fa/LC_MESSAGES/django.po +17 -1
  523. wagtail/snippets/locale/fr/LC_MESSAGES/django.po +5 -5
  524. wagtail/snippets/locale/gl/LC_MESSAGES/django.po +6 -6
  525. wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  526. wagtail/snippets/locale/hu/LC_MESSAGES/django.po +7 -7
  527. wagtail/snippets/locale/is_IS/LC_MESSAGES/django.po +5 -5
  528. wagtail/snippets/locale/it/LC_MESSAGES/django.po +5 -5
  529. wagtail/snippets/locale/ko/LC_MESSAGES/django.po +6 -6
  530. wagtail/snippets/locale/nb/LC_MESSAGES/django.po +6 -6
  531. wagtail/snippets/locale/nl/LC_MESSAGES/django.po +8 -8
  532. wagtail/snippets/locale/pl/LC_MESSAGES/django.po +9 -9
  533. wagtail/snippets/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  534. wagtail/snippets/locale/ro/LC_MESSAGES/django.po +6 -6
  535. wagtail/snippets/locale/ru/LC_MESSAGES/django.po +8 -8
  536. wagtail/snippets/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  537. wagtail/snippets/locale/sk_SK/LC_MESSAGES/django.po +3 -0
  538. wagtail/snippets/locale/sl/LC_MESSAGES/django.po +8 -8
  539. wagtail/snippets/locale/sr/LC_MESSAGES/django.po +2 -2
  540. wagtail/snippets/locale/sv/LC_MESSAGES/django.po +6 -6
  541. wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  542. wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.po +40 -1
  543. wagtail/snippets/permissions.py +5 -3
  544. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  545. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  546. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -1
  547. wagtail/snippets/tests/test_snippets.py +78 -12
  548. wagtail/snippets/tests/test_viewset.py +22 -0
  549. wagtail/snippets/views/snippets.py +19 -14
  550. wagtail/snippets/wagtail_hooks.py +2 -10
  551. wagtail/templatetags/wagtailcore_tags.py +3 -0
  552. wagtail/test/dummy_external_storage.py +1 -1
  553. wagtail/test/i18n/migrations/0003_alter_clusterabletestmodel_locale_and_more.py +40 -0
  554. wagtail/test/routablepage/models.py +4 -0
  555. wagtail/test/snippets/migrations/0012_alter_translatablesnippet_locale.py +20 -0
  556. wagtail/test/testapp/migrations/0038_sociallink.py +52 -0
  557. wagtail/test/testapp/migrations/0039_alter_eventcategory_locale_and_more.py +45 -0
  558. wagtail/test/testapp/models.py +24 -0
  559. wagtail/test/testapp/views.py +1 -0
  560. wagtail/test/testapp/wagtail_hooks.py +9 -0
  561. wagtail/test/urls_multilang.py +6 -1
  562. wagtail/test/urls_multilang_non_root.py +11 -0
  563. wagtail/tests/streamfield_migrations/test_migrations.py +53 -12
  564. wagtail/tests/test_audit_log.py +72 -2
  565. wagtail/tests/test_blocks.py +103 -0
  566. wagtail/tests/test_signals.py +49 -2
  567. wagtail/tests/test_streamfield.py +153 -0
  568. wagtail/tests/test_utils.py +42 -1
  569. wagtail/tests/tests.py +5 -0
  570. wagtail/users/apps.py +1 -0
  571. wagtail/users/forms.py +7 -0
  572. wagtail/users/locale/ar/LC_MESSAGES/django.po +4 -4
  573. wagtail/users/locale/be/LC_MESSAGES/django.po +9 -9
  574. wagtail/users/locale/ca/LC_MESSAGES/django.po +8 -8
  575. wagtail/users/locale/cs/LC_MESSAGES/django.po +6 -6
  576. wagtail/users/locale/cy/LC_MESSAGES/django.po +8 -8
  577. wagtail/users/locale/de/LC_MESSAGES/django.po +8 -8
  578. wagtail/users/locale/el/LC_MESSAGES/django.po +4 -4
  579. wagtail/users/locale/en/LC_MESSAGES/django.po +55 -50
  580. wagtail/users/locale/es/LC_MESSAGES/django.po +8 -8
  581. wagtail/users/locale/et/LC_MESSAGES/django.po +8 -8
  582. wagtail/users/locale/fa/LC_MESSAGES/django.mo +0 -0
  583. wagtail/users/locale/fa/LC_MESSAGES/django.po +69 -7
  584. wagtail/users/locale/fi/LC_MESSAGES/django.po +8 -8
  585. wagtail/users/locale/fr/LC_MESSAGES/django.mo +0 -0
  586. wagtail/users/locale/fr/LC_MESSAGES/django.po +52 -11
  587. wagtail/users/locale/gl/LC_MESSAGES/django.po +8 -8
  588. wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +10 -10
  589. wagtail/users/locale/hu/LC_MESSAGES/django.po +8 -8
  590. wagtail/users/locale/id_ID/LC_MESSAGES/django.po +4 -4
  591. wagtail/users/locale/is_IS/LC_MESSAGES/django.po +8 -8
  592. wagtail/users/locale/it/LC_MESSAGES/django.po +8 -8
  593. wagtail/users/locale/ja/LC_MESSAGES/django.po +4 -4
  594. wagtail/users/locale/ko/LC_MESSAGES/django.po +4 -4
  595. wagtail/users/locale/lt/LC_MESSAGES/django.po +4 -4
  596. wagtail/users/locale/lv/LC_MESSAGES/django.po +4 -4
  597. wagtail/users/locale/mn/LC_MESSAGES/django.po +5 -4
  598. wagtail/users/locale/nb/LC_MESSAGES/django.po +8 -8
  599. wagtail/users/locale/nl/LC_MESSAGES/django.po +6 -6
  600. wagtail/users/locale/pl/LC_MESSAGES/django.po +9 -9
  601. wagtail/users/locale/pt_BR/LC_MESSAGES/django.po +9 -9
  602. wagtail/users/locale/pt_PT/LC_MESSAGES/django.po +8 -8
  603. wagtail/users/locale/ro/LC_MESSAGES/django.po +8 -8
  604. wagtail/users/locale/ru/LC_MESSAGES/django.po +11 -11
  605. wagtail/users/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  606. wagtail/users/locale/sk_SK/LC_MESSAGES/django.po +12 -5
  607. wagtail/users/locale/sl/LC_MESSAGES/django.mo +0 -0
  608. wagtail/users/locale/sl/LC_MESSAGES/django.po +56 -12
  609. wagtail/users/locale/sv/LC_MESSAGES/django.mo +0 -0
  610. wagtail/users/locale/sv/LC_MESSAGES/django.po +49 -10
  611. wagtail/users/locale/tet/LC_MESSAGES/django.po +4 -4
  612. wagtail/users/locale/th/LC_MESSAGES/django.po +4 -4
  613. wagtail/users/locale/tr/LC_MESSAGES/django.po +4 -4
  614. wagtail/users/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  615. wagtail/users/locale/uk/LC_MESSAGES/django.po +8 -8
  616. wagtail/users/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  617. wagtail/users/locale/zh_Hans/LC_MESSAGES/django.po +49 -5
  618. wagtail/users/locale/zh_Hant/LC_MESSAGES/django.po +2 -2
  619. wagtail/users/models.py +1 -0
  620. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +3 -2
  621. wagtail/users/templatetags/wagtailusers_tags.py +9 -0
  622. wagtail/users/tests/__init__.py +7 -1
  623. wagtail/users/tests/test_admin_views.py +117 -32
  624. wagtail/users/views/groups.py +4 -0
  625. wagtail/users/views/users.py +58 -14
  626. wagtail/users/wagtail_hooks.py +7 -123
  627. wagtail/utils/utils.py +27 -0
  628. wagtail/utils/version.py +5 -2
  629. wagtail-6.2rc1.dist-info/METADATA +78 -0
  630. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/RECORD +634 -607
  631. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/WHEEL +1 -1
  632. wagtail/admin/templates/wagtailadmin/reports/aging_pages.html +0 -58
  633. wagtail/admin/templates/wagtailadmin/reports/page_types_usage.html +0 -18
  634. wagtail/admin/templates/wagtailadmin/reports/site_history.html +0 -57
  635. wagtail/admin/templates/wagtailadmin/reports/workflow.html +0 -81
  636. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks.html +0 -63
  637. wagtail/contrib/frontend_cache/backends.py +0 -400
  638. wagtail/contrib/redirects/templates/wagtailredirects/list.html +0 -43
  639. wagtail/contrib/redirects/templates/wagtailredirects/reports/redirects_report.html +0 -14
  640. wagtail/contrib/redirects/tests/test_reports_view.py +0 -82
  641. wagtail-6.1.2.dist-info/METADATA +0 -78
  642. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/LICENSE +0 -0
  643. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/entry_points.txt +0 -0
  644. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/top_level.txt +0 -0
@@ -217,8 +217,12 @@ class TestDocumentValidateExtensions(TestCase):
217
217
  creation when called full_clean. This specific testcase invalid
218
218
  file extension is passed
219
219
  """
220
- with self.assertRaises(ValidationError):
220
+ with self.assertRaises(ValidationError) as e:
221
221
  self.document_invalid.full_clean()
222
+ expected_message = (
223
+ "File extension “doc” is not allowed. Allowed extensions are: pdf."
224
+ )
225
+ self.assertEqual(e.exception.message_dict["file"][0], expected_message)
222
226
 
223
227
  def test_create_doc_valid_extension(self):
224
228
  """
wagtail/embeds/apps.py CHANGED
@@ -11,5 +11,7 @@ class WagtailEmbedsAppConfig(AppConfig):
11
11
  default_auto_field = "django.db.models.AutoField"
12
12
 
13
13
  def ready(self):
14
+ from . import signal_handlers # noqa
15
+
14
16
  # Check configuration on startup
15
17
  get_finders()
wagtail/embeds/embeds.py CHANGED
@@ -9,7 +9,18 @@ from .finders import get_finders
9
9
  from .models import Embed
10
10
 
11
11
 
12
- def get_embed(url, max_width=None, max_height=None, finder=None):
12
+ def get_finder_for_embed(url, max_width=None, max_height=None):
13
+ for finder in get_finders():
14
+ if finder.accept(url):
15
+ kwargs = {}
16
+ if accepts_kwarg(finder.find_embed, "max_height"):
17
+ kwargs["max_height"] = max_height
18
+ return finder.find_embed(url, max_width=max_width, **kwargs)
19
+
20
+ raise EmbedUnsupportedProviderException
21
+
22
+
23
+ def get_embed(url, max_width=None, max_height=None, finder=get_finder_for_embed):
13
24
  embed_hash = get_embed_hash(url, max_width, max_height)
14
25
 
15
26
  # Check database
@@ -18,19 +29,6 @@ def get_embed(url, max_width=None, max_height=None, finder=None):
18
29
  except Embed.DoesNotExist:
19
30
  pass
20
31
 
21
- # Get/Call finder
22
- if not finder:
23
-
24
- def finder(url, max_width=None, max_height=None):
25
- for finder in get_finders():
26
- if finder.accept(url):
27
- kwargs = {}
28
- if accepts_kwarg(finder.find_embed, "max_height"):
29
- kwargs["max_height"] = max_height
30
- return finder.find_embed(url, max_width=max_width, **kwargs)
31
-
32
- raise EmbedUnsupportedProviderException
33
-
34
32
  embed_dict = finder(url, max_width, max_height)
35
33
 
36
34
  # Make sure width and height are valid integers before inserting into database
@@ -1,3 +1,4 @@
1
+ from functools import lru_cache
1
2
  from importlib import import_module
2
3
 
3
4
  from django.conf import settings
@@ -34,6 +35,7 @@ def _get_config_from_settings():
34
35
  ]
35
36
 
36
37
 
38
+ @lru_cache(maxsize=None)
37
39
  def get_finders():
38
40
  finders = []
39
41
 
@@ -1,5 +1,4 @@
1
1
  import json
2
- import re
3
2
  from urllib import request as urllib_request
4
3
  from urllib.error import HTTPError, URLError
5
4
  from urllib.parse import urlencode
@@ -7,29 +6,25 @@ from urllib.request import Request
7
6
 
8
7
  from wagtail.embeds.exceptions import EmbedException, EmbedNotFoundException
9
8
 
10
- from .base import EmbedFinder
9
+ from .oembed import OEmbedFinder
11
10
 
12
11
 
13
12
  class AccessDeniedFacebookOEmbedException(EmbedException):
14
13
  pass
15
14
 
16
15
 
17
- class FacebookOEmbedFinder(EmbedFinder):
18
- """
19
- An embed finder that supports the authenticated Facebook oEmbed Endpoint.
20
- https://developers.facebook.com/docs/plugins/oembed
21
- """
22
-
23
- facebook_video = {
16
+ FACEBOOK_PROVIDERS = [
17
+ # Videos
18
+ {
24
19
  "endpoint": "https://graph.facebook.com/v11.0/oembed_video",
25
20
  "urls": [
26
21
  r"^https://(?:www\.)?facebook\.com/.+?/videos/.+$",
27
22
  r"^https://(?:www\.)?facebook\.com/video\.php\?(?:v|id)=.+$",
28
23
  r"^https://fb.watch/.+$",
29
24
  ],
30
- }
31
-
32
- facebook_post = {
25
+ },
26
+ # Posts
27
+ {
33
28
  "endpoint": "https://graph.facebook.com/v11.0/oembed_post",
34
29
  "urls": [
35
30
  r"^https://(?:www\.)?facebook\.com/.+?/(?:posts|activity)/.+$",
@@ -42,7 +37,15 @@ class FacebookOEmbedFinder(EmbedFinder):
42
37
  # Works for posts with a single photo
43
38
  r"^https://(?:www\.)?facebook\.com/.+?/photos/.+$",
44
39
  ],
45
- }
40
+ },
41
+ ]
42
+
43
+
44
+ class FacebookOEmbedFinder(OEmbedFinder):
45
+ """
46
+ An embed finder that supports the authenticated Facebook oEmbed Endpoint.
47
+ https://developers.facebook.com/docs/plugins/oembed
48
+ """
46
49
 
47
50
  def __init__(self, omitscript=False, app_id=None, app_secret=None):
48
51
  # {settings.facebook_APP_ID}|{settings.facebook_APP_SECRET}
@@ -50,26 +53,7 @@ class FacebookOEmbedFinder(EmbedFinder):
50
53
  self.app_secret = app_secret
51
54
  self.omitscript = omitscript
52
55
 
53
- self._endpoints = {}
54
-
55
- for provider in [self.facebook_video, self.facebook_post]:
56
- patterns = []
57
-
58
- endpoint = provider["endpoint"].replace("{format}", "json")
59
-
60
- for url in provider["urls"]:
61
- patterns.append(re.compile(url))
62
-
63
- self._endpoints[endpoint] = patterns
64
-
65
- def _get_endpoint(self, url):
66
- for endpoint, patterns in self._endpoints.items():
67
- for pattern in patterns:
68
- if re.match(pattern, url):
69
- return endpoint
70
-
71
- def accept(self, url):
72
- return self._get_endpoint(url) is not None
56
+ super().__init__(providers=FACEBOOK_PROVIDERS)
73
57
 
74
58
  def find_embed(self, url, max_width=None, max_height=None):
75
59
  # Find provider
@@ -1,5 +1,4 @@
1
1
  import json
2
- import re
3
2
  from urllib import request as urllib_request
4
3
  from urllib.error import HTTPError, URLError
5
4
  from urllib.parse import urlencode
@@ -7,39 +6,43 @@ from urllib.request import Request
7
6
 
8
7
  from wagtail.embeds.exceptions import EmbedException, EmbedNotFoundException
9
8
 
10
- from .base import EmbedFinder
9
+ from .oembed import OEmbedFinder
11
10
 
12
11
 
13
12
  class AccessDeniedInstagramOEmbedException(EmbedException):
14
13
  pass
15
14
 
16
15
 
17
- class InstagramOEmbedFinder(EmbedFinder):
16
+ INSTAGRAM_PROVIDER = {
17
+ "endpoint": "https://graph.facebook.com/v11.0/instagram_oembed",
18
+ "urls": [
19
+ r"^https?://(?:www\.)?instagram\.com/p/.+$",
20
+ r"^https?://(?:www\.)?instagram\.com/tv/.+$",
21
+ r"^https?://(?:www\.)?instagram\.com/reel/.+$",
22
+ ],
23
+ }
24
+
25
+
26
+ class InstagramOEmbedFinder(OEmbedFinder):
18
27
  """
19
28
  An embed finder that supports the authenticated Instagram oEmbed Endpoint.
20
29
  https://developers.facebook.com/docs/instagram/oembed
21
30
  """
22
31
 
23
- INSTAGRAM_ENDPOINT = "https://graph.facebook.com/v11.0/instagram_oembed"
24
- INSTAGRAM_URL_PATTERNS = [
25
- r"^https?://(?:www\.)?instagram\.com/p/.+$",
26
- r"^https?://(?:www\.)?instagram\.com/tv/.+$",
27
- r"^https?://(?:www\.)?instagram\.com/reel/.+$",
28
- ]
29
-
30
32
  def __init__(self, omitscript=False, app_id=None, app_secret=None):
31
33
  # {settings.INSTAGRAM_APP_ID}|{settings.INSTAGRAM_APP_SECRET}
32
34
  self.app_id = app_id
33
35
  self.app_secret = app_secret
34
36
  self.omitscript = omitscript
35
37
 
36
- def accept(self, url):
37
- for pattern in self.INSTAGRAM_URL_PATTERNS:
38
- if re.match(pattern, url):
39
- return True
40
- return False
38
+ super().__init__(providers=[INSTAGRAM_PROVIDER])
41
39
 
42
40
  def find_embed(self, url, max_width=None, max_height=None):
41
+ # Find provider
42
+ endpoint = self._get_endpoint(url)
43
+ if endpoint is None:
44
+ raise EmbedNotFoundException
45
+
43
46
  params = {"url": url, "format": "json"}
44
47
  if max_width:
45
48
  params["maxwidth"] = max_width
@@ -49,7 +52,7 @@ class InstagramOEmbedFinder(EmbedFinder):
49
52
  params["omitscript"] = "true"
50
53
 
51
54
  # Configure request
52
- request = Request(self.INSTAGRAM_ENDPOINT + "?" + urlencode(params))
55
+ request = Request(endpoint + "?" + urlencode(params))
53
56
  request.add_header("Authorization", f"Bearer {self.app_id}|{self.app_secret}")
54
57
 
55
58
  # Perform request
@@ -17,9 +17,9 @@ msgstr ""
17
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
18
  "Content-Transfer-Encoding: 8bit\n"
19
19
  "Language: be\n"
20
- "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
21
- "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
22
- "%100>=11 && n%100<=14)? 2 : 3);\n"
20
+ "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
21
+ "n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
22
+ "(n%100>=11 && n%100<=14)? 2 : 3);\n"
23
23
 
24
24
  msgid "Wagtail embeds"
25
25
  msgstr "Ўбудоўваемы код Wagtail"
@@ -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-04-18 17:28+0100\n"
11
+ "POT-Creation-Date: 2024-07-19 16:26+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"
@@ -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: hr_HR\n"
20
- "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
21
- "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
20
+ "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
21
+ "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
22
22
 
23
23
  msgid "Wagtail embeds"
24
24
  msgstr "Wagtail umetci"
@@ -22,9 +22,9 @@ msgstr ""
22
22
  "Content-Type: text/plain; charset=UTF-8\n"
23
23
  "Content-Transfer-Encoding: 8bit\n"
24
24
  "Language: pl\n"
25
- "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n"
26
- "%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n"
27
- "%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
25
+ "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && "
26
+ "(n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && "
27
+ "n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
28
28
 
29
29
  msgid "Wagtail embeds"
30
30
  msgstr "Embedy Wagtail"
@@ -24,9 +24,9 @@ msgstr ""
24
24
  "Content-Type: text/plain; charset=UTF-8\n"
25
25
  "Content-Transfer-Encoding: 8bit\n"
26
26
  "Language: ru\n"
27
- "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
28
- "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
29
- "%100>=11 && n%100<=14)? 2 : 3);\n"
27
+ "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
28
+ "n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
29
+ "(n%100>=11 && n%100<=14)? 2 : 3);\n"
30
30
 
31
31
  msgid "Wagtail embeds"
32
32
  msgstr "Встраиваемый код Wagtail"
@@ -19,8 +19,8 @@ msgstr ""
19
19
  "Content-Type: text/plain; charset=UTF-8\n"
20
20
  "Content-Transfer-Encoding: 8bit\n"
21
21
  "Language: sl\n"
22
- "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
23
- "%100==4 ? 2 : 3);\n"
22
+ "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
23
+ "n%100==4 ? 2 : 3);\n"
24
24
 
25
25
  msgid "Wagtail embeds"
26
26
  msgstr "Wagtail vdelano"
@@ -0,0 +1,13 @@
1
+ from django.core.signals import setting_changed
2
+ from django.dispatch import receiver
3
+
4
+ from .finders import get_finders
5
+
6
+
7
+ @receiver(setting_changed)
8
+ def clear_embed_caches(*, setting: str, **kwargs: dict) -> None:
9
+ """
10
+ Clear the embed caches when settings change
11
+ """
12
+ if setting == "WAGTAILEMBEDS_FINDERS":
13
+ get_finders.cache_clear()
@@ -652,7 +652,7 @@ class TestInstagramOEmbed(TestCase):
652
652
  def test_instagram_oembed_return_values(self, urlopen):
653
653
  urlopen.return_value = self.dummy_response
654
654
  result = InstagramOEmbedFinder(app_id="123", app_secret="abc").find_embed(
655
- "https://instagr.am/p/CHeRxmnDSYe/"
655
+ "https://instagram.com/p/CHeRxmnDSYe/"
656
656
  )
657
657
  self.assertEqual(
658
658
  result,
@@ -671,13 +671,13 @@ class TestInstagramOEmbed(TestCase):
671
671
  request = urlopen.call_args[0][0]
672
672
  self.assertEqual(
673
673
  request.get_full_url(),
674
- "https://graph.facebook.com/v11.0/instagram_oembed?url=https%3A%2F%2Finstagr.am%2Fp%2FCHeRxmnDSYe%2F&format=json",
674
+ "https://graph.facebook.com/v11.0/instagram_oembed?url=https%3A%2F%2Finstagram.com%2Fp%2FCHeRxmnDSYe%2F&format=json",
675
675
  )
676
676
  self.assertEqual(request.get_header("Authorization"), "Bearer 123|abc")
677
677
 
678
678
  def test_instagram_request_denied_401(self):
679
679
  err = HTTPError(
680
- "https://instagr.am/p/CHeRxmnDSYe/",
680
+ "https://instagram.com/p/CHeRxmnDSYe/",
681
681
  code=401,
682
682
  msg="invalid credentials",
683
683
  hdrs={},
@@ -688,12 +688,12 @@ class TestInstagramOEmbed(TestCase):
688
688
  self.assertRaises(
689
689
  AccessDeniedInstagramOEmbedException,
690
690
  InstagramOEmbedFinder().find_embed,
691
- "https://instagr.am/p/CHeRxmnDSYe/",
691
+ "https://instagram.com/p/CHeRxmnDSYe/",
692
692
  )
693
693
 
694
694
  def test_instagram_request_not_found(self):
695
695
  err = HTTPError(
696
- "https://instagr.am/p/badrequest/",
696
+ "https://instagram.com/p/badrequest/",
697
697
  code=404,
698
698
  msg="Not Found",
699
699
  hdrs={},
@@ -704,7 +704,7 @@ class TestInstagramOEmbed(TestCase):
704
704
  self.assertRaises(
705
705
  EmbedNotFoundException,
706
706
  InstagramOEmbedFinder().find_embed,
707
- "https://instagr.am/p/CHeRxmnDSYe/",
707
+ "https://instagram.com/p/CHeRxmnDSYe/",
708
708
  )
709
709
 
710
710
  def test_instagram_failed_request(self):
@@ -713,7 +713,7 @@ class TestInstagramOEmbed(TestCase):
713
713
  self.assertRaises(
714
714
  EmbedNotFoundException,
715
715
  InstagramOEmbedFinder().find_embed,
716
- "https://instagr.am/p/CHeRxmnDSYe/",
716
+ "https://instagram.com/p/CHeRxmnDSYe/",
717
717
  )
718
718
 
719
719
 
wagtail/fields.py CHANGED
@@ -5,8 +5,13 @@ from django.core.validators import MaxLengthValidator
5
5
  from django.db import models
6
6
  from django.db.models.fields.json import KeyTransform
7
7
  from django.utils.encoding import force_str
8
+ from django.utils.functional import cached_property
8
9
 
9
10
  from wagtail.blocks import Block, BlockField, StreamBlock, StreamValue
11
+ from wagtail.blocks.definition_lookup import (
12
+ BlockDefinitionLookup,
13
+ BlockDefinitionLookupBuilder,
14
+ )
10
15
  from wagtail.rich_text import (
11
16
  RichTextMaxLengthValidator,
12
17
  extract_references_from_rich_text,
@@ -82,34 +87,68 @@ class Creator:
82
87
 
83
88
 
84
89
  class StreamField(models.Field):
85
- def __init__(self, block_types, use_json_field=True, **kwargs):
86
- # use_json_field no longer has any effect but is recognised to support historical
87
- # migrations
90
+ def __init__(self, block_types, use_json_field=True, block_lookup=None, **kwargs):
91
+ """
92
+ Construct a StreamField.
93
+
94
+ :param block_types: Either a list of block types that are allowed in this StreamField
95
+ (as a list of tuples of block name and block instance) or a StreamBlock to use as
96
+ the top level block (as a block instance or class).
97
+ :param use_json_field: Ignored, but retained for compatibility with historical migrations.
98
+ :param block_lookup: Used in migrations to provide a more compact block definition -
99
+ see ``wagtail.blocks.definition_lookup.BlockDefinitionLookup``. If passed, ``block_types``
100
+ can contain integer indexes into this lookup table, in place of actual block instances.
101
+ """
88
102
 
89
103
  # extract kwargs that are to be passed on to the block, not handled by super
90
- block_opts = {}
104
+ self.block_opts = {}
91
105
  for arg in ["min_num", "max_num", "block_counts", "collapsed"]:
92
106
  if arg in kwargs:
93
- block_opts[arg] = kwargs.pop(arg)
107
+ self.block_opts[arg] = kwargs.pop(arg)
94
108
 
95
109
  # for a top-level block, the 'blank' kwarg (defaulting to False) always overrides the
96
110
  # block's own 'required' meta attribute, even if not passed explicitly; this ensures
97
111
  # that the field and block have consistent definitions
98
- block_opts["required"] = not kwargs.get("blank", False)
112
+ self.block_opts["required"] = not kwargs.get("blank", False)
113
+
114
+ # Store the `block_types` and `block_lookup` arguments to be handled in the `stream_block`
115
+ # property
116
+ self.block_types_arg = block_types
117
+ self.block_lookup = block_lookup
99
118
 
100
119
  super().__init__(**kwargs)
101
120
 
102
- if isinstance(block_types, Block):
121
+ @cached_property
122
+ def stream_block(self):
123
+ has_block_lookup = self.block_lookup is not None
124
+ if has_block_lookup:
125
+ lookup = BlockDefinitionLookup(self.block_lookup)
126
+
127
+ if isinstance(self.block_types_arg, Block):
103
128
  # use the passed block as the top-level block
104
- self.stream_block = block_types
105
- elif isinstance(block_types, type):
129
+ block = self.block_types_arg
130
+ elif isinstance(self.block_types_arg, int) and has_block_lookup:
131
+ # retrieve block from lookup table to use as the top-level block
132
+ block = lookup.get_block(self.block_types_arg)
133
+ elif isinstance(self.block_types_arg, type):
106
134
  # block passed as a class - instantiate it
107
- self.stream_block = block_types()
135
+ block = self.block_types_arg()
108
136
  else:
109
- # construct a top-level StreamBlock from the list of block types
110
- self.stream_block = StreamBlock(block_types)
137
+ # construct a top-level StreamBlock from the list of block types.
138
+ # If an integer is found in place of a block instance, and block_lookup is
139
+ # provided, it will be replaced with the corresponding block definition.
140
+ child_blocks = []
141
+
142
+ for name, child_block in self.block_types_arg:
143
+ if isinstance(child_block, int) and has_block_lookup:
144
+ child_blocks.append((name, lookup.get_block(child_block)))
145
+ else:
146
+ child_blocks.append((name, child_block))
147
+
148
+ block = StreamBlock(child_blocks)
111
149
 
112
- self.stream_block.set_meta_options(block_opts)
150
+ block.set_meta_options(self.block_opts)
151
+ return block
113
152
 
114
153
  @property
115
154
  def json_field(self):
@@ -126,8 +165,13 @@ class StreamField(models.Field):
126
165
 
127
166
  def deconstruct(self):
128
167
  name, path, _, kwargs = super().deconstruct()
129
- block_types = list(self.stream_block.child_blocks.items())
168
+ lookup = BlockDefinitionLookupBuilder()
169
+ block_types = [
170
+ (name, lookup.add_block(block))
171
+ for name, block in self.stream_block.child_blocks.items()
172
+ ]
130
173
  args = [block_types]
174
+ kwargs["block_lookup"] = lookup.get_lookup_as_dict()
131
175
  return name, path, args, kwargs
132
176
 
133
177
  def to_python(self, value):
@@ -15,7 +15,7 @@ def get_image_model():
15
15
  """
16
16
  Get the image model from the ``WAGTAILIMAGES_IMAGE_MODEL`` setting.
17
17
  Useful for developers making Wagtail plugins that need the image model.
18
- Defaults to the standard :class:`~wagtail.images.models.Image` model
18
+ Defaults to the standard ``wagtail.images.models.Image`` model
19
19
  if no custom model is defined.
20
20
  """
21
21
  from django.apps import apps
@@ -232,16 +232,16 @@ msgstr "عذرًا ، لا توجد صور تطابق \"<em>%(query_string)s</em
232
232
 
233
233
  #, python-format
234
234
  msgid ""
235
- "You haven't uploaded any images in this collection. Why not <a href="
236
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
235
+ "You haven't uploaded any images in this collection. Why not <a "
236
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
237
237
  msgstr ""
238
- "لم تحمِّل أي صور في هذه المجموعة. لماذا لا <a href="
239
- "\"%(wagtailimages_add_image_url)s\">تحمل واحد الآن</a>؟"
238
+ "لم تحمِّل أي صور في هذه المجموعة. لماذا لا <a "
239
+ "href=\"%(wagtailimages_add_image_url)s\">تحمل واحد الآن</a>؟"
240
240
 
241
241
  #, python-format
242
242
  msgid ""
243
- "You haven't uploaded any images. Why not <a href="
244
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
243
+ "You haven't uploaded any images. Why not <a "
244
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
245
245
  msgstr ""
246
246
  "لم تحمِّل أي صور. لماذا لا <a href=\"%(wagtailimages_add_image_url)s\">تحمل "
247
247
  "واحد الآن</a>؟"
@@ -17,9 +17,9 @@ msgstr ""
17
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
18
  "Content-Transfer-Encoding: 8bit\n"
19
19
  "Language: be\n"
20
- "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
21
- "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
22
- "%100>=11 && n%100<=14)? 2 : 3);\n"
20
+ "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
21
+ "n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
22
+ "(n%100>=11 && n%100<=14)? 2 : 3);\n"
23
23
 
24
24
  msgid "Wagtail images"
25
25
  msgstr "Малявання Wagtail "
@@ -387,19 +387,19 @@ msgstr "Ho sentim, cap imatge coincideix amb \"<em>%(query_string)s</em>\""
387
387
 
388
388
  #, python-format
389
389
  msgid ""
390
- "You haven't uploaded any images in this collection. Why not <a href="
391
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
390
+ "You haven't uploaded any images in this collection. Why not <a "
391
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
392
392
  msgstr ""
393
- "No heu pujat cap imatge a aquesta col·lecció. Per què no en <a href="
394
- "\"%(wagtailimages_add_image_url)s\">pugeu una ara</a>?"
393
+ "No heu pujat cap imatge a aquesta col·lecció. Per què no en <a "
394
+ "href=\"%(wagtailimages_add_image_url)s\">pugeu una ara</a>?"
395
395
 
396
396
  #, python-format
397
397
  msgid ""
398
- "You haven't uploaded any images. Why not <a href="
399
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
398
+ "You haven't uploaded any images. Why not <a "
399
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
400
400
  msgstr ""
401
- "No heu pujat cap imatge. Per què no en <a href="
402
- "\"%(wagtailimages_add_image_url)s\">pugeu una ara</a>?"
401
+ "No heu pujat cap imatge. Per què no en <a "
402
+ "href=\"%(wagtailimages_add_image_url)s\">pugeu una ara</a>?"
403
403
 
404
404
  msgid "Preview"
405
405
  msgstr "Previsualització"
@@ -314,19 +314,19 @@ msgstr ""
314
314
 
315
315
  #, python-format
316
316
  msgid ""
317
- "You haven't uploaded any images in this collection. Why not <a href="
318
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
317
+ "You haven't uploaded any images in this collection. Why not <a "
318
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
319
319
  msgstr ""
320
- "V kolekci nebyly nalezeny žádné obrázky. Nový obrázek můžete přidat <a href="
321
- "\"%(wagtailimages_add_image_url)s\">zde</a>."
320
+ "V kolekci nebyly nalezeny žádné obrázky. Nový obrázek můžete přidat <a "
321
+ "href=\"%(wagtailimages_add_image_url)s\">zde</a>."
322
322
 
323
323
  #, python-format
324
324
  msgid ""
325
- "You haven't uploaded any images. Why not <a href="
326
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
325
+ "You haven't uploaded any images. Why not <a "
326
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
327
327
  msgstr ""
328
- "Nebyly nalezeny žádné obrázky. Nový obrázek můžete přidat <a href="
329
- "\"%(wagtailimages_add_image_url)s\">zde</a>."
328
+ "Nebyly nalezeny žádné obrázky. Nový obrázek můžete přidat <a "
329
+ "href=\"%(wagtailimages_add_image_url)s\">zde</a>."
330
330
 
331
331
  msgid "Preview"
332
332
  msgstr "Náhled"
@@ -332,19 +332,19 @@ msgstr ""
332
332
 
333
333
  #, python-format
334
334
  msgid ""
335
- "You haven't uploaded any images in this collection. Why not <a href="
336
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
335
+ "You haven't uploaded any images in this collection. Why not <a "
336
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
337
337
  msgstr ""
338
- "Nid ydych wedi uwchlwytho unrhyw lluniau yn y casgliad hwn. Pam ddim <a href="
339
- "\"%(wagtailimages_add_image_url)s\">uwchlwytho un rwan</a>?"
338
+ "Nid ydych wedi uwchlwytho unrhyw lluniau yn y casgliad hwn. Pam ddim <a "
339
+ "href=\"%(wagtailimages_add_image_url)s\">uwchlwytho un rwan</a>?"
340
340
 
341
341
  #, python-format
342
342
  msgid ""
343
- "You haven't uploaded any images. Why not <a href="
344
- "\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
343
+ "You haven't uploaded any images. Why not <a "
344
+ "href=\"%(wagtailimages_add_image_url)s\">upload one now</a>?"
345
345
  msgstr ""
346
- "Nid ydych wedi uwchlwytho unrhyw luniau. Pam ddim <a href="
347
- "\"%(wagtailimages_add_image_url)s\">uwchlwytho un rwan</a>?"
346
+ "Nid ydych wedi uwchlwytho unrhyw luniau. Pam ddim <a "
347
+ "href=\"%(wagtailimages_add_image_url)s\">uwchlwytho un rwan</a>?"
348
348
 
349
349
  msgid "Preview"
350
350
  msgstr "Rhagolwg"