wagtail 7.2.1__py3-none-any.whl → 7.3rc1__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 (312) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_for_translation.py +4 -2
  3. wagtail/admin/action_menu.py +4 -1
  4. wagtail/admin/api/actions/convert_alias.py +2 -2
  5. wagtail/admin/api/actions/copy.py +2 -2
  6. wagtail/admin/api/actions/copy_for_translation.py +2 -2
  7. wagtail/admin/api/actions/create_alias.py +2 -2
  8. wagtail/admin/api/actions/delete.py +1 -1
  9. wagtail/admin/api/actions/move.py +1 -1
  10. wagtail/admin/api/actions/publish.py +2 -2
  11. wagtail/admin/api/actions/revert_to_page_revision.py +2 -2
  12. wagtail/admin/api/actions/unpublish.py +1 -1
  13. wagtail/admin/api/filters.py +2 -2
  14. wagtail/admin/compare.py +22 -0
  15. wagtail/admin/forms/account.py +52 -1
  16. wagtail/admin/forms/comments.py +53 -0
  17. wagtail/admin/forms/models.py +36 -0
  18. wagtail/admin/forms/pages.py +7 -0
  19. wagtail/admin/forms/workflows.py +5 -2
  20. wagtail/admin/icons.py +4 -3
  21. wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
  22. wagtail/admin/locale/ar/LC_MESSAGES/django.po +35 -0
  23. wagtail/admin/locale/en/LC_MESSAGES/django.po +262 -234
  24. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +72 -43
  25. wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
  26. wagtail/admin/locale/it/LC_MESSAGES/django.po +566 -6
  27. wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
  28. wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +40 -2
  29. wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
  30. wagtail/admin/locale/nl/LC_MESSAGES/django.po +2 -2
  31. wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
  32. wagtail/admin/locale/sv/LC_MESSAGES/django.po +330 -15
  33. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.mo +0 -0
  34. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.po +3 -2
  35. wagtail/admin/panels/comment_panel.py +1 -51
  36. wagtail/admin/panels/title_field_panel.py +3 -1
  37. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  38. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  39. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  40. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  41. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -1
  42. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  43. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  44. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  45. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  46. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  47. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
  48. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  49. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  50. wagtail/admin/templates/wagtailadmin/base.html +1 -1
  51. wagtail/admin/templates/wagtailadmin/generic/edit_partials.html +100 -0
  52. wagtail/admin/templates/wagtailadmin/generic/form.html +26 -5
  53. wagtail/admin/templates/wagtailadmin/generic/includes/_loaded_revision_inputs.html +3 -0
  54. wagtail/admin/templates/wagtailadmin/generic/listing_results.html +1 -17
  55. wagtail/admin/templates/wagtailadmin/pages/create.html +14 -4
  56. wagtail/admin/templates/wagtailadmin/pages/edit.html +16 -3
  57. wagtail/admin/templates/wagtailadmin/pages/edit_partials.html +31 -0
  58. wagtail/admin/templates/wagtailadmin/pages/index_results.html +1 -9
  59. wagtail/admin/templates/wagtailadmin/shared/autosave/indicator.html +36 -0
  60. wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +1 -1
  61. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +2 -2
  62. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +19 -3
  63. wagtail/admin/templates/wagtailadmin/shared/headers/_actions.html +5 -0
  64. wagtail/admin/templates/wagtailadmin/shared/headers/_history_icon_link.html +2 -2
  65. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +8 -9
  66. wagtail/admin/templates/wagtailadmin/shared/listing/filter_partials.html +19 -0
  67. wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +3 -3
  68. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/side_panel.html +3 -0
  69. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +18 -6
  70. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/usage.html +11 -4
  71. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/workflow.html +22 -1
  72. wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +1 -0
  73. wagtail/admin/templates/wagtailadmin/shared/side_panels.html +1 -2
  74. wagtail/admin/templates/wagtailadmin/shared/unsaved_changes_warning.html +20 -20
  75. wagtail/admin/templates/wagtailadmin/userbar/base.html +2 -0
  76. wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +1 -1
  77. wagtail/admin/templatetags/wagtailadmin_tags.py +6 -14
  78. wagtail/admin/tests/pages/test_create_page.py +298 -1
  79. wagtail/admin/tests/pages/test_custom_listing.py +48 -2
  80. wagtail/admin/tests/pages/test_edit_page.py +721 -7
  81. wagtail/admin/tests/pages/test_explorer_view.py +9 -5
  82. wagtail/admin/tests/pages/test_page_search.py +15 -0
  83. wagtail/admin/tests/pages/test_revisions.py +4 -0
  84. wagtail/admin/tests/test_account_management.py +88 -2
  85. wagtail/admin/tests/test_collections_views.py +15 -15
  86. wagtail/admin/tests/test_compare.py +34 -0
  87. wagtail/admin/tests/test_editing_sessions.py +230 -8
  88. wagtail/admin/tests/test_forms.py +192 -1
  89. wagtail/admin/tests/test_icon_sprite.py +22 -2
  90. wagtail/admin/tests/test_page_chooser.py +13 -13
  91. wagtail/admin/tests/test_reports_views.py +4 -1
  92. wagtail/admin/tests/test_userbar.py +69 -5
  93. wagtail/admin/tests/test_views_generic.py +5 -5
  94. wagtail/admin/tests/test_workflows.py +14 -12
  95. wagtail/admin/tests/viewsets/test_model_viewset.py +13 -0
  96. wagtail/admin/ui/autosave.py +5 -0
  97. wagtail/admin/ui/editing_sessions.py +3 -0
  98. wagtail/admin/ui/side_panels.py +19 -20
  99. wagtail/admin/userbar.py +48 -27
  100. wagtail/admin/views/bulk_action/dispatcher.py +2 -2
  101. wagtail/admin/views/chooser.py +6 -6
  102. wagtail/admin/views/editing_sessions.py +20 -7
  103. wagtail/admin/views/generic/__init__.py +1 -0
  104. wagtail/admin/views/generic/chooser.py +5 -5
  105. wagtail/admin/views/generic/mixins.py +143 -26
  106. wagtail/admin/views/generic/models.py +157 -27
  107. wagtail/admin/views/generic/ordering.py +1 -1
  108. wagtail/admin/views/generic/preview.py +4 -4
  109. wagtail/admin/views/home.py +3 -1
  110. wagtail/admin/views/pages/create.py +77 -29
  111. wagtail/admin/views/pages/edit.py +160 -34
  112. wagtail/admin/views/pages/preview.py +4 -4
  113. wagtail/admin/views/pages/revisions.py +3 -0
  114. wagtail/admin/views/pages/search.py +4 -4
  115. wagtail/admin/views/pages/usage.py +2 -2
  116. wagtail/admin/views/tags.py +2 -2
  117. wagtail/admin/views/workflows.py +73 -54
  118. wagtail/admin/viewsets/model.py +34 -8
  119. wagtail/admin/widgets/button.py +11 -4
  120. wagtail/admin/widgets/chooser.py +6 -4
  121. wagtail/admin/widgets/slug.py +1 -1
  122. wagtail/api/v2/filters.py +27 -21
  123. wagtail/api/v2/pagination.py +4 -4
  124. wagtail/api/v2/views.py +7 -7
  125. wagtail/blocks/list_block.py +0 -8
  126. wagtail/blocks/migrations/migrate_operation.py +8 -1
  127. wagtail/blocks/stream_block.py +2 -10
  128. wagtail/blocks/struct_block.py +192 -12
  129. wagtail/compat.py +2 -2
  130. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
  131. wagtail/contrib/forms/locale/it/LC_MESSAGES/django.mo +0 -0
  132. wagtail/contrib/forms/locale/it/LC_MESSAGES/django.po +40 -2
  133. wagtail/contrib/frontend_cache/backends/azure.py +6 -6
  134. wagtail/contrib/frontend_cache/backends/cloudfront.py +2 -2
  135. wagtail/contrib/frontend_cache/utils.py +1 -1
  136. wagtail/contrib/redirects/forms.py +1 -1
  137. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +14 -14
  138. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.mo +0 -0
  139. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +15 -2
  140. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.mo +0 -0
  141. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.po +16 -3
  142. wagtail/contrib/redirects/middleware.py +11 -7
  143. wagtail/contrib/redirects/models.py +17 -1
  144. wagtail/contrib/redirects/tests/test_import_admin_views.py +3 -3
  145. wagtail/contrib/redirects/tests/test_redirects.py +56 -8
  146. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +6 -6
  147. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
  148. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +43 -2
  149. wagtail/contrib/search_promotions/tests.py +1 -1
  150. wagtail/contrib/search_promotions/views/settings.py +24 -25
  151. wagtail/contrib/settings/jinja2tags.py +2 -2
  152. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +2 -2
  153. wagtail/contrib/settings/locale/it/LC_MESSAGES/django.mo +0 -0
  154. wagtail/contrib/settings/locale/it/LC_MESSAGES/django.po +6 -2
  155. wagtail/contrib/settings/locale/sv/LC_MESSAGES/django.mo +0 -0
  156. wagtail/contrib/settings/locale/sv/LC_MESSAGES/django.po +3 -2
  157. wagtail/contrib/settings/tests/generic/test_admin.py +118 -2
  158. wagtail/contrib/settings/tests/site_specific/test_admin.py +78 -15
  159. wagtail/contrib/settings/tests/site_specific/test_model.py +2 -2
  160. wagtail/contrib/settings/views.py +7 -0
  161. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  162. wagtail/contrib/simple_translation/locale/it/LC_MESSAGES/django.mo +0 -0
  163. wagtail/contrib/simple_translation/locale/it/LC_MESSAGES/django.po +5 -2
  164. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  165. wagtail/contrib/styleguide/tests.py +2 -0
  166. wagtail/contrib/styleguide/views.py +4 -5
  167. wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.mo +0 -0
  168. wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.po +5 -1
  169. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  170. wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.mo +0 -0
  171. wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +5 -2
  172. wagtail/contrib/typed_table_block/blocks.py +37 -0
  173. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  174. wagtail/contrib/typed_table_block/locale/sv/LC_MESSAGES/django.mo +0 -0
  175. wagtail/contrib/typed_table_block/locale/sv/LC_MESSAGES/django.po +4 -3
  176. wagtail/contrib/typed_table_block/tests.py +108 -0
  177. wagtail/coreutils.py +4 -4
  178. wagtail/documents/__init__.py +4 -4
  179. wagtail/documents/locale/en/LC_MESSAGES/django.po +15 -15
  180. wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
  181. wagtail/documents/locale/it/LC_MESSAGES/django.po +32 -2
  182. wagtail/documents/locale/sv/LC_MESSAGES/django.mo +0 -0
  183. wagtail/documents/locale/sv/LC_MESSAGES/django.po +32 -4
  184. wagtail/documents/models.py +1 -1
  185. wagtail/documents/tests/test_admin_views.py +19 -4
  186. wagtail/documents/tests/test_search.py +0 -2
  187. wagtail/documents/tests/test_views.py +6 -4
  188. wagtail/documents/views/bulk_actions/add_tags.py +1 -1
  189. wagtail/embeds/finders/facebook.py +3 -3
  190. wagtail/embeds/finders/instagram.py +3 -3
  191. wagtail/embeds/finders/oembed.py +7 -2
  192. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  193. wagtail/embeds/oembed_providers.py +8 -0
  194. wagtail/embeds/tests/test_embeds.py +35 -0
  195. wagtail/images/__init__.py +4 -4
  196. wagtail/images/admin_urls.py +3 -3
  197. wagtail/images/blocks.py +1 -1
  198. wagtail/images/formats.py +2 -2
  199. wagtail/images/image_operations.py +2 -2
  200. wagtail/images/locale/en/LC_MESSAGES/django.po +44 -40
  201. wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
  202. wagtail/images/locale/it/LC_MESSAGES/django.po +50 -4
  203. wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
  204. wagtail/images/locale/nl/LC_MESSAGES/django.po +3 -3
  205. wagtail/images/locale/sv/LC_MESSAGES/django.mo +0 -0
  206. wagtail/images/locale/sv/LC_MESSAGES/django.po +49 -6
  207. wagtail/images/models.py +11 -10
  208. wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
  209. wagtail/images/templates/wagtailimages/images/url_generator.html +17 -38
  210. wagtail/images/templates/wagtailimages/images/url_generator_output.html +28 -0
  211. wagtail/images/templatetags/wagtailimages_tags.py +4 -4
  212. wagtail/images/tests/test_admin_views.py +432 -59
  213. wagtail/images/tests/test_image_operations.py +2 -2
  214. wagtail/images/tests/test_models.py +0 -2
  215. wagtail/images/views/bulk_actions/add_tags.py +1 -1
  216. wagtail/images/views/images.py +72 -39
  217. wagtail/locale/en/LC_MESSAGES/django.po +103 -105
  218. wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
  219. wagtail/locale/it/LC_MESSAGES/django.po +105 -2
  220. wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
  221. wagtail/locale/sv/LC_MESSAGES/django.po +95 -12
  222. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  223. wagtail/locales/locale/it/LC_MESSAGES/django.mo +0 -0
  224. wagtail/locales/locale/it/LC_MESSAGES/django.po +13 -2
  225. wagtail/locales/locale/sv/LC_MESSAGES/django.mo +0 -0
  226. wagtail/locales/locale/sv/LC_MESSAGES/django.po +4 -3
  227. wagtail/locales/tests.py +5 -5
  228. wagtail/models/i18n.py +4 -6
  229. wagtail/models/media.py +18 -0
  230. wagtail/models/pages.py +65 -11
  231. wagtail/models/reference_index.py +15 -0
  232. wagtail/models/revisions.py +40 -12
  233. wagtail/models/workflows.py +0 -3
  234. wagtail/permission_policies/base.py +2 -2
  235. wagtail/permission_policies/collections.py +2 -2
  236. wagtail/project_template/requirements.txt +2 -2
  237. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  238. wagtail/signal_handlers.py +1 -0
  239. wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
  240. wagtail/sites/locale/sv/LC_MESSAGES/django.mo +0 -0
  241. wagtail/sites/locale/sv/LC_MESSAGES/django.po +3 -2
  242. wagtail/sites/tests.py +7 -7
  243. wagtail/snippets/action_menu.py +2 -1
  244. wagtail/snippets/locale/en/LC_MESSAGES/django.po +23 -13
  245. wagtail/snippets/locale/sv/LC_MESSAGES/django.mo +0 -0
  246. wagtail/snippets/locale/sv/LC_MESSAGES/django.po +12 -1
  247. wagtail/snippets/tests/test_chooser_block.py +197 -0
  248. wagtail/snippets/tests/test_chooser_panel.py +149 -0
  249. wagtail/snippets/tests/test_chooser_views.py +375 -0
  250. wagtail/snippets/tests/test_chooser_widget.py +22 -0
  251. wagtail/snippets/tests/test_compare_revisions_view.py +167 -0
  252. wagtail/snippets/tests/test_copy_view.py +38 -0
  253. wagtail/snippets/tests/test_create_view.py +1159 -0
  254. wagtail/snippets/tests/test_delete_view.py +225 -0
  255. wagtail/snippets/tests/test_edit_view.py +2882 -0
  256. wagtail/snippets/tests/test_history_view.py +182 -0
  257. wagtail/snippets/tests/test_index_view.py +105 -0
  258. wagtail/snippets/tests/test_list_view.py +786 -0
  259. wagtail/snippets/tests/test_locking.py +28 -0
  260. wagtail/snippets/tests/test_permissions.py +167 -0
  261. wagtail/snippets/tests/test_preview.py +3 -3
  262. wagtail/snippets/tests/test_revert_view.py +343 -0
  263. wagtail/snippets/tests/test_snippet_models.py +112 -0
  264. wagtail/snippets/tests/test_unpublish_view.py +228 -0
  265. wagtail/snippets/tests/test_unschedule_view.py +151 -0
  266. wagtail/snippets/tests/test_viewset.py +38 -5
  267. wagtail/snippets/views/snippets.py +78 -30
  268. wagtail/snippets/widgets.py +2 -2
  269. wagtail/templatetags/wagtailcore_tags.py +2 -2
  270. wagtail/test/dummy_external_storage.py +1 -1
  271. wagtail/test/testapp/fixtures/test.json +22 -0
  272. wagtail/test/testapp/fixtures/test_empty.json +2 -0
  273. wagtail/test/testapp/fixtures/test_explorable_pages.json +10 -0
  274. wagtail/test/testapp/fixtures/test_specific.json +9 -0
  275. wagtail/test/testapp/migrations/0059_nopromotepage.py +25 -0
  276. wagtail/test/testapp/models.py +7 -0
  277. wagtail/test/testapp/views.py +5 -0
  278. wagtail/test/utils/page_tests.py +7 -7
  279. wagtail/test/utils/wagtail_factories/builder.py +2 -2
  280. wagtail/tests/streamfield_migrations/test_migrations.py +35 -0
  281. wagtail/tests/test_blocks.py +321 -61
  282. wagtail/tests/test_collection_model.py +12 -0
  283. wagtail/tests/test_page_model.py +190 -1
  284. wagtail/tests/test_page_privacy.py +5 -0
  285. wagtail/tests/test_reference_index.py +42 -0
  286. wagtail/tests/test_revision_model.py +118 -1
  287. wagtail/tests/test_utils.py +2 -2
  288. wagtail/users/locale/en/LC_MESSAGES/django.po +14 -14
  289. wagtail/users/locale/id_ID/LC_MESSAGES/django.mo +0 -0
  290. wagtail/users/locale/id_ID/LC_MESSAGES/django.po +6 -2
  291. wagtail/users/locale/it/LC_MESSAGES/django.mo +0 -0
  292. wagtail/users/locale/it/LC_MESSAGES/django.po +14 -2
  293. wagtail/users/locale/sv/LC_MESSAGES/django.mo +0 -0
  294. wagtail/users/locale/sv/LC_MESSAGES/django.po +48 -17
  295. wagtail/users/tests/test_admin_views.py +39 -25
  296. wagtail/users/utils.py +4 -1
  297. wagtail/users/views/groups.py +19 -5
  298. wagtail/users/wagtail_hooks.py +1 -1
  299. wagtail/utils/loading.py +2 -2
  300. wagtail-7.3rc1.data/data/AGENTS.md +21 -0
  301. wagtail-7.3rc1.data/data/CHANGELOG.txt +4941 -0
  302. wagtail-7.3rc1.data/data/CODE_OF_CONDUCT.md +71 -0
  303. wagtail-7.3rc1.data/data/CONTRIBUTORS.md +999 -0
  304. wagtail-7.3rc1.data/data/SPONSORS.md +55 -0
  305. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/METADATA +6 -6
  306. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/RECORD +310 -280
  307. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/WHEEL +1 -1
  308. wagtail/images/static/wagtailimages/js/image-url-generator.js +0 -1
  309. wagtail/snippets/tests/test_snippets.py +0 -6377
  310. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/entry_points.txt +0 -0
  311. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/licenses/LICENSE +0 -0
  312. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@
