wagtail 6.1.3__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.
- wagtail/__init__.py +1 -1
- wagtail/actions/copy_for_translation.py +15 -1
- wagtail/admin/checks.py +20 -30
- wagtail/admin/forms/pages.py +10 -0
- wagtail/admin/icons.py +43 -0
- wagtail/admin/locale/en/LC_MESSAGES/django.po +405 -295
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -3
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +30 -0
- wagtail/admin/menu.py +2 -2
- wagtail/admin/migrations/0004_editingsession.py +57 -0
- wagtail/admin/migrations/0005_editingsession_is_editing.py +18 -0
- wagtail/admin/models.py +36 -3
- wagtail/admin/rich_text/editors/draftail/__init__.py +2 -20
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
- wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js +1 -1
- wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
- wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
- wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/preview-panel.js +2 -1
- wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +11 -0
- wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +2 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +11 -0
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +0 -12
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/templates/wagtailadmin/collection_privacy/ancestor_privacy.html +2 -6
- wagtail/admin/templates/wagtailadmin/generic/index_results.html +1 -17
- wagtail/admin/templates/wagtailadmin/generic/listing_results.html +20 -1
- wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +2 -11
- wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +2 -6
- wagtail/admin/templates/wagtailadmin/page_privacy/no_privacy.html +2 -0
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
- wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -1
- wagtail/admin/templates/wagtailadmin/reports/aging_pages_results.html +54 -0
- wagtail/admin/templates/wagtailadmin/reports/base_page_report.html +1 -17
- wagtail/admin/templates/wagtailadmin/reports/base_page_report_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/reports/base_report.html +1 -40
- wagtail/admin/templates/wagtailadmin/reports/base_report_results.html +1 -0
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +21 -27
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +48 -54
- wagtail/admin/templates/wagtailadmin/reports/{locked_pages.html → locked_pages_results.html} +3 -3
- wagtail/admin/templates/wagtailadmin/reports/page_types_usage_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/reports/site_history_results.html +53 -0
- wagtail/admin/templates/wagtailadmin/reports/workflow_results.html +74 -0
- wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +56 -0
- wagtail/admin/templates/wagtailadmin/shared/_workflow_init.html +8 -44
- wagtail/admin/templates/wagtailadmin/shared/avatar.html +11 -1
- wagtail/admin/templates/wagtailadmin/shared/dialog/dialog.html +5 -4
- wagtail/admin/templates/wagtailadmin/shared/dropdown/dropdown_button.html +2 -1
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +132 -0
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +44 -0
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +7 -1
- wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +32 -16
- wagtail/admin/templates/wagtailadmin/skeleton.html +1 -1
- wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +9 -11
- wagtail/admin/templatetags/wagtailadmin_tags.py +13 -2
- wagtail/admin/tests/formats/en/__init__.py +0 -0
- wagtail/admin/tests/formats/en/formats.py +1 -0
- wagtail/admin/tests/pages/test_create_page.py +47 -0
- wagtail/admin/tests/pages/test_edit_page.py +10 -8
- wagtail/admin/tests/pages/test_parent_page_chooser_view.py +45 -1
- wagtail/admin/tests/test_checks.py +53 -3
- wagtail/admin/tests/test_collections_views.py +62 -1
- wagtail/admin/tests/test_edit_handlers.py +37 -0
- wagtail/admin/tests/test_editing_sessions.py +1336 -0
- wagtail/admin/tests/test_icon_sprite.py +12 -21
- wagtail/admin/tests/test_page_chooser.py +309 -7
- wagtail/admin/tests/test_privacy.py +82 -0
- wagtail/admin/tests/test_reports_views.py +464 -70
- wagtail/admin/tests/test_userbar.py +93 -6
- wagtail/admin/tests/test_workflows.py +223 -33
- wagtail/admin/tests/viewsets/test_model_viewset.py +151 -2
- wagtail/admin/ui/editing_sessions.py +57 -0
- wagtail/admin/urls/__init__.py +9 -15
- wagtail/admin/urls/editing_sessions.py +17 -0
- wagtail/admin/urls/reports.py +33 -1
- wagtail/admin/userbar.py +77 -20
- wagtail/admin/views/chooser.py +49 -22
- wagtail/admin/views/collections.py +0 -11
- wagtail/admin/views/editing_sessions.py +193 -0
- wagtail/admin/views/generic/__init__.py +1 -0
- wagtail/admin/views/generic/history.py +9 -3
- wagtail/admin/views/generic/mixins.py +44 -3
- wagtail/admin/views/generic/models.py +46 -72
- wagtail/admin/views/generic/permissions.py +20 -10
- wagtail/admin/views/home.py +2 -31
- wagtail/admin/views/page_privacy.py +20 -5
- wagtail/admin/views/pages/choose_parent.py +62 -0
- wagtail/admin/views/pages/edit.py +28 -0
- wagtail/admin/views/reports/aging_pages.py +6 -10
- wagtail/admin/views/reports/audit_logging.py +13 -42
- wagtail/admin/views/reports/base.py +31 -4
- wagtail/admin/views/reports/locked_pages.py +5 -8
- wagtail/admin/views/reports/page_types_usage.py +6 -10
- wagtail/admin/views/reports/workflows.py +36 -12
- wagtail/admin/viewsets/base.py +8 -3
- wagtail/admin/viewsets/chooser.py +1 -1
- wagtail/admin/viewsets/model.py +26 -1
- wagtail/admin/wagtail_hooks.py +2 -1
- wagtail/api/v2/filters.py +6 -0
- wagtail/api/v2/tests/test_documents.py +1 -1
- wagtail/api/v2/tests/test_images.py +1 -1
- wagtail/api/v2/tests/test_pages.py +11 -1
- wagtail/api/v2/utils.py +2 -2
- wagtail/blocks/base.py +35 -12
- wagtail/blocks/definition_lookup.py +85 -0
- wagtail/blocks/list_block.py +12 -0
- wagtail/blocks/migrations/migrate_operation.py +2 -0
- wagtail/blocks/stream_block.py +19 -0
- wagtail/blocks/struct_block.py +19 -0
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/frontend_cache/backends/__init__.py +5 -0
- wagtail/contrib/frontend_cache/backends/azure.py +179 -0
- wagtail/contrib/frontend_cache/backends/base.py +28 -0
- wagtail/contrib/frontend_cache/backends/cloudflare.py +114 -0
- wagtail/contrib/frontend_cache/backends/cloudfront.py +99 -0
- wagtail/contrib/frontend_cache/backends/http.py +64 -0
- wagtail/contrib/frontend_cache/tests.py +59 -17
- wagtail/contrib/frontend_cache/utils.py +26 -8
- wagtail/contrib/redirects/filters.py +15 -1
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +37 -72
- wagtail/contrib/redirects/models.py +6 -5
- wagtail/contrib/redirects/templates/wagtailredirects/edit.html +1 -38
- wagtail/contrib/redirects/tests/test_redirects.py +141 -1
- wagtail/contrib/redirects/urls.py +1 -2
- wagtail/contrib/redirects/views.py +39 -80
- wagtail/contrib/routable_page/models.py +6 -4
- wagtail/contrib/routable_page/tests.py +11 -0
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +5 -1
- wagtail/contrib/simple_translation/models.py +2 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/typed_table_block/blocks.py +19 -0
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/contrib/typed_table_block/tests.py +38 -0
- wagtail/coreutils.py +1 -1
- wagtail/documents/__init__.py +1 -1
- wagtail/documents/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sl/LC_MESSAGES/django.po +20 -0
- wagtail/documents/models.py +5 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
- wagtail/documents/tests/test_models.py +5 -1
- wagtail/embeds/apps.py +2 -0
- wagtail/embeds/embeds.py +12 -14
- wagtail/embeds/finders/__init__.py +2 -0
- wagtail/embeds/finders/facebook.py +17 -33
- wagtail/embeds/finders/instagram.py +19 -16
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/signal_handlers.py +13 -0
- wagtail/embeds/tests/test_embeds.py +7 -7
- wagtail/fields.py +58 -14
- wagtail/images/__init__.py +1 -1
- wagtail/images/locale/en/LC_MESSAGES/django.po +34 -34
- wagtail/images/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/sl/LC_MESSAGES/django.po +20 -0
- wagtail/images/models.py +2 -0
- wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
- wagtail/images/templates/wagtailimages/images/edit.html +4 -4
- wagtail/images/tests/test_admin_views.py +26 -2
- wagtail/images/views/chooser.py +6 -1
- wagtail/locale/en/LC_MESSAGES/django.po +84 -80
- wagtail/locales/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/locales/tests.py +16 -0
- wagtail/locales/wagtail_hooks.py +0 -9
- wagtail/migrations/0094_alter_page_locale.py +19 -0
- wagtail/models/__init__.py +11 -5
- wagtail/models/i18n.py +6 -1
- wagtail/project_template/requirements.txt +1 -1
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/signals.py +4 -0
- wagtail/sites/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/sites/tests.py +15 -0
- wagtail/sites/wagtail_hooks.py +0 -9
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +9 -9
- wagtail/snippets/permissions.py +5 -3
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -1
- wagtail/snippets/tests/test_snippets.py +78 -12
- wagtail/snippets/tests/test_viewset.py +22 -0
- wagtail/snippets/views/snippets.py +19 -14
- wagtail/snippets/wagtail_hooks.py +2 -10
- wagtail/templatetags/wagtailcore_tags.py +3 -0
- wagtail/test/dummy_external_storage.py +1 -1
- wagtail/test/i18n/migrations/0003_alter_clusterabletestmodel_locale_and_more.py +40 -0
- wagtail/test/routablepage/models.py +4 -0
- wagtail/test/snippets/migrations/0012_alter_translatablesnippet_locale.py +20 -0
- wagtail/test/testapp/migrations/0038_sociallink.py +52 -0
- wagtail/test/testapp/migrations/0039_alter_eventcategory_locale_and_more.py +45 -0
- wagtail/test/testapp/models.py +24 -0
- wagtail/test/testapp/views.py +1 -0
- wagtail/test/testapp/wagtail_hooks.py +9 -0
- wagtail/test/urls_multilang.py +6 -1
- wagtail/test/urls_multilang_non_root.py +11 -0
- wagtail/tests/streamfield_migrations/test_migrations.py +53 -12
- wagtail/tests/test_audit_log.py +72 -2
- wagtail/tests/test_blocks.py +103 -0
- wagtail/tests/test_signals.py +49 -2
- wagtail/tests/test_streamfield.py +153 -0
- wagtail/tests/test_utils.py +14 -0
- wagtail/tests/tests.py +5 -0
- wagtail/users/apps.py +1 -0
- wagtail/users/forms.py +7 -0
- wagtail/users/locale/en/LC_MESSAGES/django.po +55 -50
- wagtail/users/models.py +1 -0
- wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +3 -2
- wagtail/users/templatetags/wagtailusers_tags.py +9 -0
- wagtail/users/tests/__init__.py +7 -1
- wagtail/users/tests/test_admin_views.py +117 -32
- wagtail/users/views/groups.py +4 -0
- wagtail/users/views/users.py +58 -14
- wagtail/users/wagtail_hooks.py +7 -123
- wagtail/utils/utils.py +1 -0
- wagtail/utils/version.py +5 -2
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/METADATA +3 -3
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/RECORD +248 -222
- wagtail/admin/templates/wagtailadmin/reports/aging_pages.html +0 -58
- wagtail/admin/templates/wagtailadmin/reports/page_types_usage.html +0 -18
- wagtail/admin/templates/wagtailadmin/reports/site_history.html +0 -57
- wagtail/admin/templates/wagtailadmin/reports/workflow.html +0 -81
- wagtail/admin/templates/wagtailadmin/reports/workflow_tasks.html +0 -63
- wagtail/contrib/frontend_cache/backends.py +0 -400
- wagtail/contrib/redirects/templates/wagtailredirects/list.html +0 -43
- wagtail/contrib/redirects/templates/wagtailredirects/reports/redirects_report.html +0 -14
- wagtail/contrib/redirects/tests/test_reports_view.py +0 -82
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/top_level.txt +0 -0
|
@@ -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-
|
|
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"
|
|
@@ -22,20 +22,19 @@ msgstr ""
|
|
|
22
22
|
msgid "Wagtail redirects"
|
|
23
23
|
msgstr ""
|
|
24
24
|
|
|
25
|
-
#: filters.py:
|
|
26
|
-
#: views.py:466
|
|
25
|
+
#: filters.py:26 views.py:102 views.py:119
|
|
27
26
|
msgid "Type"
|
|
28
27
|
msgstr ""
|
|
29
28
|
|
|
30
|
-
#: filters.py:
|
|
29
|
+
#: filters.py:29
|
|
31
30
|
msgid "Permanent"
|
|
32
31
|
msgstr ""
|
|
33
32
|
|
|
34
|
-
#: filters.py:
|
|
33
|
+
#: filters.py:30
|
|
35
34
|
msgid "Temporary"
|
|
36
35
|
msgstr ""
|
|
37
36
|
|
|
38
|
-
#: filters.py:
|
|
37
|
+
#: filters.py:32
|
|
39
38
|
msgid "All"
|
|
40
39
|
msgstr ""
|
|
41
40
|
|
|
@@ -68,59 +67,59 @@ msgstr ""
|
|
|
68
67
|
msgid "To field"
|
|
69
68
|
msgstr ""
|
|
70
69
|
|
|
71
|
-
#: models.py:
|
|
70
|
+
#: models.py:13
|
|
72
71
|
msgid "redirect from"
|
|
73
72
|
msgstr ""
|
|
74
73
|
|
|
75
|
-
#: models.py:
|
|
74
|
+
#: models.py:17
|
|
76
75
|
msgid "site"
|
|
77
76
|
msgstr ""
|
|
78
77
|
|
|
79
|
-
#: models.py:
|
|
78
|
+
#: models.py:25 models.py:85
|
|
80
79
|
msgid "permanent"
|
|
81
80
|
msgstr ""
|
|
82
81
|
|
|
83
|
-
#: models.py:
|
|
82
|
+
#: models.py:28
|
|
84
83
|
msgid ""
|
|
85
84
|
"Recommended. Permanent redirects ensure search engines forget the old page "
|
|
86
85
|
"(the 'Redirect from') and index the new page instead."
|
|
87
86
|
msgstr ""
|
|
88
87
|
|
|
89
|
-
#: models.py:
|
|
88
|
+
#: models.py:34
|
|
90
89
|
msgid "redirect to a page"
|
|
91
90
|
msgstr ""
|
|
92
91
|
|
|
93
|
-
#: models.py:
|
|
92
|
+
#: models.py:40
|
|
94
93
|
msgid "target page route"
|
|
95
94
|
msgstr ""
|
|
96
95
|
|
|
97
|
-
#: models.py:
|
|
96
|
+
#: models.py:42
|
|
98
97
|
msgid ""
|
|
99
98
|
"Optionally specify a route on the target page to redirect to. Leave blank to "
|
|
100
99
|
"redirect to the default page route."
|
|
101
100
|
msgstr ""
|
|
102
101
|
|
|
103
|
-
#: models.py:
|
|
102
|
+
#: models.py:49
|
|
104
103
|
msgid "redirect to any URL"
|
|
105
104
|
msgstr ""
|
|
106
105
|
|
|
107
|
-
#: models.py:
|
|
106
|
+
#: models.py:52
|
|
108
107
|
msgid "automatically created"
|
|
109
108
|
msgstr ""
|
|
110
109
|
|
|
111
|
-
#: models.py:
|
|
110
|
+
#: models.py:57
|
|
112
111
|
msgid "created at"
|
|
113
112
|
msgstr ""
|
|
114
113
|
|
|
115
|
-
#: models.py:
|
|
114
|
+
#: models.py:87
|
|
116
115
|
msgid "temporary"
|
|
117
116
|
msgstr ""
|
|
118
117
|
|
|
119
|
-
#: models.py:
|
|
118
|
+
#: models.py:204
|
|
120
119
|
msgid "redirect"
|
|
121
120
|
msgstr ""
|
|
122
121
|
|
|
123
|
-
#: models.py:
|
|
122
|
+
#: models.py:205
|
|
124
123
|
msgid "redirects"
|
|
125
124
|
msgstr ""
|
|
126
125
|
|
|
@@ -130,7 +129,6 @@ msgid "Add redirect"
|
|
|
130
129
|
msgstr ""
|
|
131
130
|
|
|
132
131
|
#: templates/wagtailredirects/add.html:19
|
|
133
|
-
#: templates/wagtailredirects/edit.html:19
|
|
134
132
|
msgid "Save"
|
|
135
133
|
msgstr ""
|
|
136
134
|
|
|
@@ -141,7 +139,7 @@ msgstr ""
|
|
|
141
139
|
|
|
142
140
|
#: templates/wagtailredirects/choose_import_file.html:6
|
|
143
141
|
#: templates/wagtailredirects/confirm_import.html:6
|
|
144
|
-
#: templates/wagtailredirects/import_summary.html:5 views.py:
|
|
142
|
+
#: templates/wagtailredirects/import_summary.html:5 views.py:130
|
|
145
143
|
msgid "Import redirects"
|
|
146
144
|
msgstr ""
|
|
147
145
|
|
|
@@ -191,19 +189,6 @@ msgstr ""
|
|
|
191
189
|
msgid "Preview"
|
|
192
190
|
msgstr ""
|
|
193
191
|
|
|
194
|
-
#: templates/wagtailredirects/edit.html:3
|
|
195
|
-
#, python-format
|
|
196
|
-
msgid "Editing %(title)s"
|
|
197
|
-
msgstr ""
|
|
198
|
-
|
|
199
|
-
#: templates/wagtailredirects/edit.html:5
|
|
200
|
-
msgid "Editing"
|
|
201
|
-
msgstr ""
|
|
202
|
-
|
|
203
|
-
#: templates/wagtailredirects/edit.html:21
|
|
204
|
-
msgid "Delete redirect"
|
|
205
|
-
msgstr ""
|
|
206
|
-
|
|
207
192
|
#: templates/wagtailredirects/import_summary.html:3
|
|
208
193
|
#: templates/wagtailredirects/import_summary.html:6
|
|
209
194
|
msgid "Summary"
|
|
@@ -215,14 +200,11 @@ msgid ""
|
|
|
215
200
|
"Found %(total)s redirects, created %(successes)s and found %(errors)s errors."
|
|
216
201
|
msgstr ""
|
|
217
202
|
|
|
218
|
-
#: templates/wagtailredirects/import_summary.html:17
|
|
219
|
-
#: templates/wagtailredirects/list.html:12
|
|
220
|
-
#: templates/wagtailredirects/list.html:15 views.py:84 views.py:463
|
|
203
|
+
#: templates/wagtailredirects/import_summary.html:17 views.py:84 views.py:116
|
|
221
204
|
msgid "From"
|
|
222
205
|
msgstr ""
|
|
223
206
|
|
|
224
|
-
#: templates/wagtailredirects/import_summary.html:18
|
|
225
|
-
#: templates/wagtailredirects/list.html:19 views.py:96 views.py:465
|
|
207
|
+
#: templates/wagtailredirects/import_summary.html:18 views.py:96 views.py:118
|
|
226
208
|
msgid "To"
|
|
227
209
|
msgstr ""
|
|
228
210
|
|
|
@@ -246,76 +228,59 @@ msgid ""
|
|
|
246
228
|
"href=\"%(wagtailredirects_add_redirect_url)s\">add one</a>?"
|
|
247
229
|
msgstr ""
|
|
248
230
|
|
|
249
|
-
#:
|
|
231
|
+
#: views.py:90 views.py:117
|
|
250
232
|
msgid "Site"
|
|
251
233
|
msgstr ""
|
|
252
234
|
|
|
253
|
-
#:
|
|
254
|
-
msgid "
|
|
255
|
-
msgstr ""
|
|
256
|
-
|
|
257
|
-
#: templates/wagtailredirects/reports/redirects_report.html:8
|
|
258
|
-
#: templates/wagtailredirects/reports/redirects_report.html:13
|
|
259
|
-
msgid "No redirects found."
|
|
260
|
-
msgstr ""
|
|
261
|
-
|
|
262
|
-
#: views.py:122
|
|
263
|
-
msgid "Export redirects"
|
|
235
|
+
#: views.py:148
|
|
236
|
+
msgid "The redirect could not be saved due to errors."
|
|
264
237
|
msgstr ""
|
|
265
238
|
|
|
266
|
-
#: views.py:
|
|
239
|
+
#: views.py:153
|
|
267
240
|
#, python-format
|
|
268
241
|
msgid "Redirect '%(redirect_title)s' updated."
|
|
269
242
|
msgstr ""
|
|
270
243
|
|
|
271
|
-
#: views.py:
|
|
272
|
-
msgid "Edit"
|
|
273
|
-
msgstr ""
|
|
274
|
-
|
|
275
|
-
#: views.py:158
|
|
276
|
-
msgid "The redirect could not be saved due to errors."
|
|
277
|
-
msgstr ""
|
|
278
|
-
|
|
279
|
-
#: views.py:190
|
|
244
|
+
#: views.py:173
|
|
280
245
|
#, python-format
|
|
281
246
|
msgid "Redirect '%(redirect_title)s' deleted."
|
|
282
247
|
msgstr ""
|
|
283
248
|
|
|
284
|
-
#: views.py:
|
|
249
|
+
#: views.py:198
|
|
285
250
|
#, python-format
|
|
286
251
|
msgid "Redirect '%(redirect_title)s' added."
|
|
287
252
|
msgstr ""
|
|
288
253
|
|
|
289
|
-
#: views.py:
|
|
254
|
+
#: views.py:203
|
|
255
|
+
msgid "Edit"
|
|
256
|
+
msgstr ""
|
|
257
|
+
|
|
258
|
+
#: views.py:210
|
|
290
259
|
msgid "The redirect could not be created due to errors."
|
|
291
260
|
msgstr ""
|
|
292
261
|
|
|
293
|
-
#: views.py:
|
|
262
|
+
#: views.py:249
|
|
294
263
|
msgid "Search redirects"
|
|
295
264
|
msgstr ""
|
|
296
265
|
|
|
297
|
-
#: views.py:
|
|
266
|
+
#: views.py:263
|
|
298
267
|
#, python-format
|
|
299
268
|
msgid "File format of type \"%(extension)s\" is not supported"
|
|
300
269
|
msgstr ""
|
|
301
270
|
|
|
302
|
-
#: views.py:
|
|
271
|
+
#: views.py:280
|
|
303
272
|
#, python-format
|
|
304
273
|
msgid "Imported file has a wrong encoding: %(error_message)s"
|
|
305
274
|
msgstr ""
|
|
306
275
|
|
|
307
|
-
#: views.py:
|
|
276
|
+
#: views.py:287
|
|
308
277
|
#, python-format
|
|
309
278
|
msgid "%(error)s encountered while trying to read file: %(filename)s"
|
|
310
279
|
msgstr ""
|
|
311
280
|
|
|
312
|
-
#: views.py:
|
|
281
|
+
#: views.py:378
|
|
313
282
|
#, python-format
|
|
314
283
|
msgid "Imported %(total)d redirect"
|
|
315
284
|
msgid_plural "Imported %(total)d redirects"
|
|
316
285
|
msgstr[0] ""
|
|
317
286
|
msgstr[1] ""
|
|
318
|
-
|
|
319
|
-
#: views.py:451
|
|
320
|
-
msgid "Export Redirects"
|
|
321
|
-
msgstr ""
|
|
@@ -2,6 +2,7 @@ from urllib.parse import urlparse
|
|
|
2
2
|
|
|
3
3
|
from django.db import models
|
|
4
4
|
from django.urls import Resolver404
|
|
5
|
+
from django.utils.functional import cached_property
|
|
5
6
|
from django.utils.translation import gettext_lazy as _
|
|
6
7
|
|
|
7
8
|
from wagtail.models import Page
|
|
@@ -63,10 +64,10 @@ class Redirect(models.Model):
|
|
|
63
64
|
def __str__(self):
|
|
64
65
|
return self.title
|
|
65
66
|
|
|
66
|
-
@
|
|
67
|
+
@cached_property
|
|
67
68
|
def link(self):
|
|
68
69
|
if self.redirect_page:
|
|
69
|
-
page = self.redirect_page.
|
|
70
|
+
page = self.redirect_page.specific_deferred
|
|
70
71
|
base_url = page.url
|
|
71
72
|
if not self.redirect_page_route_path:
|
|
72
73
|
return base_url
|
|
@@ -145,7 +146,7 @@ class Redirect(models.Model):
|
|
|
145
146
|
url_parsed = urlparse(url)
|
|
146
147
|
|
|
147
148
|
# Path must start with / but not end with /
|
|
148
|
-
path = url_parsed
|
|
149
|
+
path = url_parsed.path
|
|
149
150
|
if not path.startswith("/"):
|
|
150
151
|
path = "/" + path
|
|
151
152
|
|
|
@@ -153,12 +154,12 @@ class Redirect(models.Model):
|
|
|
153
154
|
path = path[:-1]
|
|
154
155
|
|
|
155
156
|
# Parameters must be sorted alphabetically
|
|
156
|
-
parameters = url_parsed
|
|
157
|
+
parameters = url_parsed.params
|
|
157
158
|
parameters_components = parameters.split(";")
|
|
158
159
|
parameters = ";".join(sorted(parameters_components))
|
|
159
160
|
|
|
160
161
|
# Query string components must be sorted alphabetically
|
|
161
|
-
query_string = url_parsed
|
|
162
|
+
query_string = url_parsed.query
|
|
162
163
|
query_string_components = query_string.split("&")
|
|
163
164
|
query_string = "&".join(sorted(query_string_components))
|
|
164
165
|
|
|
@@ -1,38 +1 @@
|
|
|
1
|
-
{% extends "wagtailadmin/
|
|
2
|
-
{% load i18n wagtailadmin_tags %}
|
|
3
|
-
{% block titletag %}{% blocktrans trimmed with title=redirect.title %}Editing {{ title }}{% endblocktrans %}{% endblock %}
|
|
4
|
-
{% block content %}
|
|
5
|
-
{% trans "Editing" as editing_str %}
|
|
6
|
-
{% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=redirect.title icon="redirect" %}
|
|
7
|
-
|
|
8
|
-
{% include "wagtailadmin/shared/non_field_errors.html" %}
|
|
9
|
-
|
|
10
|
-
<form action="{% url 'wagtailredirects:edit' redirect.id %}" method="POST" class="nice-padding" novalidate>
|
|
11
|
-
{% csrf_token %}
|
|
12
|
-
|
|
13
|
-
<ul class="fields">
|
|
14
|
-
{% for field in form.visible_fields %}
|
|
15
|
-
<li>{% formattedfield field %}</li>
|
|
16
|
-
{% endfor %}
|
|
17
|
-
|
|
18
|
-
<li>
|
|
19
|
-
<input type="submit" value="{% trans 'Save' %}" class="button" />
|
|
20
|
-
{% if user_can_delete %}
|
|
21
|
-
<a href="{% url 'wagtailredirects:delete' redirect.id %}" class="button no">{% trans "Delete redirect" %}</a>
|
|
22
|
-
{% endif %}
|
|
23
|
-
</li>
|
|
24
|
-
</ul>
|
|
25
|
-
</form>
|
|
26
|
-
|
|
27
|
-
{% endblock %}
|
|
28
|
-
|
|
29
|
-
{% block extra_js %}
|
|
30
|
-
{{ block.super }}
|
|
31
|
-
{% include "wagtailadmin/pages/_editor_js.html" %}
|
|
32
|
-
{{ form.media.js }}
|
|
33
|
-
{% endblock %}
|
|
34
|
-
|
|
35
|
-
{% block extra_css %}
|
|
36
|
-
{{ block.super }}
|
|
37
|
-
{{ form.media.css }}
|
|
38
|
-
{% endblock %}
|
|
1
|
+
{% extends "wagtailadmin/generic/edit.html" %}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
1
3
|
from django.conf import settings
|
|
4
|
+
from django.contrib.auth.models import Permission
|
|
2
5
|
from django.test import TestCase, override_settings
|
|
3
6
|
from django.urls import reverse
|
|
7
|
+
from openpyxl.reader.excel import load_workbook
|
|
4
8
|
|
|
5
9
|
from wagtail.admin.admin_url_finder import AdminURLFinder
|
|
6
10
|
from wagtail.contrib.redirects import models
|
|
@@ -592,7 +596,14 @@ class TestRedirects(TestCase):
|
|
|
592
596
|
self.assertIs(redirect.is_permanent, True)
|
|
593
597
|
|
|
594
598
|
|
|
599
|
+
@override_settings(
|
|
600
|
+
CACHES={"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"}}
|
|
601
|
+
)
|
|
595
602
|
class TestRedirectsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
603
|
+
@classmethod
|
|
604
|
+
def setUpTestData(cls):
|
|
605
|
+
cls.site = Site.objects.first()
|
|
606
|
+
|
|
596
607
|
def setUp(self):
|
|
597
608
|
self.login()
|
|
598
609
|
|
|
@@ -607,6 +618,7 @@ class TestRedirectsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
|
|
|
607
618
|
[{"url": "", "label": "Redirects"}],
|
|
608
619
|
response.content,
|
|
609
620
|
)
|
|
621
|
+
self.assertContains(response, "No redirects have been created")
|
|
610
622
|
|
|
611
623
|
def test_search(self):
|
|
612
624
|
models.Redirect.objects.create(
|
|
@@ -692,6 +704,94 @@ class TestRedirectsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
|
|
|
692
704
|
(ordering,),
|
|
693
705
|
)
|
|
694
706
|
|
|
707
|
+
def test_filtering_by_type(self):
|
|
708
|
+
temp_redirect = models.Redirect.add_redirect("/from", "/to", False)
|
|
709
|
+
perm_redirect = models.Redirect.add_redirect("/cat", "/dog", True)
|
|
710
|
+
|
|
711
|
+
response = self.get(params={"is_permanent": "True"})
|
|
712
|
+
|
|
713
|
+
self.assertContains(response, perm_redirect.old_path)
|
|
714
|
+
self.assertNotContains(response, temp_redirect.old_path)
|
|
715
|
+
|
|
716
|
+
def test_filtering_by_site(self):
|
|
717
|
+
site_redirect = models.Redirect.add_redirect("/cat", "/dog")
|
|
718
|
+
site_redirect.site = self.site
|
|
719
|
+
site_redirect.save()
|
|
720
|
+
nosite_redirect = models.Redirect.add_redirect("/from", "/to")
|
|
721
|
+
|
|
722
|
+
response = self.get(params={"site": self.site.pk})
|
|
723
|
+
|
|
724
|
+
self.assertContains(response, site_redirect.old_path)
|
|
725
|
+
self.assertNotContains(response, nosite_redirect.old_path)
|
|
726
|
+
|
|
727
|
+
def test_csv_export(self):
|
|
728
|
+
models.Redirect.add_redirect("/from", "/to", False)
|
|
729
|
+
|
|
730
|
+
# Session, User, UserProfile, Redirects
|
|
731
|
+
with self.assertNumQueries(4):
|
|
732
|
+
response = self.get(params={"export": "csv"})
|
|
733
|
+
|
|
734
|
+
csv_data = response.getvalue().decode().split("\n")
|
|
735
|
+
|
|
736
|
+
self.assertEqual(response.status_code, 200)
|
|
737
|
+
csv_header = csv_data[0]
|
|
738
|
+
csv_entries = csv_data[1:]
|
|
739
|
+
csv_entries = csv_entries[:-1] # Drop empty last line
|
|
740
|
+
|
|
741
|
+
self.assertEqual(csv_header, "From,To,Type,Site\r")
|
|
742
|
+
self.assertEqual(len(csv_entries), 1)
|
|
743
|
+
self.assertEqual(csv_entries[0], "/from,/to,temporary,\r")
|
|
744
|
+
|
|
745
|
+
def test_xlsx_export(self):
|
|
746
|
+
models.Redirect.add_redirect("/from", "/to", True)
|
|
747
|
+
|
|
748
|
+
# Session, User, UserProfile, Redirects
|
|
749
|
+
with self.assertNumQueries(4):
|
|
750
|
+
response = self.get(params={"export": "xlsx"})
|
|
751
|
+
workbook_data = response.getvalue()
|
|
752
|
+
|
|
753
|
+
self.assertEqual(response.status_code, 200)
|
|
754
|
+
|
|
755
|
+
worksheet = load_workbook(filename=BytesIO(workbook_data))["Sheet1"]
|
|
756
|
+
cell_array = [[cell.value for cell in row] for row in worksheet.rows]
|
|
757
|
+
|
|
758
|
+
self.assertEqual(cell_array[0], ["From", "To", "Type", "Site"])
|
|
759
|
+
self.assertEqual(len(cell_array), 2)
|
|
760
|
+
self.assertEqual(cell_array[1], ["/from", "/to", "permanent", None])
|
|
761
|
+
|
|
762
|
+
def test_num_queries_in_export(self):
|
|
763
|
+
page = Page.objects.get(id=2)
|
|
764
|
+
for i in range(3):
|
|
765
|
+
models.Redirect.add_redirect(f"/from{i}", "/to", False)
|
|
766
|
+
models.Redirect.add_redirect(f"/from-site{i}", "/to", False, site=self.site)
|
|
767
|
+
models.Redirect.add_redirect(f"/to-page{i}", page, False)
|
|
768
|
+
|
|
769
|
+
response = self.get(params={"export": "csv"})
|
|
770
|
+
csv_data = response.getvalue().decode().strip().split("\n")
|
|
771
|
+
# Session, User, UserProfile, Redirects
|
|
772
|
+
with self.assertNumQueries(4):
|
|
773
|
+
response = self.get(params={"export": "csv"})
|
|
774
|
+
csv_data = response.getvalue().decode().strip().split("\n")
|
|
775
|
+
|
|
776
|
+
self.assertEqual(len(csv_data), 10)
|
|
777
|
+
|
|
778
|
+
def test_redirect_page_filter_only_includes_relevant_pages(self):
|
|
779
|
+
"""
|
|
780
|
+
The redirect_page filter should only include pages referenced by Redirect objects.
|
|
781
|
+
"""
|
|
782
|
+
response = self.get()
|
|
783
|
+
request = response.context["request"]
|
|
784
|
+
qs = response.context["filters"].filters["redirect_page"].queryset(request)
|
|
785
|
+
self.assertQuerySetEqual(qs, Page.objects.none())
|
|
786
|
+
|
|
787
|
+
page = Page.objects.get(id=2)
|
|
788
|
+
models.Redirect.add_redirect("/to-page", page, False)
|
|
789
|
+
|
|
790
|
+
response = self.get()
|
|
791
|
+
request = response.context["request"]
|
|
792
|
+
qs = response.context["filters"].filters["redirect_page"].queryset(request)
|
|
793
|
+
self.assertQuerySetEqual(qs, Page.objects.filter(pk=2))
|
|
794
|
+
|
|
695
795
|
|
|
696
796
|
class TestRedirectsAddView(WagtailTestUtils, TestCase):
|
|
697
797
|
fixtures = ["test.json"]
|
|
@@ -849,7 +949,7 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
|
|
|
849
949
|
self.assertIsNone(redirects.first().site)
|
|
850
950
|
|
|
851
951
|
|
|
852
|
-
class TestRedirectsEditView(WagtailTestUtils, TestCase):
|
|
952
|
+
class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
853
953
|
def setUp(self):
|
|
854
954
|
# Create a redirect to edit
|
|
855
955
|
self.redirect = models.Redirect(
|
|
@@ -876,6 +976,13 @@ class TestRedirectsEditView(WagtailTestUtils, TestCase):
|
|
|
876
976
|
response = self.get()
|
|
877
977
|
self.assertEqual(response.status_code, 200)
|
|
878
978
|
self.assertTemplateUsed(response, "wagtailredirects/edit.html")
|
|
979
|
+
self.assertBreadcrumbsItemsRendered(
|
|
980
|
+
[
|
|
981
|
+
{"url": reverse("wagtailredirects:index"), "label": "Redirects"},
|
|
982
|
+
{"url": "", "label": "/test"},
|
|
983
|
+
],
|
|
984
|
+
response.content,
|
|
985
|
+
)
|
|
879
986
|
|
|
880
987
|
url_finder = AdminURLFinder(self.user)
|
|
881
988
|
expected_url = "/admin/redirects/%d/" % self.redirect.id
|
|
@@ -957,6 +1064,39 @@ class TestRedirectsEditView(WagtailTestUtils, TestCase):
|
|
|
957
1064
|
# Should not redirect to index
|
|
958
1065
|
self.assertEqual(response.status_code, 200)
|
|
959
1066
|
|
|
1067
|
+
def test_get_with_no_permission(self, redirect_id=None):
|
|
1068
|
+
self.user.is_superuser = False
|
|
1069
|
+
self.user.save()
|
|
1070
|
+
# Only basic access_admin permission is given
|
|
1071
|
+
self.user.user_permissions.add(
|
|
1072
|
+
Permission.objects.get(
|
|
1073
|
+
content_type__app_label="wagtailadmin",
|
|
1074
|
+
codename="access_admin",
|
|
1075
|
+
)
|
|
1076
|
+
)
|
|
1077
|
+
|
|
1078
|
+
response = self.get()
|
|
1079
|
+
self.assertEqual(response.status_code, 302)
|
|
1080
|
+
self.assertRedirects(response, reverse("wagtailadmin_home"))
|
|
1081
|
+
|
|
1082
|
+
def test_get_with_edit_permission_only(self):
|
|
1083
|
+
self.user.is_superuser = False
|
|
1084
|
+
self.user.save()
|
|
1085
|
+
self.user.user_permissions.add(
|
|
1086
|
+
Permission.objects.get(
|
|
1087
|
+
content_type__app_label="wagtailadmin",
|
|
1088
|
+
codename="access_admin",
|
|
1089
|
+
),
|
|
1090
|
+
Permission.objects.get(
|
|
1091
|
+
content_type__app_label="wagtailredirects",
|
|
1092
|
+
codename="change_redirect",
|
|
1093
|
+
),
|
|
1094
|
+
)
|
|
1095
|
+
|
|
1096
|
+
response = self.get()
|
|
1097
|
+
self.assertEqual(response.status_code, 200)
|
|
1098
|
+
self.assertTemplateUsed(response, "wagtailredirects/edit.html")
|
|
1099
|
+
|
|
960
1100
|
|
|
961
1101
|
class TestRedirectsDeleteView(WagtailTestUtils, TestCase):
|
|
962
1102
|
def setUp(self):
|
|
@@ -7,9 +7,8 @@ urlpatterns = [
|
|
|
7
7
|
path("", views.IndexView.as_view(), name="index"),
|
|
8
8
|
path("results/", views.IndexView.as_view(results_only=True), name="index_results"),
|
|
9
9
|
path("add/", views.add, name="add"),
|
|
10
|
-
path("<int:redirect_id>/", views.
|
|
10
|
+
path("<int:redirect_id>/", views.EditView.as_view(), name="edit"),
|
|
11
11
|
path("<int:redirect_id>/delete/", views.delete, name="delete"),
|
|
12
12
|
path("import/", views.start_import, name="start_import"),
|
|
13
13
|
path("import/process/", views.process_import, name="process_import"),
|
|
14
|
-
path("report", views.RedirectsReportView.as_view(), name="report"),
|
|
15
14
|
]
|