wagtail 6.3.2__py3-none-any.whl → 6.4rc1__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/publish_revision.py +4 -5
- wagtail/admin/auth.py +0 -2
- wagtail/admin/checks.py +1 -1
- wagtail/admin/filters.py +3 -1
- wagtail/admin/forms/account.py +21 -11
- wagtail/admin/forms/collections.py +2 -9
- wagtail/admin/forms/formsets.py +32 -0
- wagtail/admin/forms/pages.py +5 -1
- wagtail/admin/forms/workflows.py +2 -13
- wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/django.po +68 -1
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.po +5 -1
- wagtail/admin/locale/en/LC_MESSAGES/django.po +312 -356
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -16
- wagtail/admin/menu.py +0 -13
- wagtail/admin/panels/base.py +2 -2
- wagtail/admin/panels/group.py +4 -1
- wagtail/admin/panels/inline_panel.py +5 -2
- wagtail/admin/panels/model_utils.py +36 -0
- wagtail/admin/panels/page_utils.py +2 -40
- wagtail/admin/panels/signal_handlers.py +0 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/streamfield.css +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/core.js.LICENSE.txt +1 -8
- wagtail/admin/static/wagtailadmin/js/draftail.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/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +7 -0
- wagtail/admin/templates/wagtailadmin/404.html +4 -0
- wagtail/admin/templates/wagtailadmin/chooser/browse.html +2 -1
- wagtail/admin/templates/wagtailadmin/chooser/tables/parent_page_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/collections/_privacy_switch.html +8 -1
- wagtail/admin/templates/wagtailadmin/generic/confirm_delete.html +15 -9
- wagtail/admin/templates/wagtailadmin/generic/confirm_unpublish.html +21 -25
- wagtail/admin/templates/wagtailadmin/generic/form.html +1 -1
- wagtail/admin/templates/wagtailadmin/generic/preview_error.html +3 -0
- wagtail/admin/templates/wagtailadmin/generic/revisions/compare.html +63 -76
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -2
- wagtail/admin/templates/wagtailadmin/pages/edit.html +1 -5
- wagtail/admin/templates/wagtailadmin/panels/inline_panel_child.html +1 -0
- wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_form.html +1 -1
- wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +6 -22
- wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/header.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +32 -39
- wagtail/admin/templates/wagtailadmin/shared/revisions/confirm_unschedule.html +13 -17
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +15 -3
- wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +1 -1
- wagtail/admin/templates/wagtailadmin/skeleton.html +4 -2
- wagtail/admin/templates/wagtailadmin/workflows/create.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/edit.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_form.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_formset.html +6 -23
- wagtail/admin/templatetags/wagtailadmin_tags.py +12 -0
- wagtail/admin/templatetags/wagtailuserbar.py +2 -3
- wagtail/admin/tests/pages/test_create_page.py +110 -1
- wagtail/admin/tests/pages/test_edit_page.py +3 -2
- wagtail/admin/tests/pages/test_explorer_view.py +18 -0
- wagtail/admin/tests/pages/test_page_usage.py +24 -20
- wagtail/admin/tests/pages/test_preview.py +69 -1
- wagtail/admin/tests/pages/test_revisions.py +40 -6
- wagtail/admin/tests/test_account_management.py +39 -1
- wagtail/admin/tests/test_audit_log.py +4 -2
- wagtail/admin/tests/test_block_preview.py +224 -0
- wagtail/admin/tests/test_edit_handlers.py +23 -6
- wagtail/admin/tests/test_page_chooser.py +50 -3
- wagtail/admin/tests/test_privacy.py +49 -26
- wagtail/admin/tests/test_site_summary.py +15 -10
- wagtail/admin/tests/test_templatetags.py +19 -0
- wagtail/admin/tests/test_userbar.py +82 -1
- wagtail/admin/tests/test_views_generic.py +27 -12
- wagtail/admin/tests/test_workflows.py +69 -0
- wagtail/admin/tests/tests.py +23 -4
- wagtail/admin/tests/ui/test_sidebar.py +1 -1
- wagtail/admin/tests/viewsets/test_model_viewset.py +15 -13
- wagtail/admin/ui/side_panels.py +7 -4
- wagtail/admin/urls/__init__.py +6 -0
- wagtail/admin/urls/pages.py +1 -1
- wagtail/admin/userbar.py +21 -1
- wagtail/admin/views/account.py +5 -0
- wagtail/admin/views/chooser.py +5 -1
- wagtail/admin/views/collections.py +0 -2
- wagtail/admin/views/generic/base.py +20 -10
- wagtail/admin/views/generic/history.py +0 -1
- wagtail/admin/views/generic/models.py +79 -21
- wagtail/admin/views/generic/preview.py +50 -1
- wagtail/admin/views/mixins.py +4 -2
- wagtail/admin/views/pages/bulk_actions/delete.py +11 -23
- wagtail/admin/views/pages/bulk_actions/page_bulk_action.py +17 -0
- wagtail/admin/views/pages/bulk_actions/publish.py +11 -31
- wagtail/admin/views/pages/bulk_actions/unpublish.py +11 -31
- wagtail/admin/views/pages/create.py +1 -0
- wagtail/admin/views/pages/edit.py +38 -30
- wagtail/admin/views/pages/revisions.py +43 -114
- wagtail/admin/views/pages/utils.py +0 -1
- wagtail/admin/views/tags.py +6 -2
- wagtail/admin/views/workflows.py +8 -6
- wagtail/admin/viewsets/model.py +0 -4
- wagtail/admin/viewsets/pages.py +0 -1
- wagtail/admin/widgets/tags.py +1 -0
- wagtail/api/v2/tests/test_documents.py +4 -2
- wagtail/api/v2/tests/test_images.py +4 -2
- wagtail/api/v2/tests/test_pages.py +8 -4
- wagtail/blocks/base.py +59 -1
- wagtail/blocks/field_block.py +6 -0
- wagtail/blocks/list_block.py +4 -0
- wagtail/blocks/static_block.py +3 -0
- wagtail/blocks/stream_block.py +5 -1
- wagtail/blocks/struct_block.py +6 -0
- wagtail/compat.py +16 -0
- wagtail/contrib/forms/forms.py +27 -7
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/forms/tests/test_models.py +7 -5
- wagtail/contrib/forms/tests/test_views.py +75 -0
- wagtail/contrib/frontend_cache/tasks.py +83 -0
- wagtail/contrib/frontend_cache/tests.py +47 -32
- wagtail/contrib/frontend_cache/utils.py +2 -70
- wagtail/contrib/redirects/base_formats.py +2 -2
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +3 -0
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +24 -37
- wagtail/contrib/redirects/templates/wagtailredirects/add.html +1 -24
- wagtail/contrib/redirects/templates/wagtailredirects/confirm_delete.html +3 -13
- wagtail/contrib/redirects/tests/test_redirects.py +122 -110
- wagtail/contrib/redirects/tests/test_signal_handlers.py +75 -69
- wagtail/contrib/redirects/urls.py +2 -2
- wagtail/contrib/redirects/views.py +35 -73
- wagtail/contrib/search_promotions/admin_urls.py +10 -3
- wagtail/contrib/search_promotions/forms.py +55 -26
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +44 -54
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/add.html +21 -31
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/confirm_delete.html +3 -12
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/edit.html +11 -34
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotion_form.html +1 -0
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js +2 -1
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +0 -1
- wagtail/contrib/search_promotions/tests.py +814 -13
- wagtail/contrib/search_promotions/views/__init__.py +1 -0
- wagtail/contrib/search_promotions/views/reports.py +56 -0
- wagtail/contrib/search_promotions/views/settings.py +258 -0
- wagtail/contrib/search_promotions/wagtail_hooks.py +12 -1
- wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/settings/templates/wagtailsettings/edit.html +1 -5
- wagtail/contrib/settings/tests/generic/test_admin.py +2 -5
- wagtail/contrib/settings/tests/generic/test_register.py +1 -1
- wagtail/contrib/settings/tests/site_specific/test_admin.py +2 -5
- wagtail/contrib/settings/tests/site_specific/test_register.py +1 -1
- wagtail/contrib/settings/views.py +9 -23
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/tests.py +4 -1
- wagtail/contrib/typed_table_block/blocks.py +3 -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 +33 -0
- wagtail/documents/locale/en/LC_MESSAGES/django.po +26 -26
- wagtail/documents/migrations/0011_add_choose_permissions.py +1 -0
- wagtail/documents/models.py +1 -0
- wagtail/documents/signal_handlers.py +6 -2
- wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
- wagtail/documents/templates/wagtaildocs/documents/edit.html +1 -3
- wagtail/documents/templates/wagtaildocs/multiple/add.html +7 -1
- wagtail/documents/tests/test_admin_views.py +74 -33
- wagtail/documents/tests/test_views.py +21 -12
- wagtail/documents/views/chooser.py +1 -0
- wagtail/documents/views/documents.py +1 -2
- wagtail/documents/views/multiple.py +0 -1
- wagtail/documents/views/serve.py +9 -2
- wagtail/documents/wagtail_hooks.py +6 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/oembed_providers.py +0 -64
- wagtail/fields.py +3 -0
- wagtail/images/apps.py +2 -1
- wagtail/images/blocks.py +6 -2
- wagtail/images/forms.py +40 -3
- wagtail/images/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ar/LC_MESSAGES/django.po +4 -0
- wagtail/images/locale/en/LC_MESSAGES/django.po +49 -49
- wagtail/images/migrations/0023_add_choose_permissions.py +1 -0
- wagtail/images/rich_text/contentstate.py +1 -0
- wagtail/images/rich_text/editor_html.py +1 -0
- wagtail/images/signal_handlers.py +17 -10
- wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
- wagtail/images/static/wagtailimages/js/image-block.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/static/wagtailimages/js/image-url-generator.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
- wagtail/images/tasks.py +18 -0
- wagtail/images/templates/wagtailimages/images/edit.html +1 -3
- wagtail/images/templates/wagtailimages/images/url_generator.html +1 -1
- wagtail/images/templates/wagtailimages/multiple/add.html +7 -2
- wagtail/images/templates/wagtailimages/widgets/image_chooser.html +1 -1
- wagtail/images/tests/test_admin_views.py +53 -29
- wagtail/images/tests/test_blocks.py +3 -2
- wagtail/images/tests/test_models.py +12 -10
- wagtail/images/tests/tests.py +10 -0
- wagtail/images/views/chooser.py +1 -0
- wagtail/images/views/images.py +1 -3
- wagtail/images/views/multiple.py +0 -1
- wagtail/images/views/serve.py +18 -2
- wagtail/images/widgets.py +3 -0
- wagtail/locale/en/LC_MESSAGES/django.po +228 -216
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/management/commands/publish_scheduled.py +1 -1
- wagtail/migrations/0087_alter_grouppagepermission_unique_together_and_more.py +16 -8
- wagtail/models/__init__.py +300 -119
- wagtail/models/i18n.py +2 -2
- wagtail/models/panels.py +37 -0
- wagtail/models/sites.py +7 -6
- wagtail/permission_policies/pages.py +2 -2
- wagtail/project_template/project_name/settings/base.py +4 -0
- wagtail/project_template/requirements.txt +1 -1
- wagtail/query.py +145 -0
- wagtail/search/backends/database/mysql/mysql.py +25 -17
- wagtail/search/backends/database/postgres/postgres.py +44 -83
- wagtail/search/backends/database/sqlite/sqlite.py +25 -17
- wagtail/search/backends/elasticsearch7.py +4 -0
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/search/query.py +8 -2
- wagtail/search/signal_handlers.py +6 -9
- wagtail/search/tasks.py +10 -0
- wagtail/search/tests/test_elasticsearch7_backend.py +21 -0
- wagtail/search/tests/test_index_functions.py +10 -6
- wagtail/search/tests/test_postgres_backend.py +0 -14
- wagtail/signal_handlers.py +5 -20
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -13
- wagtail/snippets/tests/test_preview.py +5 -0
- wagtail/snippets/tests/test_snippets.py +100 -45
- wagtail/snippets/tests/test_usage.py +29 -24
- wagtail/snippets/tests/test_viewset.py +1 -1
- wagtail/snippets/views/snippets.py +0 -12
- wagtail/tasks.py +41 -0
- wagtail/templates/wagtailcore/shared/block_preview.html +29 -0
- wagtail/test/earlypage/__init__.py +0 -0
- wagtail/test/earlypage/migrations/0001_initial.py +37 -0
- wagtail/test/earlypage/migrations/__init__.py +0 -0
- wagtail/test/earlypage/models.py +14 -0
- wagtail/test/settings.py +3 -0
- wagtail/test/testapp/fixtures/test.json +7 -0
- wagtail/test/testapp/fixtures/test_specific.json +6 -3
- wagtail/test/testapp/models.py +58 -44
- wagtail/test/testapp/templates/tests/custom_block_preview.html +16 -0
- wagtail/test/testapp/templates/tests/static_block_preview.html +5 -0
- wagtail/test/testapp/wagtail_hooks.py +9 -0
- wagtail/tests/test_blocks.py +189 -2
- wagtail/tests/test_hooks.py +166 -1
- wagtail/tests/test_management_commands.py +54 -13
- wagtail/tests/test_page_allowed_http_methods.py +32 -0
- wagtail/tests/test_page_model.py +68 -0
- wagtail/tests/test_page_privacy.py +10 -0
- wagtail/tests/test_page_queryset.py +79 -0
- wagtail/tests/test_reference_index.py +84 -75
- wagtail/tests/test_streamfield.py +30 -0
- wagtail/tests/test_utils.py +61 -0
- wagtail/users/forms.py +2 -9
- wagtail/users/locale/en/LC_MESSAGES/django.po +17 -17
- wagtail/users/templates/wagtailusers/groups/create.html +0 -5
- wagtail/users/templates/wagtailusers/groups/includes/page_permissions_form.html +1 -1
- wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.html +6 -6
- wagtail/users/tests/test_admin_views.py +96 -4
- wagtail/users/tests/test_utils.py +76 -0
- wagtail/users/utils.py +43 -11
- wagtail/utils/setup.py +2 -2
- wagtail/utils/templates.py +26 -0
- wagtail/utils/widgets.py +1 -0
- wagtail/views.py +9 -1
- wagtail/wagtail_hooks.py +67 -29
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/METADATA +2 -2
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/RECORD +289 -276
- wagtail/admin/static/wagtailadmin/js/expanding-formset.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/rangy-core.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/uuidv4.min.js +0 -1
- wagtail/contrib/search_promotions/views.py +0 -323
- wagtail/images/static/wagtailimages/js/vendor/canvas-to-blob.min.js +0 -1
- wagtail/users/static/wagtailusers/js/group-form.js +0 -1
- wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/top_level.txt +0 -0
|
@@ -1,30 +1,21 @@
|
|
|
1
|
-
from django.conf import settings
|
|
2
|
-
from django.contrib.contenttypes.models import ContentType
|
|
3
1
|
from django.core.exceptions import PermissionDenied
|
|
4
2
|
from django.shortcuts import get_object_or_404, redirect
|
|
5
3
|
from django.template.loader import render_to_string
|
|
6
|
-
from django.template.response import TemplateResponse
|
|
7
4
|
from django.urls import reverse
|
|
8
5
|
from django.utils.decorators import method_decorator
|
|
9
6
|
from django.utils.safestring import mark_safe
|
|
10
7
|
from django.utils.translation import gettext as _
|
|
11
|
-
from django.utils.translation import gettext_lazy
|
|
12
8
|
|
|
13
9
|
from wagtail.admin import messages
|
|
14
10
|
from wagtail.admin.action_menu import PageActionMenu
|
|
15
11
|
from wagtail.admin.auth import user_has_any_page_permission, user_passes_test
|
|
16
|
-
from wagtail.admin.ui.components import MediaContainer
|
|
17
|
-
from wagtail.admin.ui.side_panels import (
|
|
18
|
-
ChecksSidePanel,
|
|
19
|
-
CommentsSidePanel,
|
|
20
|
-
PageStatusSidePanel,
|
|
21
|
-
PreviewSidePanel,
|
|
22
|
-
)
|
|
23
12
|
from wagtail.admin.views.generic.models import (
|
|
24
13
|
RevisionsCompareView,
|
|
25
14
|
RevisionsUnscheduleView,
|
|
26
15
|
)
|
|
27
16
|
from wagtail.admin.views.generic.preview import PreviewRevision
|
|
17
|
+
from wagtail.admin.views.pages.edit import EditView
|
|
18
|
+
from wagtail.admin.views.pages.utils import GenericPageBreadcrumbsMixin
|
|
28
19
|
from wagtail.models import Page
|
|
29
20
|
from wagtail.utils.timestamps import render_timestamp
|
|
30
21
|
|
|
@@ -33,116 +24,55 @@ def revisions_index(request, page_id):
|
|
|
33
24
|
return redirect("wagtailadmin_pages:history", page_id)
|
|
34
25
|
|
|
35
26
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
page = get_object_or_404(Page, id=page_id).specific
|
|
39
|
-
page_perms = page.permissions_for_user(request.user)
|
|
40
|
-
if not page_perms.can_edit():
|
|
41
|
-
raise PermissionDenied
|
|
27
|
+
class RevisionsRevertView(EditView):
|
|
28
|
+
revisions_revert_url_name = "wagtailadmin_pages:revisions_revert"
|
|
42
29
|
|
|
43
|
-
|
|
44
|
-
|
|
30
|
+
def get_action_menu(self):
|
|
31
|
+
return PageActionMenu(
|
|
32
|
+
self.request,
|
|
33
|
+
view="revisions_revert",
|
|
34
|
+
is_revision=True,
|
|
35
|
+
page=self.page,
|
|
36
|
+
lock=self.lock,
|
|
37
|
+
locked_for_user=self.locked_for_user,
|
|
38
|
+
)
|
|
45
39
|
|
|
46
|
-
|
|
40
|
+
def get(self, request, *args, **kwargs):
|
|
41
|
+
self._add_warning_message()
|
|
42
|
+
return super().get(request, *args, **kwargs)
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
def _add_warning_message(self):
|
|
45
|
+
messages.warning(self.request, self.get_warning_message())
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
edit_handler = page_class.get_edit_handler()
|
|
68
|
-
form_class = edit_handler.get_form_class()
|
|
69
|
-
|
|
70
|
-
form = form_class(instance=revision_page, for_user=request.user)
|
|
71
|
-
edit_handler = edit_handler.get_bound_panel(
|
|
72
|
-
instance=revision_page, request=request, form=form
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
preview_url = reverse("wagtailadmin_pages:preview_on_edit", args=[page.id])
|
|
76
|
-
lock = page.get_lock()
|
|
77
|
-
|
|
78
|
-
action_menu = PageActionMenu(
|
|
79
|
-
request,
|
|
80
|
-
view="revisions_revert",
|
|
81
|
-
is_revision=True,
|
|
82
|
-
page=page,
|
|
83
|
-
lock=lock,
|
|
84
|
-
locked_for_user=lock is not None and lock.for_user(request.user),
|
|
85
|
-
)
|
|
86
|
-
side_panels = [
|
|
87
|
-
PageStatusSidePanel(
|
|
88
|
-
revision_page,
|
|
89
|
-
request,
|
|
90
|
-
show_schedule_publishing_toggle=form.show_schedule_publishing_toggle,
|
|
91
|
-
live_object=page,
|
|
92
|
-
scheduled_object=scheduled_page,
|
|
93
|
-
locale=locale,
|
|
94
|
-
translations=translations,
|
|
95
|
-
),
|
|
96
|
-
]
|
|
97
|
-
if page.is_previewable():
|
|
98
|
-
side_panels.append(PreviewSidePanel(page, request, preview_url=preview_url))
|
|
99
|
-
side_panels.append(ChecksSidePanel(page, request))
|
|
100
|
-
if form.show_comments_toggle:
|
|
101
|
-
side_panels.append(CommentsSidePanel(page, request))
|
|
102
|
-
side_panels = MediaContainer(side_panels)
|
|
103
|
-
|
|
104
|
-
media = MediaContainer([edit_handler, form, action_menu, side_panels]).media
|
|
105
|
-
|
|
106
|
-
user_avatar = render_to_string(
|
|
107
|
-
"wagtailadmin/shared/user_avatar.html", {"user": revision.user}
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
messages.warning(
|
|
111
|
-
request,
|
|
112
|
-
mark_safe(
|
|
47
|
+
def get_object(self):
|
|
48
|
+
return self.previous_revision.as_object()
|
|
49
|
+
|
|
50
|
+
def get_revisions_revert_url(self):
|
|
51
|
+
return reverse(
|
|
52
|
+
self.revisions_revert_url_name,
|
|
53
|
+
args=[self.page.pk, self.revision_id],
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def get_warning_message(self):
|
|
57
|
+
user_avatar = render_to_string(
|
|
58
|
+
"wagtailadmin/shared/user_avatar.html",
|
|
59
|
+
{"user": self.previous_revision.user},
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
return mark_safe(
|
|
113
63
|
_(
|
|
114
64
|
"You are viewing a previous version of this page from <b>%(created_at)s</b> by %(user)s"
|
|
115
65
|
)
|
|
116
66
|
% {
|
|
117
|
-
"created_at": render_timestamp(
|
|
67
|
+
"created_at": render_timestamp(self.previous_revision.created_at),
|
|
118
68
|
"user": user_avatar,
|
|
119
69
|
}
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"
|
|
125
|
-
|
|
126
|
-
page_subtitle = page.get_admin_display_title()
|
|
127
|
-
header_title = f"{page_title}: {page_subtitle}"
|
|
128
|
-
|
|
129
|
-
return TemplateResponse(
|
|
130
|
-
request,
|
|
131
|
-
"wagtailadmin/pages/edit.html",
|
|
132
|
-
{
|
|
133
|
-
"page": page,
|
|
134
|
-
"revision": revision,
|
|
135
|
-
"is_revision": True,
|
|
136
|
-
"content_type": content_type,
|
|
137
|
-
"edit_handler": edit_handler,
|
|
138
|
-
"errors_debug": None,
|
|
139
|
-
"action_menu": action_menu,
|
|
140
|
-
"side_panels": side_panels,
|
|
141
|
-
"header_title": header_title,
|
|
142
|
-
"form": form, # Used in unit tests
|
|
143
|
-
"media": media,
|
|
144
|
-
},
|
|
145
|
-
)
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def get_context_data(self, **kwargs):
|
|
73
|
+
context = super().get_context_data(**kwargs)
|
|
74
|
+
context["action_url"] = self.get_revisions_revert_url()
|
|
75
|
+
return context
|
|
146
76
|
|
|
147
77
|
|
|
148
78
|
@method_decorator(user_passes_test(user_has_any_page_permission), name="dispatch")
|
|
@@ -163,12 +93,11 @@ class RevisionsView(PreviewRevision):
|
|
|
163
93
|
return page
|
|
164
94
|
|
|
165
95
|
|
|
166
|
-
class RevisionsCompare(RevisionsCompareView):
|
|
167
|
-
history_label = gettext_lazy("Page history")
|
|
168
|
-
edit_label = gettext_lazy("Edit this page")
|
|
96
|
+
class RevisionsCompare(GenericPageBreadcrumbsMixin, RevisionsCompareView):
|
|
169
97
|
history_url_name = "wagtailadmin_pages:history"
|
|
170
98
|
edit_url_name = "wagtailadmin_pages:edit"
|
|
171
99
|
header_icon = "doc-empty-inverse"
|
|
100
|
+
breadcrumbs_items_to_take = 2
|
|
172
101
|
|
|
173
102
|
@method_decorator(user_passes_test(user_has_any_page_permission))
|
|
174
103
|
def dispatch(self, request, *args, **kwargs):
|
wagtail/admin/views/tags.py
CHANGED
|
@@ -19,8 +19,12 @@ def autocomplete(request, app_name=None, model_name=None):
|
|
|
19
19
|
|
|
20
20
|
term = request.GET.get("term", None)
|
|
21
21
|
if term:
|
|
22
|
-
tags =
|
|
22
|
+
tags = (
|
|
23
|
+
tag_model.objects.filter(name__istartswith=term)
|
|
24
|
+
.order_by("name")
|
|
25
|
+
.values_list("name", flat=True)[:10]
|
|
26
|
+
)
|
|
23
27
|
else:
|
|
24
28
|
tags = tag_model.objects.none()
|
|
25
29
|
|
|
26
|
-
return JsonResponse(
|
|
30
|
+
return JsonResponse(list(tags), safe=False)
|
wagtail/admin/views/workflows.py
CHANGED
|
@@ -175,7 +175,6 @@ class Create(CreateView):
|
|
|
175
175
|
index_url_name = "wagtailadmin_workflows:index"
|
|
176
176
|
header_icon = "tasks"
|
|
177
177
|
edit_handler = None
|
|
178
|
-
_show_breadcrumbs = True
|
|
179
178
|
|
|
180
179
|
def get_edit_handler(self):
|
|
181
180
|
if not self.edit_handler:
|
|
@@ -263,7 +262,6 @@ class Edit(EditView):
|
|
|
263
262
|
header_more_buttons = []
|
|
264
263
|
edit_handler = None
|
|
265
264
|
MAX_PAGES = 5
|
|
266
|
-
_show_breadcrumbs = True
|
|
267
265
|
|
|
268
266
|
def get_edit_handler(self):
|
|
269
267
|
if not self.edit_handler:
|
|
@@ -304,7 +302,6 @@ class Edit(EditView):
|
|
|
304
302
|
pages_formset = self.get_pages_formset()
|
|
305
303
|
context["edit_handler"] = bound_panel
|
|
306
304
|
context["pages"] = self.get_paginated_pages()
|
|
307
|
-
context["pages_formset"] = pages_formset
|
|
308
305
|
context["has_workflow_enabled_models"] = bool(get_workflow_enabled_models())
|
|
309
306
|
context["content_type_form"] = self.get_content_type_form()
|
|
310
307
|
context["can_disable"] = (
|
|
@@ -315,7 +312,14 @@ class Edit(EditView):
|
|
|
315
312
|
self.permission_policy is None
|
|
316
313
|
or self.permission_policy.user_has_permission(self.request.user, "add")
|
|
317
314
|
) and not self.object.active
|
|
318
|
-
context["media"] = bound_panel.media + form.media
|
|
315
|
+
context["media"] = bound_panel.media + form.media
|
|
316
|
+
|
|
317
|
+
# Only add the pages_formset if the workflow is active
|
|
318
|
+
if self.object.active:
|
|
319
|
+
pages_formset = self.get_pages_formset()
|
|
320
|
+
context["pages_formset"] = pages_formset
|
|
321
|
+
context["media"] += pages_formset.media
|
|
322
|
+
|
|
319
323
|
return context
|
|
320
324
|
|
|
321
325
|
@property
|
|
@@ -641,7 +645,6 @@ class CreateTask(CreateView):
|
|
|
641
645
|
edit_url_name = "wagtailadmin_workflows:edit_task"
|
|
642
646
|
index_url_name = "wagtailadmin_workflows:task_index"
|
|
643
647
|
header_icon = "thumbtack"
|
|
644
|
-
_show_breadcrumbs = True
|
|
645
648
|
|
|
646
649
|
@cached_property
|
|
647
650
|
def model(self):
|
|
@@ -704,7 +707,6 @@ class EditTask(EditView):
|
|
|
704
707
|
enable_url_name = "wagtailadmin_workflows:enable_task"
|
|
705
708
|
header_icon = "thumbtack"
|
|
706
709
|
header_more_buttons = []
|
|
707
|
-
_show_breadcrumbs = True
|
|
708
710
|
|
|
709
711
|
@cached_property
|
|
710
712
|
def model(self):
|
wagtail/admin/viewsets/model.py
CHANGED
|
@@ -63,9 +63,6 @@ class ModelViewSet(ViewSet):
|
|
|
63
63
|
#: The view class to use for the inspect view; must be a subclass of ``wagtail.admin.views.generic.InspectView``.
|
|
64
64
|
inspect_view_class = generic.InspectView
|
|
65
65
|
|
|
66
|
-
# Breadcrumbs can be turned off until we have a design that can be consistently applied
|
|
67
|
-
_show_breadcrumbs = True
|
|
68
|
-
|
|
69
66
|
#: The prefix of template names to look for when rendering the admin views.
|
|
70
67
|
template_prefix = ""
|
|
71
68
|
|
|
@@ -136,7 +133,6 @@ class ModelViewSet(ViewSet):
|
|
|
136
133
|
"edit_url_name": self.get_url_name("edit"),
|
|
137
134
|
"delete_url_name": self.get_url_name("delete"),
|
|
138
135
|
"header_icon": self.icon,
|
|
139
|
-
"_show_breadcrumbs": self._show_breadcrumbs,
|
|
140
136
|
**kwargs,
|
|
141
137
|
}
|
|
142
138
|
)
|
wagtail/admin/viewsets/pages.py
CHANGED
|
@@ -31,7 +31,6 @@ class PageListingViewSet(ViewSet):
|
|
|
31
31
|
def get_common_view_kwargs(self, **kwargs):
|
|
32
32
|
return super().get_common_view_kwargs(
|
|
33
33
|
**{
|
|
34
|
-
"_show_breadcrumbs": True,
|
|
35
34
|
"header_icon": self.icon,
|
|
36
35
|
"model": self.model,
|
|
37
36
|
"index_url_name": self.get_url_name("index"),
|
wagtail/admin/widgets/tags.py
CHANGED
|
@@ -48,6 +48,7 @@ class AdminTagWidget(TagWidget):
|
|
|
48
48
|
help_text = _("Tags can only consist of a single word, no spaces allowed.")
|
|
49
49
|
|
|
50
50
|
context["widget"]["help_text"] = help_text
|
|
51
|
+
context["widget"]["attrs"]["data-w-tag-delay-value"] = 200
|
|
51
52
|
context["widget"]["attrs"]["data-w-tag-url-value"] = autocomplete_url
|
|
52
53
|
context["widget"]["attrs"]["data-w-tag-options-value"] = json.dumps(
|
|
53
54
|
{
|
|
@@ -605,11 +605,13 @@ class TestDocumentCacheInvalidation(TestCase):
|
|
|
605
605
|
signal_handlers.unregister_signal_handlers()
|
|
606
606
|
|
|
607
607
|
def test_resave_document_purges(self, purge):
|
|
608
|
-
|
|
608
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
609
|
+
get_document_model().objects.get(id=5).save()
|
|
609
610
|
|
|
610
611
|
purge.assert_any_call("http://api.example.com/api/main/documents/5/")
|
|
611
612
|
|
|
612
613
|
def test_delete_document_purges(self, purge):
|
|
613
|
-
|
|
614
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
615
|
+
get_document_model().objects.get(id=5).delete()
|
|
614
616
|
|
|
615
617
|
purge.assert_any_call("http://api.example.com/api/main/documents/5/")
|
|
@@ -597,11 +597,13 @@ class TestImageCacheInvalidation(TestCase):
|
|
|
597
597
|
signal_handlers.unregister_signal_handlers()
|
|
598
598
|
|
|
599
599
|
def test_resave_image_purges(self, purge):
|
|
600
|
-
|
|
600
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
601
|
+
get_image_model().objects.get(id=5).save()
|
|
601
602
|
|
|
602
603
|
purge.assert_any_call("http://api.example.com/api/main/images/5/")
|
|
603
604
|
|
|
604
605
|
def test_delete_image_purges(self, purge):
|
|
605
|
-
|
|
606
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
607
|
+
get_image_model().objects.get(id=5).delete()
|
|
606
608
|
|
|
607
609
|
purge.assert_any_call("http://api.example.com/api/main/images/5/")
|
|
@@ -1886,22 +1886,26 @@ class TestPageCacheInvalidation(TestCase):
|
|
|
1886
1886
|
signal_handlers.unregister_signal_handlers()
|
|
1887
1887
|
|
|
1888
1888
|
def test_republish_page_purges(self, purge):
|
|
1889
|
-
|
|
1889
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
1890
|
+
Page.objects.get(id=2).specific.save_revision().publish()
|
|
1890
1891
|
|
|
1891
1892
|
purge.assert_any_call("http://api.example.com/api/main/pages/2/")
|
|
1892
1893
|
|
|
1893
1894
|
def test_unpublish_page_purges(self, purge):
|
|
1894
|
-
|
|
1895
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
1896
|
+
Page.objects.get(id=2).unpublish()
|
|
1895
1897
|
|
|
1896
1898
|
purge.assert_any_call("http://api.example.com/api/main/pages/2/")
|
|
1897
1899
|
|
|
1898
1900
|
def test_delete_page_purges(self, purge):
|
|
1899
|
-
|
|
1901
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
1902
|
+
Page.objects.get(id=16).delete()
|
|
1900
1903
|
|
|
1901
1904
|
purge.assert_any_call("http://api.example.com/api/main/pages/16/")
|
|
1902
1905
|
|
|
1903
1906
|
def test_save_draft_doesnt_purge(self, purge):
|
|
1904
|
-
|
|
1907
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
1908
|
+
Page.objects.get(id=2).specific.save_revision()
|
|
1905
1909
|
|
|
1906
1910
|
purge.assert_not_called()
|
|
1907
1911
|
|
wagtail/blocks/base.py
CHANGED
|
@@ -20,6 +20,7 @@ from wagtail.admin.staticfiles import versioned_static
|
|
|
20
20
|
from wagtail.coreutils import accepts_kwarg
|
|
21
21
|
from wagtail.telepath import JSContext
|
|
22
22
|
from wagtail.utils.deprecation import RemovedInWagtail70Warning
|
|
23
|
+
from wagtail.utils.templates import template_is_overridden
|
|
23
24
|
|
|
24
25
|
__all__ = [
|
|
25
26
|
"BaseBlock",
|
|
@@ -55,8 +56,10 @@ class BaseBlock(type):
|
|
|
55
56
|
class Block(metaclass=BaseBlock):
|
|
56
57
|
name = ""
|
|
57
58
|
creation_counter = 0
|
|
59
|
+
definition_registry = {}
|
|
58
60
|
|
|
59
61
|
TEMPLATE_VAR = "value"
|
|
62
|
+
DEFAULT_PREVIEW_TEMPLATE = "wagtailcore/shared/block_preview.html"
|
|
60
63
|
|
|
61
64
|
class Meta:
|
|
62
65
|
label = None
|
|
@@ -94,6 +97,7 @@ class Block(metaclass=BaseBlock):
|
|
|
94
97
|
self.creation_counter = Block.creation_counter
|
|
95
98
|
Block.creation_counter += 1
|
|
96
99
|
self.definition_prefix = "blockdef-%d" % self.creation_counter
|
|
100
|
+
Block.definition_registry[self.definition_prefix] = self
|
|
97
101
|
|
|
98
102
|
self.label = self.meta.label or ""
|
|
99
103
|
|
|
@@ -157,7 +161,7 @@ class Block(metaclass=BaseBlock):
|
|
|
157
161
|
model definition time (e.g. something like StructValue which incorporates a
|
|
158
162
|
pointer back to the block definition object).
|
|
159
163
|
"""
|
|
160
|
-
return self.normalize(self.meta
|
|
164
|
+
return self.normalize(getattr(self.meta, "default", None))
|
|
161
165
|
|
|
162
166
|
def clean(self, value):
|
|
163
167
|
"""
|
|
@@ -269,6 +273,60 @@ class Block(metaclass=BaseBlock):
|
|
|
269
273
|
|
|
270
274
|
return mark_safe(render_to_string(template, new_context))
|
|
271
275
|
|
|
276
|
+
def get_preview_context(self, value, parent_context=None):
|
|
277
|
+
# We do not fall back to `get_context` here, because the preview context
|
|
278
|
+
# will be used for a complete view, not just the block. Instead, the
|
|
279
|
+
# default preview context uses `{% include_block %}`, which will use
|
|
280
|
+
# `get_context`.
|
|
281
|
+
return parent_context or {}
|
|
282
|
+
|
|
283
|
+
def get_preview_template(self, value, context=None):
|
|
284
|
+
# We do not fall back to `get_template` here, because the template will
|
|
285
|
+
# be used for a complete view, not just the block. In most cases, the
|
|
286
|
+
# block's template cannot stand alone for the preview, as it would be
|
|
287
|
+
# missing the necessary static assets.
|
|
288
|
+
#
|
|
289
|
+
# Instead, the default preview template uses `{% include_block %}`,
|
|
290
|
+
# which will use `get_template` if a template is defined.
|
|
291
|
+
return (
|
|
292
|
+
getattr(self.meta, "preview_template", None)
|
|
293
|
+
or self.DEFAULT_PREVIEW_TEMPLATE
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
def get_preview_value(self):
|
|
297
|
+
if hasattr(self.meta, "preview_value"):
|
|
298
|
+
return self.normalize(self.meta.preview_value)
|
|
299
|
+
return self.get_default()
|
|
300
|
+
|
|
301
|
+
@cached_property
|
|
302
|
+
def is_previewable(self):
|
|
303
|
+
# To prevent showing a broken preview if the block preview has not been
|
|
304
|
+
# configured, consider the block to be previewable if either:
|
|
305
|
+
# - a specific preview template is configured for the block
|
|
306
|
+
# - a preview value is provided and the global template has been overridden
|
|
307
|
+
# which are the intended ways to configure block previews.
|
|
308
|
+
#
|
|
309
|
+
# If a block is made previewable by other means, the `is_previewable`
|
|
310
|
+
# property should be overridden to return `True`.
|
|
311
|
+
has_specific_template = (
|
|
312
|
+
hasattr(self.meta, "preview_template")
|
|
313
|
+
or self.__class__.get_preview_template is not Block.get_preview_template
|
|
314
|
+
)
|
|
315
|
+
has_preview_value = (
|
|
316
|
+
hasattr(self.meta, "preview_value")
|
|
317
|
+
or getattr(self.meta, "default", None) is not None
|
|
318
|
+
or self.__class__.get_preview_context is not Block.get_preview_context
|
|
319
|
+
or self.__class__.get_preview_value is not Block.get_preview_value
|
|
320
|
+
)
|
|
321
|
+
has_global_template = template_is_overridden(
|
|
322
|
+
self.DEFAULT_PREVIEW_TEMPLATE,
|
|
323
|
+
"templates",
|
|
324
|
+
)
|
|
325
|
+
return has_specific_template or (has_preview_value and has_global_template)
|
|
326
|
+
|
|
327
|
+
def get_description(self):
|
|
328
|
+
return getattr(self.meta, "description", "")
|
|
329
|
+
|
|
272
330
|
def get_api_representation(self, value, context=None):
|
|
273
331
|
"""
|
|
274
332
|
Can be used to customise the API response and defaults to the value returned by get_prep_value.
|
wagtail/blocks/field_block.py
CHANGED
|
@@ -81,6 +81,9 @@ class FieldBlock(Block):
|
|
|
81
81
|
self.field.prepare_value(self.value_for_form(value))
|
|
82
82
|
)
|
|
83
83
|
|
|
84
|
+
def get_description(self):
|
|
85
|
+
return super().get_description() or self.field.help_text or ""
|
|
86
|
+
|
|
84
87
|
class Meta:
|
|
85
88
|
# No icon specified here, because that depends on the purpose that the
|
|
86
89
|
# block is being used for. Feel encouraged to specify an icon in your
|
|
@@ -110,8 +113,11 @@ class FieldBlockAdapter(Adapter):
|
|
|
110
113
|
|
|
111
114
|
meta = {
|
|
112
115
|
"label": block.label,
|
|
116
|
+
"description": block.get_description(),
|
|
113
117
|
"required": block.required,
|
|
114
118
|
"icon": block.meta.icon,
|
|
119
|
+
"blockDefId": block.definition_prefix,
|
|
120
|
+
"isPreviewable": block.is_previewable,
|
|
115
121
|
"classname": " ".join(classname),
|
|
116
122
|
"showAddCommentButton": getattr(
|
|
117
123
|
block.field.widget, "show_add_comment_button", True
|
wagtail/blocks/list_block.py
CHANGED
|
@@ -449,12 +449,16 @@ class ListBlockAdapter(Adapter):
|
|
|
449
449
|
def js_args(self, block):
|
|
450
450
|
meta = {
|
|
451
451
|
"label": block.label,
|
|
452
|
+
"description": block.get_description(),
|
|
452
453
|
"icon": block.meta.icon,
|
|
454
|
+
"blockDefId": block.definition_prefix,
|
|
455
|
+
"isPreviewable": block.is_previewable,
|
|
453
456
|
"classname": block.meta.form_classname,
|
|
454
457
|
"collapsed": block.meta.collapsed,
|
|
455
458
|
"strings": {
|
|
456
459
|
"MOVE_UP": _("Move up"),
|
|
457
460
|
"MOVE_DOWN": _("Move down"),
|
|
461
|
+
"DRAG": _("Drag"),
|
|
458
462
|
"DUPLICATE": _("Duplicate"),
|
|
459
463
|
"DELETE": _("Delete"),
|
|
460
464
|
"ADD": _("Add"),
|
wagtail/blocks/static_block.py
CHANGED
wagtail/blocks/stream_block.py
CHANGED
|
@@ -710,7 +710,7 @@ class StreamValue(MutableSequence):
|
|
|
710
710
|
raw_values = OrderedDict(
|
|
711
711
|
(i, raw_item["value"])
|
|
712
712
|
for i, raw_item in enumerate(self._raw_data)
|
|
713
|
-
if
|
|
713
|
+
if self._bound_blocks[i] is None and raw_item["type"] == type_name
|
|
714
714
|
)
|
|
715
715
|
# pass the raw block values to bulk_to_python as a list
|
|
716
716
|
converted_values = child_block.bulk_to_python(raw_values.values())
|
|
@@ -826,8 +826,11 @@ class StreamBlockAdapter(Adapter):
|
|
|
826
826
|
def js_args(self, block):
|
|
827
827
|
meta = {
|
|
828
828
|
"label": block.label,
|
|
829
|
+
"description": block.get_description(),
|
|
829
830
|
"required": block.required,
|
|
830
831
|
"icon": block.meta.icon,
|
|
832
|
+
"blockDefId": block.definition_prefix,
|
|
833
|
+
"isPreviewable": block.is_previewable,
|
|
831
834
|
"classname": block.meta.form_classname,
|
|
832
835
|
"maxNum": block.meta.max_num,
|
|
833
836
|
"minNum": block.meta.min_num,
|
|
@@ -836,6 +839,7 @@ class StreamBlockAdapter(Adapter):
|
|
|
836
839
|
"strings": {
|
|
837
840
|
"MOVE_UP": _("Move up"),
|
|
838
841
|
"MOVE_DOWN": _("Move down"),
|
|
842
|
+
"DRAG": _("Drag"),
|
|
839
843
|
"DUPLICATE": _("Duplicate"),
|
|
840
844
|
"DELETE": _("Delete"),
|
|
841
845
|
"ADD": _("Add"),
|
wagtail/blocks/struct_block.py
CHANGED
|
@@ -360,6 +360,9 @@ class BaseStructBlock(Block):
|
|
|
360
360
|
)
|
|
361
361
|
return mark_safe(render_to_string(self.meta.form_template, context))
|
|
362
362
|
|
|
363
|
+
def get_description(self):
|
|
364
|
+
return super().get_description() or getattr(self.meta, "help_text", "")
|
|
365
|
+
|
|
363
366
|
def get_form_context(self, value, prefix="", errors=None):
|
|
364
367
|
return {
|
|
365
368
|
"children": collections.OrderedDict(
|
|
@@ -401,8 +404,11 @@ class StructBlockAdapter(Adapter):
|
|
|
401
404
|
def js_args(self, block):
|
|
402
405
|
meta = {
|
|
403
406
|
"label": block.label,
|
|
407
|
+
"description": block.get_description(),
|
|
404
408
|
"required": block.required,
|
|
405
409
|
"icon": block.meta.icon,
|
|
410
|
+
"blockDefId": block.definition_prefix,
|
|
411
|
+
"isPreviewable": block.is_previewable,
|
|
406
412
|
"classname": block.meta.form_classname,
|
|
407
413
|
}
|
|
408
414
|
|
wagtail/compat.py
CHANGED
|
@@ -11,3 +11,19 @@ except ValueError:
|
|
|
11
11
|
raise ImproperlyConfigured(
|
|
12
12
|
"AUTH_USER_MODEL must be of the form" " 'app_label.model_name'"
|
|
13
13
|
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from http import HTTPMethod
|
|
18
|
+
except ImportError:
|
|
19
|
+
# For Python < 3.11
|
|
20
|
+
from enum import Enum
|
|
21
|
+
|
|
22
|
+
class HTTPMethod(Enum):
|
|
23
|
+
GET = "GET"
|
|
24
|
+
HEAD = "HEAD"
|
|
25
|
+
OPTIONS = "OPTIONS"
|
|
26
|
+
POST = "POST"
|
|
27
|
+
PUT = "PUT"
|
|
28
|
+
DELETE = "DELETE"
|
|
29
|
+
PATCH = "PATCH"
|
wagtail/contrib/forms/forms.py
CHANGED
|
@@ -173,16 +173,34 @@ class SelectDateForm(django.forms.Form):
|
|
|
173
173
|
|
|
174
174
|
class WagtailAdminFormPageForm(WagtailAdminPageForm):
|
|
175
175
|
def clean(self):
|
|
176
|
-
|
|
176
|
+
"""
|
|
177
|
+
Dynamically detect all related AbstractFormField subclasses to ensure
|
|
178
|
+
validation is applied regardless of the related_name or if there are multiple
|
|
179
|
+
AbstractFormField subclasses related to this page.
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
from .models import AbstractFormField
|
|
183
|
+
|
|
184
|
+
cleaned_data = super().clean()
|
|
177
185
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
186
|
+
form_fields_related_names = [
|
|
187
|
+
related_object.related_name
|
|
188
|
+
for related_object in self.instance._meta.related_objects
|
|
189
|
+
if issubclass(related_object.related_model, AbstractFormField)
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
for related_name in form_fields_related_names:
|
|
193
|
+
if related_name not in self.formsets:
|
|
194
|
+
continue
|
|
195
|
+
|
|
196
|
+
forms = self.formsets[related_name].forms
|
|
181
197
|
for form in forms:
|
|
182
198
|
form.is_valid()
|
|
183
199
|
|
|
184
|
-
# Use existing clean_name or generate for new fields
|
|
185
|
-
#
|
|
200
|
+
# Use existing clean_name or generate for new fields,
|
|
201
|
+
# raise an error if there are duplicate resolved clean names.
|
|
202
|
+
# Note: `clean_name` is set in `FormField.save`.
|
|
203
|
+
|
|
186
204
|
clean_names = [
|
|
187
205
|
f.instance.clean_name or f.instance.get_field_clean_name()
|
|
188
206
|
for f in forms
|
|
@@ -193,7 +211,7 @@ class WagtailAdminFormPageForm(WagtailAdminPageForm):
|
|
|
193
211
|
if duplicate_clean_name:
|
|
194
212
|
duplicate_form_field = next(
|
|
195
213
|
f
|
|
196
|
-
for f in self.formsets[
|
|
214
|
+
for f in self.formsets[related_name].forms
|
|
197
215
|
if f.instance.get_field_clean_name() == duplicate_clean_name
|
|
198
216
|
)
|
|
199
217
|
duplicate_form_field.add_error(
|
|
@@ -205,3 +223,5 @@ class WagtailAdminFormPageForm(WagtailAdminPageForm):
|
|
|
205
223
|
% {"label_name": duplicate_form_field.instance.label}
|
|
206
224
|
),
|
|
207
225
|
)
|
|
226
|
+
|
|
227
|
+
return cleaned_data
|