7
7
  # giammi <gian-maria.daffre@giammi.org>, 2018
8
8
  # giammi <gian-maria.daffre@giammi.org>, 2018
9
9
  # Guglielmo Celata <guglielmo.celata@gmail.com>, 2019
10
- # Marco Badan <marco.badan@gmail.com>, 2021-2024
10
+ # Marco Badan <marco.badan@gmail.com>, 2021-2024,2026
11
11
  # Matt Westcott <matthew@torchbox.com>, 2022
12
12
  # Sandro Badalamenti <sandro@mailinator.com>, 2019
13
13
  # Stefano Marchetto <airbatum@gmail.com>, 2020
@@ -17,7 +17,7 @@ msgstr ""
17
17
  "Report-Msgid-Bugs-To: \n"
18
18
  "POT-Creation-Date: 2025-10-23 16:45+0100\n"
19
19
  "PO-Revision-Date: 2014-02-20 21:05+0000\n"
20
- "Last-Translator: Stefano Marchetto <airbatum@gmail.com>, 2020\n"
20
+ "Last-Translator: Marco Badan <marco.badan@gmail.com>, 2021-2024,2026\n"
21
21
  "Language-Team: Italian (http://app.transifex.com/torchbox/wagtail/language/"
22
22
  "it/)\n"
23
23
  "MIME-Version: 1.0\n"
@@ -267,6 +267,9 @@ msgstr "No, non rimuovere"
267
267
  msgid "Popular tags"
268
268
  msgstr "Tags popolari"
269
269
 
270
+ msgid "Layout"
271
+ msgstr "Layout"
272
+
270
273
  msgid ""
271
274
  "Upload successful. However, your new image seems to be a duplicate of an "
272
275
  "existing image. You may delete it if it wasn't required."
@@ -300,17 +303,38 @@ msgstr "Non hai caricato nessuna immagine in questa raccolta."
300
303
  msgid "You haven't uploaded any images."
301
304
  msgstr "Non hai caricato alcuna immagine."
302
305
 
306
+ msgid ""
307
+ "Why not <a class=\"upload-one-now\" href=\"#tab-upload\" data-action=\"w-"
308
+ "tabs#select:prevent\" data-w-tabs-target=\"trigger\" data-w-tabs-focus-"
309
+ "param=\"true\">upload one now</a>?"
310
+ msgstr ""
311
+ "Perché non<a class=\"upload-one-now\" href=\"#tab-upload\" data-action=\"w-"
312
+ "tabs#select:prevent\" data-w-tabs-target=\"trigger\" data-w-tabs-focus-"
313
+ "param=\"true\">caricarne uno adesso</a>?"
314
+
303
315
  msgid "Choose a format"
304
316
  msgstr "Scegli un formato"
305
317
 
306
318
  msgid "Insert image"
307
319
  msgstr "Inserisci immagine"
308
320
 
321
+ #, python-format
322
+ msgid ""
323
+ "%(total)s Image <span class=\"w-sr-only\">created in %(site_name)s</span>"
324
+ msgid_plural ""
325
+ "%(total)s Images <span class=\"w-sr-only\">created in %(site_name)s</span>"
326
+ msgstr[0] ""
327
+ "%(total)s Immagine <span class=\"w-sr-only\">creata in %(site_name)s</span>"
328
+ msgstr[1] ""
329
+ "%(total)s Immagini <span class=\"w-sr-only\">create in %(site_name)s</span>"
330
+ msgstr[2] ""
331
+ "%(total)s Immagini <span class=\"w-sr-only\">create in %(site_name)s</span>"
332
+
309
333
  msgid "Change image file:"
310
- msgstr "Cambia immagine"
334
+ msgstr "Cambia file immagine:"
311
335
 
312
336
  msgid "Add an image"
313
- msgstr "Aggiungi un immagine"
337
+ msgstr "Aggiungi un'immagine"
314
338
 
315
339
  msgid "Uploading…"
316
340
  msgstr "Caricamento…"
@@ -395,6 +419,12 @@ msgstr ""
395
419
  "Non hai caricato nessuna immagine. Perché non <a "
396
420
  "href=\"%(wagtailimages_add_image_url)s\">ne aggiungi una adesso</a>?"
397
421
 
422
+ msgid "Grid layout"
423
+ msgstr "Layout a griglia"
424
+
425
+ msgid "List layout"
426
+ msgstr "Layout a lista"
427
+
398
428
  msgid "Preview"
399
429
  msgstr "Anteprima"
400
430
 
@@ -425,6 +455,13 @@ msgstr "Oppure sceglila dal tuo computer"
425
455
  msgid "Add to collection:"
426
456
  msgstr "Aggiungi alla raccolta:"
427
457
 
458
+ msgid ""
459
+ "Please provide an image description to comply with best practices for "
460
+ "accessibility."
461
+ msgstr ""
462
+ "Per favore, fornisci una descrizione dell’immagine per essere conforme alle "
463
+ "migliori pratiche di accessibilità."
464
+
428
465
  msgid ""
429
466
  "Upload successful. Please update this image with a more appropriate title, "
430
467
  "if necessary. You may also delete the image completely if the upload wasn't "
@@ -540,6 +577,12 @@ msgstr "Dimensione file: (crescente)"
540
577
  msgid "File size: (high to low)"
541
578
  msgstr "Dimensione file: (decrescente)"
542
579
 
580
+ msgid "Usage count: (low to high)"
581
+ msgstr "Conteggio utilizzo: (da basso a alto)"
582
+
583
+ msgid "Usage count: (high to low)"
584
+ msgstr "Conteggio di utilizzo: (da alto a basso)"
585
+
543
586
  msgid "Images"
544
587
  msgstr "Immagini"
545
588
 
@@ -557,6 +600,9 @@ msgstr ""
557
600
  "Il file dell'immagine non è stato trovato. Cambia il file oppure elimina "
558
601
  "l'immagine."
559
602
 
603
+ msgid "Generate URL"
604
+ msgstr "Genera URL"
605
+
560
606
  msgid "Delete image"
561
607
  msgstr "Elimina immagine"
562
608
 
@@ -271,9 +271,9 @@ msgid ""
271
271
  "Upload successful. However, your new image seems to be a duplicate of an "
272
272
  "existing image. You may delete it if it wasn't required."
273
273
  msgstr ""
274
- "Upload is geslaagd. Maar je nieuwe afbeelding lijkt op een dubbeling van een "
275
- "bestaande afbeelding. Misschien was de upload niet nodig en kun je deze "
276
- "afbeelding verwijderen?"
274
+ "Upload is geslaagd. Maar je nieuwe afbeelding lijkt een dubbeling te zijn "
275
+ "van een bestaande afbeelding. Misschien was de upload niet nodig en kun je "
276
+ "deze afbeelding verwijderen?"
277
277
 
278
278
  msgid "Existing"
279
279
  msgstr "Bestaand"
@@ -4,6 +4,7 @@
4
4
  #
5
5
  # Translators:
6
6
  # Jim Brouzoulis <jim.brouzoulis@chalmers.se>, 2017
7
+ # Jonathan Lindén, 2025
7
8
  # Martin Sandström <martin@marteinn.se>, 2020-2024
8
9
  # Matt Westcott <matthew@torchbox.com>, 2022
9
10
  # Oscar Fröberg <oscfr657@gmail.com>, 2020
@@ -15,7 +16,7 @@ msgstr ""
15
16
  "Report-Msgid-Bugs-To: \n"
16
17
  "POT-Creation-Date: 2025-10-23 16:45+0100\n"
17
18
  "PO-Revision-Date: 2014-02-20 21:05+0000\n"
18
- "Last-Translator: Thomas Kunambi <kunambi@gmail.com>, 2015,2021\n"
19
+ "Last-Translator: Jonathan Lindén, 2025\n"
19
20
  "Language-Team: Swedish (http://app.transifex.com/torchbox/wagtail/language/"
20
21
  "sv/)\n"
21
22
  "MIME-Version: 1.0\n"
@@ -249,6 +250,9 @@ msgstr "Nej, radera inte"
249
250
  msgid "Popular tags"
250
251
  msgstr "Populära taggar"
251
252
 
253
+ msgid "Layout"
254
+ msgstr "Layout"
255
+
252
256
  msgid ""
253
257
  "Upload successful. However, your new image seems to be a duplicate of an "
254
258
  "existing image. You may delete it if it wasn't required."
@@ -281,12 +285,31 @@ msgstr "Du har inte laddat upp några bilder i denna samling"
281
285
  msgid "You haven't uploaded any images."
282
286
  msgstr "Du har inte laddat upp några bilder."
283
287
 
288
+ msgid ""
289
+ "Why not <a class=\"upload-one-now\" href=\"#tab-upload\" data-action=\"w-"
290
+ "tabs#select:prevent\" data-w-tabs-target=\"trigger\" data-w-tabs-focus-"
291
+ "param=\"true\">upload one now</a>?"
292
+ msgstr ""
293
+ "Varför inte <a class=\"upload-one-now\" href=\"#tab-upload\" data-action=\"w-"
294
+ "tabs#select:prevent\" data-w-tabs-target=\"trigger\" data-w-tabs-focus-"
295
+ "param=\"true\">ladda upp en nu</a>?"
296
+
284
297
  msgid "Choose a format"
285
298
  msgstr "Välj ett format"
286
299
 
287
300
  msgid "Insert image"
288
301
  msgstr "Lägg in bild"
289
302
 
303
+ #, python-format
304
+ msgid ""
305
+ "%(total)s Image <span class=\"w-sr-only\">created in %(site_name)s</span>"
306
+ msgid_plural ""
307
+ "%(total)s Images <span class=\"w-sr-only\">created in %(site_name)s</span>"
308
+ msgstr[0] ""
309
+ "%(total)s Bild <span class=\"w-sr-only\">skapad i %(site_name)s</span>"
310
+ msgstr[1] ""
311
+ "%(total)s Bilder <span class=\"w-sr-only\">skapade i %(site_name)s</span>"
312
+
290
313
  msgid "Change image file:"
291
314
  msgstr "Byt bildfil:"
292
315
 
@@ -374,6 +397,12 @@ msgstr ""
374
397
  "Du har inte laddat upp några bilder Varför inte <a "
375
398
  "href=\"%(wagtailimages_add_image_url)s\">ladda upp en nu</a>?"
376
399
 
400
+ msgid "Grid layout"
401
+ msgstr "Rutnät"
402
+
403
+ msgid "List layout"
404
+ msgstr "Lista"
405
+
377
406
  msgid "Preview"
378
407
  msgstr "Förhandsgranska"
379
408
 
@@ -404,13 +433,18 @@ msgstr "Eller välj från din dator"
404
433
  msgid "Add to collection:"
405
434
  msgstr "Lägg till i samling:"
406
435
 
436
+ msgid ""
437
+ "Please provide an image description to comply with best practices for "
438
+ "accessibility."
439
+ msgstr "Ange en bildbeskrivning för att följa bästa praxis för tillgänglighet."
440
+
407
441
  msgid ""
408
442
  "Upload successful. Please update this image with a more appropriate title, "
409
443
  "if necessary. You may also delete the image completely if the upload wasn't "
410
444
  "required."
411
445
  msgstr ""
412
446
  "Uppladdningen lyckades. Vänligen uppdatera den här bilden med en mer lämplig "
413
- "titel, om nödvändigt. Du kan också ta bort bilden helt och hållet om "
447
+ "titel, om nödvändigt. Du kan också radera bilden helt och hållet om "
414
448
  "uppladdningen inte var nödvändig."
415
449
 
416
450
  msgid ""
@@ -514,11 +548,17 @@ msgstr "Filstorlek: (låg till hög)"
514
548
  msgid "File size: (high to low)"
515
549
  msgstr "Filstorlek: (hög till låg)"
516
550
 
551
+ msgid "Usage count: (low to high)"
552
+ msgstr "Antal användningar: (låg till hög)"
553
+
554
+ msgid "Usage count: (high to low)"
555
+ msgstr "Antal användningar: (hög till låg)"
556
+
517
557
  msgid "Images"
518
558
  msgstr "Bilder"
519
559
 
520
560
  msgid "The image could not be saved due to errors."
521
- msgstr "Bilden kunde inte sparas p.g.a. fel."
561
+ msgstr "Bilden kunde inte sparas grund av fel."
522
562
 
523
563
  #, python-format
524
564
  msgid "Image '%(image_title)s' updated."
@@ -528,8 +568,11 @@ msgid ""
528
568
  "The source image file could not be found. Please change the source or delete "
529
569
  "the image."
530
570
  msgstr ""
531
- "Filen för originalbilden kunde inte hittas. Vänligen ändra filen eller ta "
532
- "bort bilden."
571
+ "Filen för originalbilden kunde inte hittas. Vänligen ändra källan eller "
572
+ "radera bilden."
573
+
574
+ msgid "Generate URL"
575
+ msgstr "Generera URL"
533
576
 
534
577
  msgid "Delete image"
535
578
  msgstr "Radera bild"
@@ -539,7 +582,7 @@ msgid "Image '%(image_title)s' deleted."
539
582
  msgstr "Bild '%(image_title)s' raderad."
540
583
 
541
584
  msgid "The image could not be created due to errors."
542
- msgstr "Bilden kunde inte skapas p.g.a. fel."
585
+ msgstr "Bilden kunde inte skapas grund av fel."
543
586
 
544
587
  #, python-format
545
588
  msgid "Image '%(image_title)s' added."
wagtail/images/models.py CHANGED
@@ -141,10 +141,10 @@ def get_rendition_storage():
141
141
  try:
142
142
  module = import_string(storage)
143
143
  storage = module()
144
- except ImportError:
144
+ except ImportError as e:
145
145
  raise ImproperlyConfigured(
146
146
  "WAGTAILIMAGES_RENDITION_STORAGE must be either a valid storage alias or dotted module path."
147
- )
147
+ ) from e
148
148
 
149
149
  return storage
150
150
 
@@ -171,7 +171,7 @@ class ImageFileMixin:
171
171
  # Have to catch everything, because the exception
172
172
  # depends on the file subclass, and therefore the
173
173
  # storage being used.
174
- raise SourceImageIOError(str(e))
174
+ raise SourceImageIOError(str(e)) from e
175
175
 
176
176
  self.save(update_fields=["file_size"])
177
177
 
@@ -198,7 +198,7 @@ class ImageFileMixin:
198
198
  except OSError as e:
199
199
  # re-throw this as a SourceImageIOError so that calling code can distinguish
200
200
  # these from IOErrors elsewhere in the process
201
- raise SourceImageIOError(str(e))
201
+ raise SourceImageIOError(str(e)) from e
202
202
 
203
203
  # Seek to beginning
204
204
  image_file.seek(0)
@@ -576,8 +576,8 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
576
576
 
577
577
  try:
578
578
  return self.find_existing_renditions(filter)[filter]
579
- except KeyError:
580
- raise Rendition.DoesNotExist
579
+ except KeyError as e:
580
+ raise Rendition.DoesNotExist from e
581
581
 
582
582
  def create_rendition(self, filter: Filter) -> AbstractRendition:
583
583
  """
@@ -1103,7 +1103,7 @@ class Filter:
1103
1103
  if "jpeg-quality" in env:
1104
1104
  quality = env["jpeg-quality"]
1105
1105
  else:
1106
- quality = getattr(settings, "WAGTAILIMAGES_JPEG_QUALITY", 85)
1106
+ quality = getattr(settings, "WAGTAILIMAGES_JPEG_QUALITY", 76)
1107
1107
 
1108
1108
  # If the image has an alpha channel, give it a white background
1109
1109
  if willow.has_alpha():
@@ -1139,7 +1139,7 @@ class Filter:
1139
1139
  elif "avif-quality" in env:
1140
1140
  quality = env["avif-quality"]
1141
1141
  else:
1142
- quality = getattr(settings, "WAGTAILIMAGES_AVIF_QUALITY", 80)
1142
+ quality = getattr(settings, "WAGTAILIMAGES_AVIF_QUALITY", 61)
1143
1143
  return willow.save_as_avif(output, quality=quality)
1144
1144
  elif output_format == "heic":
1145
1145
  # Allow changing of HEIC compression quality. Safari is the only browser that supports HEIC,
@@ -1448,12 +1448,13 @@ class AbstractRendition(ImageFileMixin, models.Model):
1448
1448
  else:
1449
1449
  return "50%"
1450
1450
 
1451
- def img_tag(self, extra_attributes={}):
1451
+ def img_tag(self, extra_attributes=None):
1452
1452
  attrs = self.attrs_dict.copy()
1453
1453
 
1454
1454
  attrs.update(apps.get_app_config("wagtailimages").default_attrs)
1455
1455
 
1456
- attrs.update(extra_attributes)
1456
+ if extra_attributes:
1457
+ attrs.update(extra_attributes)
1457
1458
 
1458
1459
  return mark_safe(f"<img{flatatt(attrs)}>")
1459
1460
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  {% block before_results %}
6
6
  {{ block.super }}
7
- <template data-controller="w-teleport" data-w-teleport-target-value="#layout-switch-control" data-w-teleport-reset-value="true">
7
+ <template data-controller="w-teleport" data-w-teleport-target-value="#layout-switch-control" data-w-teleport-mode-value="innerHTML">
8
8
  {% include "wagtailimages/images/layout_toggle_button.html" %}
9
9
  </template>
10
10
  {% endblock %}
@@ -1,10 +1,21 @@
1
1
  {% extends "wagtailadmin/generic/base.html" %}
2
2
  {% load wagtailimages_tags wagtailadmin_tags i18n %}
3
3
 
4
-
5
4
  {% block main_content %}
6
- <div class="w-image-url-generator w-mt-8" data-generator-url="{% url 'wagtailimages:generate_url' object.id '__filterspec__' %}">
7
- <form class="w-image-url-generator__form w-mb-5" data-controller="w-rules" data-action="change->w-rules#resolve keyup->w-rules#resolve">
5
+ <div class="w-image-url-generator w-mt-8">
6
+ <form
7
+ class="w-image-url-generator__form w-mb-5"
8
+ id="image-url-generator-form"
9
+ method="get"
10
+ data-controller="w-rules w-swap"
11
+ data-action="change->w-rules#resolve keyup->w-rules#resolve change->w-swap#submitLazy keyup->w-swap#submitLazy"
12
+ data-w-swap-loading-class="loading"
13
+ data-w-swap-messages-value='{{ message_labels }}'
14
+ data-w-swap-reflect-value="true"
15
+ data-w-swap-src-value="{% url 'wagtailimages:url_generator_output' object.id %}"
16
+ data-w-swap-target-value="output[form='image-url-generator-form']"
17
+ data-w-swap-wait-value="500"
18
+ >
8
19
  {% include "wagtailadmin/shared/field.html" with field=form.filter_method %}
9
20
  {% field_row max_content=True %}
10
21
  {% include "wagtailadmin/shared/field.html" with field=form.width %}
@@ -12,40 +23,8 @@
12
23
  {% include "wagtailadmin/shared/field.html" with field=form.closeness %}
13
24
  {% endfield_row %}
14
25
  </form>
15
-
16
- {% trans "Preview" as heading %}
17
- {% panel id="preview" icon="view" heading=heading %}
18
- <div class="w-image-url-generator__preview">
19
- <div class="loading-mask w-block w-border-2 w-border-border-furniture w-overflow-scroll w-p-4 w-rounded-sm w-max-h-[clamp(25rem,50vh,50rem)]">
20
- <img class="preview w-max-w-none" src="" alt="{% trans 'Preview' %}" />
21
- </div>
22
- </div>
23
- {% endpanel %}
24
-
25
- {% trans "URL" as heading %}
26
- {% panel id="url" heading=heading %}
27
- <div class="w-relative" data-controller="w-clipboard w-clone" data-w-clone-auto-clear-value="5_000" data-action="w-clipboard:copy->w-clone#clear w-clipboard:copied->w-clone#add w-clipboard:error->w-clone#add">
28
- <label class="w-sr-only" for="result-url">{% trans "Image URL" %}</label>
29
- <textarea class="w-image-url-generator__url" id="result-url" rows="1" name="result-url" data-controller="w-action" data-action="focus->w-action#select" data-w-clipboard-target="value">
30
- </textarea>
31
- <button type="button" class="button button-secondary w-absolute w-top-3.5 w-right-3 w-bottom-auto w-left-auto" data-action="w-clipboard#copy" aria-describedby="clipboard-tooltip">
32
- {% trans "Copy URL" %}
33
- </button>
34
- <div class="clipboard-tooltip" data-w-clone-target="container" id="clipboard-tooltip" aria-atomic="true" aria-live="polite"></div>
35
- <template data-w-clone-target="template" data-type="success">
36
- <span class="w-text-grey-50 w-absolute w-right-2 w-bg-positive-100 w-p-2 w-rounded-sm">{% trans 'Copied to clipboard' %}</span>
37
- </template>
38
- <template data-w-clone-target="template" data-type="error">
39
- <span class="w-text-grey-50 w-absolute w-right-2 w-bg-critical-100 w-p-2 w-rounded-sm">{% trans 'Copying to clipboard failed' %}</span>
40
- </template>
41
- </div>
42
- {% endpanel %}
26
+ <output aria-live="polite" class="loading-mask w-block" form="image-url-generator-form" for="{% for field in form %}{{ field.id_for_label }}{% if not forloop.last %} {% endif %}{% endfor %}">
27
+ {% include "wagtailimages/images/url_generator_output.html" %}
28
+ </output>
43
29
  </div>
44
30
  {% endblock %}
45
-
46
- {% block extra_js %}
47
- {{ block.super }}
48
-
49
- <script src="{% versioned_static 'wagtailadmin/js/vendor/jquery.ba-throttle-debounce.min.js' %}"></script>
50
- <script src="{% versioned_static 'wagtailimages/js/image-url-generator.js' %}"></script>
51
- {% endblock %}
@@ -0,0 +1,28 @@
1
+ {% load wagtailadmin_tags i18n %}
2
+
3
+ {% trans "Preview" as heading %}
4
+ {% panel id="preview" icon="view" heading=heading %}
5
+ <div class="w-image-url-generator__preview">
6
+ <div class="w-block w-border-2 w-border-border-furniture w-overflow-scroll w-p-4 w-rounded-sm w-max-h-[clamp(25rem,50vh,50rem)]">
7
+ <img class="preview w-max-w-none" src="{{ preview_url }}" alt="{% trans 'Preview' %}" />
8
+ </div>
9
+ </div>
10
+ {% endpanel %}
11
+
12
+ {% trans "URL" as heading %}
13
+ {% panel id="url" heading=heading %}
14
+ <div class="w-relative" data-controller="w-clipboard w-clone" data-w-clone-auto-clear-value="5_000" data-action="w-clipboard:copy->w-clone#clear w-clipboard:copied->w-clone#add w-clipboard:error->w-clone#add">
15
+ <label class="w-sr-only" for="result-url">{% trans "Image URL" %}</label>
16
+ <textarea class="w-image-url-generator__url" id="result-url" rows="1" name="result-url" data-controller="w-action" data-action="focus->w-action#select" data-w-clipboard-target="value">{{ result_url }}</textarea>
17
+ <button type="button" class="button button-secondary button-small w-absolute w-top-5 w-right-3 w-bottom-auto w-left-auto !w-bg-surface-page" data-action="w-clipboard#copy" aria-describedby="clipboard-tooltip">
18
+ {% trans "Copy URL" %}
19
+ </button>
20
+ <div class="clipboard-tooltip" data-w-clone-target="container" id="clipboard-tooltip" aria-atomic="true" aria-live="polite"></div>
21
+ <template data-w-clone-target="template" data-type="success">
22
+ <span class="w-text-grey-50 w-absolute w-right-2 w-bg-positive-100 w-p-2 w-rounded-sm">{% trans 'Copied to clipboard' %}</span>
23
+ </template>
24
+ <template data-w-clone-target="template" data-type="error">
25
+ <span class="w-text-grey-50 w-absolute w-right-2 w-bg-critical-100 w-p-2 w-rounded-sm">{% trans 'Copying to clipboard failed' %}</span>
26
+ </template>
27
+ </div>
28
+ {% endpanel %}
@@ -46,7 +46,7 @@ def image(parser, token):
46
46
  attrs[name] = parser.compile_filter(
47
47
  value
48
48
  ) # setup to resolve context variables as value
49
- except ValueError:
49
+ except ValueError as e:
50
50
  allowed_pattern = (
51
51
  Filter.expanding_spec_pattern
52
52
  if multi_rendition
@@ -58,7 +58,7 @@ def image(parser, token):
58
58
  raise template.TemplateSyntaxError(
59
59
  "filter specs in image tags may only contain A-Z, a-z, 0-9, dots, hyphens and underscores (and commas and curly braces for multi-image tags). "
60
60
  "(given filter: {})".format(bit)
61
- )
61
+ ) from e
62
62
 
63
63
  if as_context and output_var_name is None:
64
64
  # context was introduced but no variable given ...
@@ -211,10 +211,10 @@ class PictureNode(SrcsetImageNode):
211
211
  def image_url(image, filter_spec, viewname="wagtailimages_serve"):
212
212
  try:
213
213
  return generate_image_url(image, filter_spec, viewname)
214
- except NoReverseMatch:
214
+ except NoReverseMatch as e:
215
215
  raise ImproperlyConfigured(
216
216
  "'image_url' tag requires the "
217
217
  + viewname
218
218
  + " view to be configured. Please see "
219
219
  "https://docs.wagtail.org/en/stable/advanced_topics/images/image_serve_view.html#setup for instructions."
220
- )
220
+ ) from e