wagtail 6.0.1__py3-none-any.whl → 6.1rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wagtail/__init__.py +1 -1
- wagtail/admin/checks.py +51 -0
- wagtail/admin/compare.py +1 -1
- wagtail/admin/filters.py +70 -1
- wagtail/admin/forms/account.py +1 -1
- wagtail/admin/forms/collections.py +15 -0
- wagtail/admin/forms/pages.py +49 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.po +122 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.po +5 -5
- wagtail/admin/locale/en/LC_MESSAGES/django.po +474 -385
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +3 -3
- wagtail/admin/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es/LC_MESSAGES/django.po +6 -6
- wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fr/LC_MESSAGES/django.po +70 -3
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.po +2 -6
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.po +2 -2
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +4 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.po +142 -2
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +80 -8
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +14 -2
- wagtail/admin/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/lv/LC_MESSAGES/django.po +154 -1
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +73 -2
- wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ro/LC_MESSAGES/django.po +3 -3
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +145 -2
- wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/django.po +77 -3
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +17 -1
- wagtail/admin/panels/comment_panel.py +1 -1
- wagtail/admin/panels/field_panel.py +1 -1
- wagtail/admin/rich_text/converters/editor_html.py +3 -1
- wagtail/admin/rich_text/editors/draftail/__init__.py +28 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
- wagtail/admin/static/wagtailadmin/images/favicon.ico +0 -0
- 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/core.js.LICENSE.txt +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 +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/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/telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +4 -4
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/staticfiles.py +1 -0
- wagtail/admin/templates/wagtailadmin/admin_base.html +1 -0
- wagtail/admin/templates/wagtailadmin/base.html +1 -0
- wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +3 -1
- wagtail/admin/templates/wagtailadmin/collections/edit.html +0 -1
- wagtail/admin/templates/wagtailadmin/collections/index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/generic/base.html +1 -9
- wagtail/admin/templates/wagtailadmin/generic/form.html +4 -2
- wagtail/admin/templates/wagtailadmin/generic/history/action_cell.html +27 -0
- wagtail/admin/templates/wagtailadmin/generic/index_results.html +8 -0
- wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +3 -4
- wagtail/admin/templates/wagtailadmin/icons/keyboard.svg +1 -0
- wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +3 -1
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -15
- wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +3 -1
- wagtail/admin/templates/wagtailadmin/pages/choose_parent.html +17 -0
- wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +8 -0
- wagtail/admin/templates/wagtailadmin/pages/history.html +1 -61
- wagtail/admin/templates/wagtailadmin/pages/index.html +1 -5
- wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +2 -2
- wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +25 -27
- wagtail/admin/templates/wagtailadmin/pages/page_listing_header.html +2 -1
- wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/publishing/schedule_publishing_panel.html +3 -1
- wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/active_filters.html +2 -1
- wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +8 -0
- wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/headers/page_edit_header.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +21 -9
- wagtail/admin/templates/wagtailadmin/shared/human_readable_date.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +29 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +2 -1
- wagtail/admin/templates/wagtailadmin/skeleton.html +2 -1
- wagtail/admin/templates/wagtailadmin/tables/related_objects_cell.html +9 -0
- wagtail/admin/templates/wagtailadmin/tables/title_cell.html +9 -7
- wagtail/admin/templates/wagtailadmin/widgets/draftail_rich_text_area.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/create.html +6 -23
- wagtail/admin/templates/wagtailadmin/workflows/create_task.html +6 -15
- wagtail/admin/templates/wagtailadmin/workflows/edit.html +6 -23
- wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +6 -13
- wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -4
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +18 -0
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_title_cell.html +7 -0
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +25 -0
- wagtail/admin/templates/wagtailadmin/workflows/index.html +0 -99
- wagtail/admin/templates/wagtailadmin/workflows/index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/workflows/task_index.html +0 -30
- wagtail/admin/templates/wagtailadmin/workflows/task_index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/workflows/usage.html +1 -1
- wagtail/admin/templatetags/wagtailadmin_tags.py +116 -39
- wagtail/admin/tests/api/test_pages.py +26 -10
- wagtail/admin/tests/pages/test_create_page.py +10 -4
- wagtail/admin/tests/pages/test_custom_listing.py +37 -0
- wagtail/admin/tests/pages/test_edit_page.py +6 -6
- wagtail/admin/tests/pages/test_explorer_view.py +19 -18
- wagtail/admin/tests/pages/test_move_page.py +1 -1
- wagtail/admin/tests/pages/test_page_usage.py +50 -2
- wagtail/admin/tests/pages/test_parent_page_chooser_view.py +119 -0
- wagtail/admin/tests/pages/test_preview.py +18 -4
- wagtail/admin/tests/test_account_management.py +20 -1
- wagtail/admin/tests/test_audit_log.py +172 -5
- wagtail/admin/tests/test_checks.py +92 -0
- wagtail/admin/tests/test_collections_views.py +19 -5
- wagtail/admin/tests/test_compare.py +6 -6
- wagtail/admin/tests/test_dashboard.py +404 -0
- wagtail/admin/tests/test_dbwhitelister.py +4 -5
- wagtail/admin/tests/test_edit_handlers.py +2 -2
- wagtail/admin/tests/test_keyboard_shortcuts.py +84 -0
- wagtail/admin/tests/test_page_chooser.py +31 -18
- wagtail/admin/tests/test_privacy.py +36 -2
- wagtail/admin/tests/test_rich_text.py +168 -23
- wagtail/admin/tests/test_templatetags.py +411 -43
- wagtail/admin/tests/test_views.py +4 -2
- wagtail/admin/tests/test_workflows.py +531 -9
- wagtail/admin/tests/tests.py +3 -1
- wagtail/admin/tests/ui/test_tables.py +48 -1
- wagtail/admin/tests/viewsets/test_model_viewset.py +130 -23
- wagtail/admin/ui/side_panels.py +3 -1
- wagtail/admin/ui/tables/__init__.py +13 -1
- wagtail/admin/ui/tables/pages.py +17 -6
- wagtail/admin/urls/__init__.py +8 -3
- wagtail/admin/urls/pages.py +5 -0
- wagtail/admin/urls/workflows.py +10 -0
- wagtail/admin/views/chooser.py +20 -24
- wagtail/admin/views/collections.py +17 -1
- wagtail/admin/views/generic/base.py +34 -4
- wagtail/admin/views/generic/history.py +220 -51
- wagtail/admin/views/generic/mixins.py +7 -4
- wagtail/admin/views/generic/models.py +54 -47
- wagtail/admin/views/generic/multiple_upload.py +17 -8
- wagtail/admin/views/generic/usage.py +17 -11
- wagtail/admin/views/home.py +15 -12
- wagtail/admin/views/mixins.py +30 -0
- wagtail/admin/views/pages/choose_parent.py +73 -0
- wagtail/admin/views/pages/history.py +54 -66
- wagtail/admin/views/pages/listing.py +187 -106
- wagtail/admin/views/pages/usage.py +6 -1
- wagtail/admin/views/pages/utils.py +70 -1
- wagtail/admin/views/workflows.py +150 -21
- wagtail/admin/viewsets/model.py +2 -2
- wagtail/admin/viewsets/pages.py +77 -0
- wagtail/admin/wagtail_hooks.py +40 -2
- wagtail/admin/widgets/button.py +10 -10
- wagtail/api/v2/filters.py +1 -1
- wagtail/api/v2/tests/test_pages.py +1 -1
- wagtail/blocks/base.py +18 -9
- wagtail/blocks/field_block.py +9 -7
- wagtail/blocks/list_block.py +16 -6
- wagtail/blocks/static_block.py +3 -0
- wagtail/blocks/stream_block.py +58 -23
- wagtail/blocks/struct_block.py +15 -9
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +39 -47
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/forms/models.py +5 -5
- wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +44 -33
- wagtail/contrib/forms/templates/wagtailforms/submissions_index.html +2 -63
- wagtail/contrib/forms/tests/test_models.py +26 -0
- wagtail/contrib/forms/urls.py +6 -0
- wagtail/contrib/forms/views.py +52 -49
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +34 -42
- wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/redirects/signal_handlers.py +1 -1
- wagtail/contrib/redirects/templates/wagtailredirects/index.html +1 -36
- wagtail/contrib/redirects/templates/wagtailredirects/index_results.html +18 -0
- wagtail/contrib/redirects/templates/wagtailredirects/redirect_target_cell.html +8 -0
- wagtail/contrib/redirects/tests/test_import_command.py +1 -1
- wagtail/contrib/redirects/tests/test_redirects.py +79 -8
- wagtail/contrib/redirects/urls.py +2 -1
- wagtail/contrib/redirects/views.py +85 -55
- wagtail/contrib/search_promotions/admin_urls.py +2 -1
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +41 -64
- wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +41 -2
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +9 -3
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +1 -16
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index_results.html +11 -0
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/list.html +0 -51
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/results.html +3 -16
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/search_promotion_column.html +15 -0
- wagtail/contrib/search_promotions/tests.py +122 -9
- wagtail/contrib/search_promotions/views.py +66 -65
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.po +6 -2
- wagtail/contrib/settings/registry.py +10 -5
- wagtail/contrib/settings/tests/generic/test_admin.py +9 -0
- wagtail/contrib/settings/tests/site_specific/test_admin.py +10 -1
- wagtail/contrib/settings/tests/site_specific/test_model.py +3 -3
- wagtail/contrib/settings/tests/site_specific/test_templates.py +1 -1
- wagtail/contrib/settings/views.py +3 -1
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/tests/test_wagtail_hooks.py +2 -2
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/table_block/blocks.py +2 -2
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/table_block/tests.py +6 -0
- wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/coreutils.py +3 -2
- wagtail/documents/admin_urls.py +2 -2
- wagtail/documents/locale/en/LC_MESSAGES/django.po +22 -22
- wagtail/documents/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +19 -2
- wagtail/documents/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hu/LC_MESSAGES/django.po +16 -2
- wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/it/LC_MESSAGES/django.po +19 -2
- wagtail/documents/migrations/0013_delete_uploadeddocument.py +16 -0
- wagtail/documents/models.py +1 -20
- wagtail/documents/rich_text/__init__.py +11 -7
- 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/templates/wagtaildocs/documents/index.html +0 -16
- wagtail/documents/tests/test_admin_views.py +155 -23
- wagtail/documents/tests/test_collection_privacy.py +55 -1
- wagtail/documents/tests/test_rich_text.py +14 -0
- wagtail/documents/views/documents.py +25 -22
- wagtail/documents/views/multiple.py +6 -7
- wagtail/documents/views/serve.py +16 -1
- wagtail/documents/wagtail_hooks.py +20 -15
- wagtail/embeds/blocks.py +5 -0
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/embeds/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/rich_text/__init__.py +1 -1
- wagtail/embeds/tests/test_rich_text.py +14 -0
- wagtail/embeds/wagtail_hooks.py +4 -14
- wagtail/fields.py +3 -48
- wagtail/images/admin_urls.py +2 -2
- wagtail/images/check_files/wagtail.jpg +0 -0
- wagtail/images/check_files/wagtail.png +0 -0
- wagtail/images/fields.py +2 -0
- wagtail/images/image_operations.py +1 -1
- wagtail/images/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ca/LC_MESSAGES/django.po +12 -0
- wagtail/images/locale/en/LC_MESSAGES/django.po +33 -45
- wagtail/images/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/hu/LC_MESSAGES/django.po +28 -2
- wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/it/LC_MESSAGES/django.po +14 -2
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +4 -0
- wagtail/images/migrations/0026_delete_uploadedimage.py +16 -0
- wagtail/images/models.py +49 -43
- wagtail/images/rich_text/__init__.py +18 -8
- 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/image_listing_header.html +6 -0
- wagtail/images/templates/wagtailimages/images/index.html +11 -51
- wagtail/images/tests/test_admin_views.py +119 -62
- wagtail/images/tests/test_image_operations.py +10 -0
- wagtail/images/tests/test_models.py +35 -33
- wagtail/images/tests/test_rich_text.py +14 -0
- wagtail/images/tests/utils.py +1 -1
- wagtail/images/views/images.py +35 -64
- wagtail/images/views/multiple.py +6 -7
- wagtail/images/wagtail_hooks.py +4 -14
- wagtail/locale/en/LC_MESSAGES/django.po +150 -136
- wagtail/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/es/LC_MESSAGES/django.po +3 -2
- wagtail/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/it/LC_MESSAGES/django.po +5 -5
- wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sl/LC_MESSAGES/django.po +27 -2
- wagtail/locales/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/et/LC_MESSAGES/django.po +2 -2
- wagtail/locales/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/he_IL/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/locales/tests.py +18 -3
- wagtail/locales/views.py +0 -1
- wagtail/management/commands/rebuild_references_index.py +3 -1
- wagtail/migrations/0092_alter_collectionviewrestriction_password_and_more.py +33 -0
- wagtail/migrations/0093_uploadedfile.py +53 -0
- wagtail/models/__init__.py +147 -32
- wagtail/models/i18n.py +1 -1
- wagtail/models/{collections.py → media.py} +33 -2
- wagtail/models/reference_index.py +1 -1
- wagtail/models/view_restrictions.py +10 -3
- wagtail/project_template/project_name/settings/base.py +6 -0
- wagtail/project_template/requirements.txt +1 -1
- wagtail/rich_text/__init__.py +25 -8
- wagtail/rich_text/pages.py +19 -8
- wagtail/rich_text/rewriters.py +140 -68
- wagtail/search/backends/database/mysql/mysql.py +3 -3
- wagtail/search/backends/database/postgres/postgres.py +3 -3
- wagtail/search/backends/database/sqlite/sqlite.py +2 -2
- wagtail/search/backends/elasticsearch7.py +4 -0
- wagtail/search/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/search/tests/test_postgres_backend.py +50 -0
- wagtail/sites/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/sites/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/sites/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/sites/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/sites/locale/ro/LC_MESSAGES/django.po +3 -2
- wagtail/sites/tests.py +35 -9
- wagtail/sites/views.py +3 -1
- wagtail/snippets/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/de/LC_MESSAGES/django.po +7 -8
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +16 -56
- wagtail/snippets/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +6 -2
- wagtail/snippets/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/lv/LC_MESSAGES/django.po +12 -0
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.po +4 -0
- 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/publish.html +3 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +3 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/create.html +2 -3
- wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +2 -3
- wagtail/snippets/tests/test_preview.py +13 -2
- wagtail/snippets/tests/test_snippets.py +41 -16
- wagtail/snippets/tests/test_viewset.py +95 -18
- wagtail/snippets/tests/test_workflows.py +12 -0
- wagtail/snippets/views/snippets.py +1 -40
- wagtail/templatetags/wagtailcore_tags.py +1 -1
- wagtail/test/demosite/models.py +1 -1
- wagtail/test/middleware.py +14 -1
- wagtail/test/testapp/fixtures/test.json +20 -0
- wagtail/test/testapp/migrations/0001_squashed_0073_revisablechildmodel_secret_text.py +8 -8
- wagtail/test/testapp/migrations/0023_snippetchoosermodel_full_featured.py +1 -0
- wagtail/test/testapp/migrations/0034_custompermissionmodel.py +44 -0
- wagtail/test/testapp/migrations/0035_modelwithcustommanager.py +30 -0
- wagtail/test/testapp/migrations/0036_complexdefaultstreampage.py +28 -0
- wagtail/test/testapp/models.py +79 -2
- wagtail/test/testapp/templates/tests/custom_docs_password_required.html +10 -0
- wagtail/test/testapp/templates/tests/custom_page_password_required.html +10 -0
- wagtail/test/testapp/views.py +24 -2
- wagtail/test/testapp/wagtail_hooks.py +19 -0
- wagtail/test/utils/wagtail_tests.py +2 -2
- wagtail/tests/test_blocks.py +262 -1
- wagtail/tests/test_migrations.py +1 -1
- wagtail/tests/test_page_model.py +77 -0
- wagtail/tests/test_page_privacy.py +18 -1
- wagtail/tests/test_rich_text.py +95 -5
- wagtail/tests/test_streamfield.py +43 -0
- wagtail/tests/test_utils.py +8 -2
- wagtail/tests/test_views.py +52 -1
- wagtail/tests/test_whitelist.py +7 -7
- wagtail/users/forms.py +3 -1
- wagtail/users/locale/en/LC_MESSAGES/django.po +124 -96
- wagtail/users/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +13 -2
- wagtail/users/migrations/0013_userprofile_density.py +23 -0
- wagtail/users/models.py +14 -3
- wagtail/users/templates/wagtailusers/groups/create.html +1 -7
- wagtail/users/templates/wagtailusers/groups/edit.html +1 -13
- wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +46 -2
- wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
- wagtail/users/templates/wagtailusers/users/create.html +1 -14
- wagtail/users/templates/wagtailusers/users/edit.html +1 -14
- wagtail/users/templates/wagtailusers/users/index.html +2 -5
- wagtail/users/templates/wagtailusers/users/index_results.html +3 -13
- wagtail/users/templates/wagtailusers/users/user_cell.html +9 -0
- wagtail/users/templatetags/wagtailusers_tags.py +107 -20
- wagtail/users/tests/test_admin_views.py +669 -90
- wagtail/users/views/groups.py +58 -61
- wagtail/users/views/users.py +211 -92
- wagtail/users/wagtail_hooks.py +6 -38
- wagtail/users/widgets.py +3 -5
- wagtail/utils/text.py +1 -1
- wagtail/views.py +5 -9
- wagtail/whitelist.py +1 -1
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/METADATA +5 -6
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/RECORD +496 -477
- wagtail/admin/static/wagtailadmin/js/page-editor.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/mousetrap.min.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/urlify.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/xregexp.min.js +0 -1
- wagtail/admin/templates/wagtailadmin/collections/index.html +0 -34
- wagtail/admin/templates/wagtailadmin/pages/revisions/_actions.html +0 -22
- wagtail/admin/templates/wagtailadmin/shared/page_breadcrumbs.html +0 -55
- wagtail/admin/tests/pages/test_dashboard.py +0 -172
- wagtail/contrib/redirects/templates/wagtailredirects/results.html +0 -23
- wagtail/documents/templates/wagtaildocs/documents/list.html +0 -2
- wagtail/search/tests/test_postgres_stemming.py +0 -40
- wagtail/sites/templates/wagtailsites/create.html +0 -7
- wagtail/sites/templates/wagtailsites/edit.html +0 -7
- wagtail/snippets/templates/wagtailsnippets/snippets/revisions/_actions.html +0 -36
- wagtail/users/templates/wagtailusers/users/list.html +0 -62
- wagtail/users/urls/users.py +0 -12
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/top_level.txt +0 -0
wagtail/admin/views/workflows.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import django_filters
|
|
2
|
+
from django import forms
|
|
1
3
|
from django.contrib.contenttypes.models import ContentType
|
|
2
4
|
from django.core.exceptions import PermissionDenied
|
|
3
5
|
from django.core.paginator import Paginator
|
|
4
6
|
from django.db import transaction
|
|
5
|
-
from django.db.models import Count, OuterRef
|
|
7
|
+
from django.db.models import Count, OuterRef, Prefetch
|
|
6
8
|
from django.db.models.functions import Lower
|
|
7
9
|
from django.http import Http404, HttpResponseBadRequest
|
|
8
10
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
@@ -18,6 +20,7 @@ from django.views.generic import TemplateView
|
|
|
18
20
|
|
|
19
21
|
from wagtail.admin import messages
|
|
20
22
|
from wagtail.admin.auth import PermissionPolicyChecker
|
|
23
|
+
from wagtail.admin.filters import MultipleContentTypeFilter, WagtailFilterSet
|
|
21
24
|
from wagtail.admin.forms.workflows import (
|
|
22
25
|
TaskChooserSearchForm,
|
|
23
26
|
WorkflowContentTypeForm,
|
|
@@ -26,7 +29,7 @@ from wagtail.admin.forms.workflows import (
|
|
|
26
29
|
get_workflow_edit_handler,
|
|
27
30
|
)
|
|
28
31
|
from wagtail.admin.modal_workflow import render_modal_workflow
|
|
29
|
-
from wagtail.admin.ui.tables import Column, TitleColumn
|
|
32
|
+
from wagtail.admin.ui.tables import BaseColumn, Column, TitleColumn
|
|
30
33
|
from wagtail.admin.views.generic import CreateView, DeleteView, EditView, IndexView
|
|
31
34
|
from wagtail.coreutils import resolve_model_string
|
|
32
35
|
from wagtail.models import (
|
|
@@ -36,6 +39,7 @@ from wagtail.models import (
|
|
|
36
39
|
Workflow,
|
|
37
40
|
WorkflowContentType,
|
|
38
41
|
WorkflowState,
|
|
42
|
+
WorkflowTask,
|
|
39
43
|
)
|
|
40
44
|
from wagtail.permissions import (
|
|
41
45
|
page_permission_policy,
|
|
@@ -48,35 +52,114 @@ from wagtail.workflows import get_task_types
|
|
|
48
52
|
task_permission_checker = PermissionPolicyChecker(task_permission_policy)
|
|
49
53
|
|
|
50
54
|
|
|
55
|
+
class WorkflowTitleColumn(TitleColumn):
|
|
56
|
+
cell_template_name = "wagtailadmin/workflows/includes/workflow_title_cell.html"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class WorkflowUsedByColumn(TitleColumn):
|
|
60
|
+
cell_template_name = "wagtailadmin/workflows/includes/workflow_used_by_cell.html"
|
|
61
|
+
|
|
62
|
+
def get_cell_context_data(self, instance, parent_context):
|
|
63
|
+
context = super().get_cell_context_data(instance, parent_context)
|
|
64
|
+
context["workflow_enabled_models"] = get_workflow_enabled_models()
|
|
65
|
+
return context
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class WorkflowTasksColumn(BaseColumn):
|
|
69
|
+
cell_template_name = "wagtailadmin/workflows/includes/workflow_tasks_cell.html"
|
|
70
|
+
num_tasks = 5
|
|
71
|
+
|
|
72
|
+
def get_cell_context_data(self, instance, parent_context):
|
|
73
|
+
context = super().get_cell_context_data(instance, parent_context)
|
|
74
|
+
context["tasks"] = instance.workflow_tasks.all()[: self.num_tasks]
|
|
75
|
+
context["extra_count"] = instance.workflow_tasks.count() - self.num_tasks
|
|
76
|
+
return context
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class BaseWorkflowFilterSet(WagtailFilterSet):
|
|
80
|
+
show_disabled = django_filters.ChoiceFilter(
|
|
81
|
+
label=_("Show disabled"),
|
|
82
|
+
method="filter_show_disabled",
|
|
83
|
+
choices=(("true", _("Yes")), ("false", _("No"))),
|
|
84
|
+
widget=forms.RadioSelect,
|
|
85
|
+
empty_label=None,
|
|
86
|
+
initial="false",
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
|
|
90
|
+
if data is not None:
|
|
91
|
+
if data.get("show_disabled") is None:
|
|
92
|
+
filter = self.base_filters["show_disabled"]
|
|
93
|
+
data = data.copy()
|
|
94
|
+
data["show_disabled"] = filter.extra["initial"]
|
|
95
|
+
super().__init__(data, queryset, request=request, prefix=prefix)
|
|
96
|
+
|
|
97
|
+
def filter_show_disabled(self, queryset, name, value):
|
|
98
|
+
if value == "true":
|
|
99
|
+
return queryset
|
|
100
|
+
return queryset.filter(active=True)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class WorkflowFilterSet(BaseWorkflowFilterSet):
|
|
104
|
+
class Meta:
|
|
105
|
+
model = Workflow
|
|
106
|
+
fields = []
|
|
107
|
+
|
|
108
|
+
|
|
51
109
|
class Index(IndexView):
|
|
52
110
|
permission_policy = workflow_permission_policy
|
|
53
111
|
model = Workflow
|
|
54
112
|
context_object_name = "workflows"
|
|
55
113
|
template_name = "wagtailadmin/workflows/index.html"
|
|
114
|
+
results_template_name = "wagtailadmin/workflows/index_results.html"
|
|
56
115
|
add_url_name = "wagtailadmin_workflows:add"
|
|
57
116
|
edit_url_name = "wagtailadmin_workflows:edit"
|
|
58
117
|
index_url_name = "wagtailadmin_workflows:index"
|
|
118
|
+
index_results_url_name = "wagtailadmin_workflows:index_results"
|
|
59
119
|
page_title = _("Workflows")
|
|
60
120
|
add_item_label = _("Add a workflow")
|
|
61
121
|
header_icon = "tasks"
|
|
122
|
+
columns = [
|
|
123
|
+
WorkflowTitleColumn(
|
|
124
|
+
"name",
|
|
125
|
+
label=_("Name"),
|
|
126
|
+
url_name="wagtailadmin_workflows:edit",
|
|
127
|
+
width="25%",
|
|
128
|
+
sort_key="name",
|
|
129
|
+
),
|
|
130
|
+
WorkflowUsedByColumn(
|
|
131
|
+
"usage",
|
|
132
|
+
label=_("Used by"),
|
|
133
|
+
url_name="wagtailadmin_workflows:usage",
|
|
134
|
+
width="15%",
|
|
135
|
+
),
|
|
136
|
+
WorkflowTasksColumn("tasks", label=_("Tasks")),
|
|
137
|
+
]
|
|
138
|
+
default_ordering = "name"
|
|
139
|
+
search_fields = ["name"]
|
|
140
|
+
filterset_class = WorkflowFilterSet
|
|
141
|
+
_show_breadcrumbs = True
|
|
142
|
+
paginate_by = 20
|
|
62
143
|
|
|
63
144
|
def show_disabled(self):
|
|
64
|
-
return self.
|
|
145
|
+
return self.filters.form.cleaned_data.get("show_disabled") == "true"
|
|
65
146
|
|
|
66
|
-
def
|
|
67
|
-
queryset = super().
|
|
68
|
-
if not self.show_disabled():
|
|
69
|
-
queryset = queryset.filter(active=True)
|
|
147
|
+
def get_base_queryset(self):
|
|
148
|
+
queryset = super().get_base_queryset()
|
|
70
149
|
content_types = WorkflowContentType.objects.filter(
|
|
71
150
|
workflow=OuterRef("pk")
|
|
72
151
|
).values_list("pk", flat=True)
|
|
73
152
|
queryset = queryset.annotate(content_types=Count(content_types))
|
|
74
|
-
return queryset
|
|
153
|
+
return queryset.prefetch_related(
|
|
154
|
+
"workflow_pages",
|
|
155
|
+
"workflow_pages__page",
|
|
156
|
+
"workflow_tasks",
|
|
157
|
+
"workflow_tasks__task",
|
|
158
|
+
)
|
|
75
159
|
|
|
76
160
|
def get_context_data(self, **kwargs):
|
|
77
161
|
context = super().get_context_data(**kwargs)
|
|
78
162
|
context["showing_disabled"] = self.show_disabled()
|
|
79
|
-
context["workflow_enabled_models"] = get_workflow_enabled_models()
|
|
80
163
|
return context
|
|
81
164
|
|
|
82
165
|
|
|
@@ -91,6 +174,7 @@ class Create(CreateView):
|
|
|
91
174
|
index_url_name = "wagtailadmin_workflows:index"
|
|
92
175
|
header_icon = "tasks"
|
|
93
176
|
edit_handler = None
|
|
177
|
+
_show_breadcrumbs = True
|
|
94
178
|
|
|
95
179
|
def get_edit_handler(self):
|
|
96
180
|
if not self.edit_handler:
|
|
@@ -177,6 +261,7 @@ class Edit(EditView):
|
|
|
177
261
|
header_icon = "tasks"
|
|
178
262
|
edit_handler = None
|
|
179
263
|
MAX_PAGES = 5
|
|
264
|
+
_show_breadcrumbs = True
|
|
180
265
|
|
|
181
266
|
def get_edit_handler(self):
|
|
182
267
|
if not self.edit_handler:
|
|
@@ -226,7 +311,7 @@ class Edit(EditView):
|
|
|
226
311
|
) and self.object.active
|
|
227
312
|
context["can_enable"] = (
|
|
228
313
|
self.permission_policy is None
|
|
229
|
-
or self.permission_policy.user_has_permission(self.request.user, "
|
|
314
|
+
or self.permission_policy.user_has_permission(self.request.user, "add")
|
|
230
315
|
) and not self.object.active
|
|
231
316
|
context["media"] = bound_panel.media + form.media + pages_formset.media
|
|
232
317
|
return context
|
|
@@ -334,7 +419,7 @@ def enable_workflow(request, pk):
|
|
|
334
419
|
workflow = get_object_or_404(Workflow, id=pk)
|
|
335
420
|
|
|
336
421
|
# Check permissions
|
|
337
|
-
if not workflow_permission_policy.user_has_permission(request.user, "
|
|
422
|
+
if not workflow_permission_policy.user_has_permission(request.user, "add"):
|
|
338
423
|
raise PermissionDenied
|
|
339
424
|
|
|
340
425
|
# Set workflow to active if inactive
|
|
@@ -396,33 +481,75 @@ class TaskUsageColumn(Column):
|
|
|
396
481
|
cell_template_name = "wagtailadmin/workflows/includes/task_usage_cell.html"
|
|
397
482
|
|
|
398
483
|
|
|
484
|
+
class TaskFilterSet(BaseWorkflowFilterSet):
|
|
485
|
+
def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
|
|
486
|
+
super().__init__(data, queryset, request=request, prefix=prefix)
|
|
487
|
+
task_types = get_task_types()
|
|
488
|
+
ct_ids = [
|
|
489
|
+
ct.id for ct in ContentType.objects.get_for_models(*task_types).values()
|
|
490
|
+
]
|
|
491
|
+
if len(task_types) > 1:
|
|
492
|
+
self.filters["content_type"] = MultipleContentTypeFilter(
|
|
493
|
+
label=_("Type"),
|
|
494
|
+
widget=forms.CheckboxSelectMultiple,
|
|
495
|
+
queryset=lambda request: ContentType.objects.filter(pk__in=ct_ids),
|
|
496
|
+
field_name="content_type",
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
class Meta:
|
|
500
|
+
model = Task
|
|
501
|
+
fields = []
|
|
502
|
+
|
|
503
|
+
|
|
399
504
|
class TaskIndex(IndexView):
|
|
400
505
|
permission_policy = task_permission_policy
|
|
401
506
|
model = Task
|
|
402
507
|
context_object_name = "tasks"
|
|
403
508
|
template_name = "wagtailadmin/workflows/task_index.html"
|
|
509
|
+
results_template_name = "wagtailadmin/workflows/task_index_results.html"
|
|
404
510
|
add_url_name = "wagtailadmin_workflows:select_task_type"
|
|
405
511
|
edit_url_name = "wagtailadmin_workflows:edit_task"
|
|
406
512
|
index_url_name = "wagtailadmin_workflows:task_index"
|
|
513
|
+
index_results_url_name = "wagtailadmin_workflows:task_index_results"
|
|
407
514
|
page_title = _("Workflow tasks")
|
|
408
515
|
add_item_label = _("New workflow task")
|
|
409
516
|
header_icon = "thumbtack"
|
|
410
517
|
columns = [
|
|
411
518
|
TaskTitleColumn(
|
|
412
|
-
"name",
|
|
519
|
+
"name",
|
|
520
|
+
label=_("Name"),
|
|
521
|
+
url_name="wagtailadmin_workflows:edit_task",
|
|
522
|
+
sort_key="name",
|
|
523
|
+
),
|
|
524
|
+
Column("type", label=_("Type"), accessor="get_verbose_name", width="25%"),
|
|
525
|
+
TaskUsageColumn(
|
|
526
|
+
"usage", label=_("Used on"), accessor="_active_workflows", width="25%"
|
|
413
527
|
),
|
|
414
|
-
Column("type", label=_("Type"), accessor="get_verbose_name"),
|
|
415
|
-
TaskUsageColumn("usage", label=_("Used on"), accessor="active_workflows"),
|
|
416
528
|
]
|
|
529
|
+
default_ordering = "name"
|
|
530
|
+
search_fields = ["name"]
|
|
531
|
+
filterset_class = TaskFilterSet
|
|
532
|
+
_show_breadcrumbs = True
|
|
533
|
+
paginate_by = 50
|
|
417
534
|
|
|
418
535
|
def show_disabled(self):
|
|
419
|
-
return self.
|
|
536
|
+
return self.filters.form.cleaned_data.get("show_disabled") == "true"
|
|
420
537
|
|
|
421
538
|
def get_queryset(self):
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
539
|
+
return (
|
|
540
|
+
super()
|
|
541
|
+
.get_queryset()
|
|
542
|
+
.specific()
|
|
543
|
+
.prefetch_related(
|
|
544
|
+
Prefetch(
|
|
545
|
+
"workflow_tasks",
|
|
546
|
+
queryset=WorkflowTask.objects.filter(
|
|
547
|
+
workflow__active=True
|
|
548
|
+
).select_related("workflow"),
|
|
549
|
+
to_attr="_active_workflows",
|
|
550
|
+
)
|
|
551
|
+
)
|
|
552
|
+
)
|
|
426
553
|
|
|
427
554
|
def get_context_data(self, **kwargs):
|
|
428
555
|
context = super().get_context_data(**kwargs)
|
|
@@ -473,6 +600,7 @@ class CreateTask(CreateView):
|
|
|
473
600
|
edit_url_name = "wagtailadmin_workflows:edit_task"
|
|
474
601
|
index_url_name = "wagtailadmin_workflows:task_index"
|
|
475
602
|
header_icon = "thumbtack"
|
|
603
|
+
_show_breadcrumbs = True
|
|
476
604
|
|
|
477
605
|
@cached_property
|
|
478
606
|
def model(self):
|
|
@@ -534,6 +662,7 @@ class EditTask(EditView):
|
|
|
534
662
|
enable_item_label = _("Enable")
|
|
535
663
|
enable_url_name = "wagtailadmin_workflows:enable_task"
|
|
536
664
|
header_icon = "thumbtack"
|
|
665
|
+
_show_breadcrumbs = True
|
|
537
666
|
|
|
538
667
|
@cached_property
|
|
539
668
|
def model(self):
|
|
@@ -574,7 +703,7 @@ class EditTask(EditView):
|
|
|
574
703
|
) and self.object.active
|
|
575
704
|
context["can_enable"] = (
|
|
576
705
|
self.permission_policy is None
|
|
577
|
-
or self.permission_policy.user_has_permission(self.request.user, "
|
|
706
|
+
or self.permission_policy.user_has_permission(self.request.user, "add")
|
|
578
707
|
) and not self.object.active
|
|
579
708
|
|
|
580
709
|
# TODO: add warning msg when there are pages/snippets currently on this task in a workflow, add interaction like resetting task state when saved
|
|
@@ -626,7 +755,7 @@ def enable_task(request, pk):
|
|
|
626
755
|
task = get_object_or_404(Task, id=pk)
|
|
627
756
|
|
|
628
757
|
# Check permissions
|
|
629
|
-
if not task_permission_policy.user_has_permission(request.user, "
|
|
758
|
+
if not task_permission_policy.user_has_permission(request.user, "add"):
|
|
630
759
|
raise PermissionDenied
|
|
631
760
|
|
|
632
761
|
# Set workflow to active if inactive
|
wagtail/admin/viewsets/model.py
CHANGED
|
@@ -649,8 +649,8 @@ class ModelViewSet(ViewSet):
|
|
|
649
649
|
def _legacy_urlpatterns(self):
|
|
650
650
|
# RemovedInWagtail70Warning: Remove legacy URL patterns
|
|
651
651
|
return [
|
|
652
|
-
path("<
|
|
653
|
-
path("<
|
|
652
|
+
path("<str:pk>/", self.redirect_to_edit_view),
|
|
653
|
+
path("<str:pk>/delete/", self.redirect_to_delete_view),
|
|
654
654
|
]
|
|
655
655
|
|
|
656
656
|
def on_register(self):
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from django.urls import path
|
|
2
|
+
|
|
3
|
+
from wagtail.admin.views.pages.choose_parent import ChooseParentView
|
|
4
|
+
from wagtail.admin.views.pages.listing import IndexView
|
|
5
|
+
from wagtail.models import Page
|
|
6
|
+
|
|
7
|
+
from .base import ViewSet
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PageListingViewSet(ViewSet):
|
|
11
|
+
"""
|
|
12
|
+
A viewset to present a flat listing of all pages of a specific type.
|
|
13
|
+
All attributes and methods from :class:`~wagtail.admin.viewsets.base.ViewSet`
|
|
14
|
+
are available.
|
|
15
|
+
For more information on how to use this class, see :ref:`custom_page_listings`.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
#: The view class to use for the index view; must be a subclass of ``wagtail.admin.views.pages.listing.IndexView``.
|
|
19
|
+
index_view_class = IndexView
|
|
20
|
+
#: The view class to use for choosing the parent page when creating a new page of this page type.
|
|
21
|
+
choose_parent_view_class = ChooseParentView
|
|
22
|
+
#: Required; the page model class that this viewset will work with.
|
|
23
|
+
model = Page
|
|
24
|
+
#: A list of ``wagtail.admin.ui.tables.Column`` instances for the columns in the listing.
|
|
25
|
+
columns = IndexView.columns
|
|
26
|
+
#: A subclass of ``wagtail.admin.filters.WagtailFilterSet``, which is a
|
|
27
|
+
#: subclass of `django_filters.FilterSet <https://django-filter.readthedocs.io/en/stable/ref/filterset.html>`_.
|
|
28
|
+
#: This will be passed to the ``filterset_class`` attribute of the index view.
|
|
29
|
+
filterset_class = IndexView.filterset_class
|
|
30
|
+
|
|
31
|
+
def get_common_view_kwargs(self, **kwargs):
|
|
32
|
+
return super().get_common_view_kwargs(
|
|
33
|
+
**{
|
|
34
|
+
"_show_breadcrumbs": True,
|
|
35
|
+
"header_icon": self.icon,
|
|
36
|
+
"model": self.model,
|
|
37
|
+
"index_url_name": self.get_url_name("index"),
|
|
38
|
+
"add_url_name": self.get_url_name("choose_parent"),
|
|
39
|
+
**kwargs,
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def get_index_view_kwargs(self, **kwargs):
|
|
44
|
+
return {
|
|
45
|
+
"index_results_url_name": self.get_url_name("index_results"),
|
|
46
|
+
"columns": self.columns,
|
|
47
|
+
"filterset_class": self.filterset_class,
|
|
48
|
+
**kwargs,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
def get_choose_parent_view_kwargs(self, **kwargs):
|
|
52
|
+
return kwargs
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def index_view(self):
|
|
56
|
+
return self.construct_view(
|
|
57
|
+
self.index_view_class, **self.get_index_view_kwargs()
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def index_results_view(self):
|
|
62
|
+
return self.construct_view(
|
|
63
|
+
self.index_view_class, **self.get_index_view_kwargs(), results_only=True
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def choose_parent_view(self):
|
|
68
|
+
return self.construct_view(
|
|
69
|
+
self.choose_parent_view_class, **self.get_choose_parent_view_kwargs()
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def get_urlpatterns(self):
|
|
73
|
+
return [
|
|
74
|
+
path("", self.index_view, name="index"),
|
|
75
|
+
path("results/", self.index_results_view, name="index_results"),
|
|
76
|
+
path("choose_parent/", self.choose_parent_view, name="choose_parent"),
|
|
77
|
+
]
|
wagtail/admin/wagtail_hooks.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from django.conf import settings
|
|
2
2
|
from django.contrib.auth.models import Permission
|
|
3
|
-
from django.urls import reverse
|
|
3
|
+
from django.urls import reverse, reverse_lazy
|
|
4
4
|
from django.utils.functional import cached_property
|
|
5
5
|
from django.utils.http import urlencode
|
|
6
6
|
from django.utils.translation import gettext
|
|
@@ -743,6 +743,21 @@ def register_core_features(features):
|
|
|
743
743
|
# Keep pasted links with http/https protocol, and not-pasted links (href = undefined).
|
|
744
744
|
"href": "^(http:|https:|undefined$)",
|
|
745
745
|
},
|
|
746
|
+
"chooserUrls": {
|
|
747
|
+
"pageChooser": reverse_lazy("wagtailadmin_choose_page"),
|
|
748
|
+
"externalLinkChooser": reverse_lazy(
|
|
749
|
+
"wagtailadmin_choose_page_external_link"
|
|
750
|
+
),
|
|
751
|
+
"emailLinkChooser": reverse_lazy(
|
|
752
|
+
"wagtailadmin_choose_page_email_link"
|
|
753
|
+
),
|
|
754
|
+
"phoneLinkChooser": reverse_lazy(
|
|
755
|
+
"wagtailadmin_choose_page_phone_link"
|
|
756
|
+
),
|
|
757
|
+
"anchorLinkChooser": reverse_lazy(
|
|
758
|
+
"wagtailadmin_choose_page_anchor_link"
|
|
759
|
+
),
|
|
760
|
+
},
|
|
746
761
|
},
|
|
747
762
|
js=[
|
|
748
763
|
"wagtailadmin/js/page-chooser-modal.js",
|
|
@@ -960,7 +975,7 @@ def register_reports_menu():
|
|
|
960
975
|
|
|
961
976
|
@hooks.register("register_help_menu_item")
|
|
962
977
|
def register_whats_new_in_wagtail_version_menu_item():
|
|
963
|
-
version = "6.
|
|
978
|
+
version = "6.1"
|
|
964
979
|
return DismissibleMenuItem(
|
|
965
980
|
_("What's new in Wagtail %(version)s") % {"version": version},
|
|
966
981
|
wagtail_feature_release_whats_new_link(),
|
|
@@ -983,6 +998,28 @@ def register_editors_guide_menu_item():
|
|
|
983
998
|
)
|
|
984
999
|
|
|
985
1000
|
|
|
1001
|
+
@hooks.register("register_help_menu_item")
|
|
1002
|
+
def register_keyboard_shortcuts_menu_item():
|
|
1003
|
+
"""
|
|
1004
|
+
Triggers the keyboard shortcuts dialog to open when clicked
|
|
1005
|
+
while preventing the default link click action.
|
|
1006
|
+
"""
|
|
1007
|
+
|
|
1008
|
+
return MenuItem(
|
|
1009
|
+
_("Shortcuts"),
|
|
1010
|
+
icon_name="keyboard",
|
|
1011
|
+
order=1200,
|
|
1012
|
+
attrs={
|
|
1013
|
+
"role": "button", # Ensure screen readers announce this as a button
|
|
1014
|
+
"data-a11y-dialog-show": "keyboard-shortcuts-dialog",
|
|
1015
|
+
"data-action": "w-action#noop:prevent:stop",
|
|
1016
|
+
"data-controller": "w-action",
|
|
1017
|
+
},
|
|
1018
|
+
name="keyboard-shortcuts-trigger",
|
|
1019
|
+
url="#",
|
|
1020
|
+
)
|
|
1021
|
+
|
|
1022
|
+
|
|
986
1023
|
@hooks.register("register_admin_menu_item")
|
|
987
1024
|
def register_help_menu():
|
|
988
1025
|
return DismissibleSubmenuMenuItem(
|
|
@@ -1061,6 +1098,7 @@ def register_icons(icons):
|
|
|
1061
1098
|
"info-circle.svg",
|
|
1062
1099
|
"italic.svg",
|
|
1063
1100
|
"key.svg",
|
|
1101
|
+
"keyboard.svg",
|
|
1064
1102
|
"link.svg",
|
|
1065
1103
|
"link-external.svg",
|
|
1066
1104
|
"list-ol.svg",
|
wagtail/admin/widgets/button.py
CHANGED
|
@@ -103,20 +103,20 @@ class HeaderButton(Button):
|
|
|
103
103
|
classname="",
|
|
104
104
|
icon_name=None,
|
|
105
105
|
attrs={},
|
|
106
|
+
icon_only=False,
|
|
106
107
|
**kwargs,
|
|
107
108
|
):
|
|
108
|
-
classname = f"{classname} w-header-button".strip()
|
|
109
|
+
classname = f"{classname} w-header-button button".strip()
|
|
109
110
|
attrs = attrs.copy()
|
|
110
|
-
|
|
111
|
-
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
)
|
|
111
|
+
if icon_only:
|
|
112
|
+
controller = f"{attrs.get('data-controller', '')} w-tooltip".strip()
|
|
113
|
+
attrs["data-controller"] = controller
|
|
114
|
+
attrs["data-w-tooltip-content-value"] = label
|
|
115
|
+
attrs["aria-label"] = label
|
|
116
|
+
label = ""
|
|
117
|
+
|
|
118
118
|
super().__init__(
|
|
119
|
-
label=
|
|
119
|
+
label=label,
|
|
120
120
|
url=url,
|
|
121
121
|
classname=classname,
|
|
122
122
|
icon_name=icon_name,
|
wagtail/api/v2/filters.py
CHANGED
|
@@ -221,7 +221,7 @@ class AncestorOfFilter(BaseFilterBackend):
|
|
|
221
221
|
|
|
222
222
|
class DescendantOfFilter(BaseFilterBackend):
|
|
223
223
|
"""
|
|
224
|
-
Implements the ?
|
|
224
|
+
Implements the ?descendant_of filter which limits the set of pages to a
|
|
225
225
|
particular branch of the page tree.
|
|
226
226
|
"""
|
|
227
227
|
|
|
@@ -197,7 +197,7 @@ class TestPageListing(WagtailTestUtils, TestCase):
|
|
|
197
197
|
self.assertTrue(blog_page_seen, msg="No blog pages were found in the items")
|
|
198
198
|
self.assertTrue(event_page_seen, msg="No event pages were found in the items")
|
|
199
199
|
|
|
200
|
-
def
|
|
200
|
+
def test_non_existent_type_gives_error(self):
|
|
201
201
|
response = self.get_response(type="demosite.IDontExist")
|
|
202
202
|
content = json.loads(response.content.decode("UTF-8"))
|
|
203
203
|
|
wagtail/blocks/base.py
CHANGED
|
@@ -143,10 +143,10 @@ class Block(metaclass=BaseBlock):
|
|
|
143
143
|
Return this block's default value (conventionally found in self.meta.default),
|
|
144
144
|
converted to the value type expected by this block. This caters for the case
|
|
145
145
|
where that value type is not something that can be expressed statically at
|
|
146
|
-
model definition
|
|
147
|
-
pointer back to the block
|
|
146
|
+
model definition time (e.g. something like StructValue which incorporates a
|
|
147
|
+
pointer back to the block definition object).
|
|
148
148
|
"""
|
|
149
|
-
return self.meta.default
|
|
149
|
+
return self.normalize(self.meta.default)
|
|
150
150
|
|
|
151
151
|
def clean(self, value):
|
|
152
152
|
"""
|
|
@@ -159,6 +159,15 @@ class Block(metaclass=BaseBlock):
|
|
|
159
159
|
"""
|
|
160
160
|
return value
|
|
161
161
|
|
|
162
|
+
def normalize(self, value):
|
|
163
|
+
"""
|
|
164
|
+
Given a value for any acceptable type for this block (e.g. string or RichText for a RichTextBlock;
|
|
165
|
+
dict or StructValue for a StructBlock), return a value of the block's native type (e.g. RichText
|
|
166
|
+
for RichTextBlock, StructValue for StructBlock). In simple cases this will return the value
|
|
167
|
+
unchanged.
|
|
168
|
+
"""
|
|
169
|
+
return value
|
|
170
|
+
|
|
162
171
|
def to_python(self, value):
|
|
163
172
|
"""
|
|
164
173
|
Convert 'value' from a simple (JSON-serialisable) value to a (possibly complex) Python value to be
|
|
@@ -167,6 +176,9 @@ class Block(metaclass=BaseBlock):
|
|
|
167
176
|
like the original value but provides a native HTML rendering when inserted into a template; or it
|
|
168
177
|
might be something totally different (e.g. an image chooser will use the image ID as the clean
|
|
169
178
|
value, and turn this back into an actual image object here).
|
|
179
|
+
|
|
180
|
+
For blocks that are usable at the top level of a StreamField, this must also accept any type accepted
|
|
181
|
+
by normalize. (This is because Django calls `Field.to_python` from `Field.clean`.)
|
|
170
182
|
"""
|
|
171
183
|
return value
|
|
172
184
|
|
|
@@ -215,7 +227,7 @@ class Block(metaclass=BaseBlock):
|
|
|
215
227
|
Return the template to use for rendering the block if specified on meta class.
|
|
216
228
|
This extraction was added to make dynamic templates possible if you override this method
|
|
217
229
|
|
|
218
|
-
value contains the current value of the block, allowing
|
|
230
|
+
value contains the current value of the block, allowing overridden methods to
|
|
219
231
|
select the proper template based on the actual block value.
|
|
220
232
|
"""
|
|
221
233
|
return getattr(self.meta, "template", None)
|
|
@@ -564,14 +576,11 @@ class BlockWidget(forms.Widget):
|
|
|
564
576
|
error = errors.as_data()[0]
|
|
565
577
|
error_json = json.dumps(get_error_json_data(error))
|
|
566
578
|
else:
|
|
567
|
-
error_json =
|
|
579
|
+
error_json = json.dumps(None)
|
|
568
580
|
|
|
569
581
|
return format_html(
|
|
570
582
|
"""
|
|
571
|
-
<div id="{id}" data-block="
|
|
572
|
-
<script>
|
|
573
|
-
initBlockWidget('{id}');
|
|
574
|
-
</script>
|
|
583
|
+
<div id="{id}" data-block data-controller="w-block" data-w-block-data-value="{block_json}" data-w-block-arguments-value="[{value_json},{error_json}]"></div>
|
|
575
584
|
""",
|
|
576
585
|
id=name,
|
|
577
586
|
block_json=self.block_json,
|
wagtail/blocks/field_block.py
CHANGED
|
@@ -687,12 +687,6 @@ class RichTextBlock(FieldBlock):
|
|
|
687
687
|
self.search_index = search_index
|
|
688
688
|
super().__init__(**kwargs)
|
|
689
689
|
|
|
690
|
-
def get_default(self):
|
|
691
|
-
if isinstance(self.meta.default, RichText):
|
|
692
|
-
return self.meta.default
|
|
693
|
-
else:
|
|
694
|
-
return RichText(self.meta.default)
|
|
695
|
-
|
|
696
690
|
def to_python(self, value):
|
|
697
691
|
# convert a source-HTML string from the JSONish representation
|
|
698
692
|
# to a RichText object
|
|
@@ -703,6 +697,11 @@ class RichTextBlock(FieldBlock):
|
|
|
703
697
|
# the JSONish representation
|
|
704
698
|
return value.source
|
|
705
699
|
|
|
700
|
+
def normalize(self, value):
|
|
701
|
+
if isinstance(value, RichText):
|
|
702
|
+
return value
|
|
703
|
+
return RichText(value)
|
|
704
|
+
|
|
706
705
|
@cached_property
|
|
707
706
|
def field(self):
|
|
708
707
|
from wagtail.admin.rich_text import get_rich_text_editor_widget
|
|
@@ -757,11 +756,14 @@ class RawHTMLBlock(FieldBlock):
|
|
|
757
756
|
super().__init__(**kwargs)
|
|
758
757
|
|
|
759
758
|
def get_default(self):
|
|
760
|
-
return
|
|
759
|
+
return self.normalize(self.meta.default or "")
|
|
761
760
|
|
|
762
761
|
def to_python(self, value):
|
|
763
762
|
return mark_safe(value)
|
|
764
763
|
|
|
764
|
+
def normalize(self, value):
|
|
765
|
+
return mark_safe(value)
|
|
766
|
+
|
|
765
767
|
def get_prep_value(self, value):
|
|
766
768
|
# explicitly convert to a plain string, just in case we're using some serialisation method
|
|
767
769
|
# that doesn't cope with SafeString values correctly
|
wagtail/blocks/list_block.py
CHANGED
|
@@ -151,10 +151,6 @@ class ListBlock(Block):
|
|
|
151
151
|
# Default to a list consisting of one empty (i.e. default-valued) child item
|
|
152
152
|
self.meta.default = [self.child_block.get_default()]
|
|
153
153
|
|
|
154
|
-
def get_default(self):
|
|
155
|
-
# wrap with list() so that each invocation of get_default returns a distinct instance
|
|
156
|
-
return ListValue(self, values=list(self.meta.default))
|
|
157
|
-
|
|
158
154
|
def value_from_datadict(self, data, files, prefix):
|
|
159
155
|
count = int(data["%s-count" % prefix])
|
|
160
156
|
child_blocks_with_indexes = []
|
|
@@ -183,8 +179,7 @@ class ListBlock(Block):
|
|
|
183
179
|
def clean(self, value):
|
|
184
180
|
# value is expected to be a ListValue, but if it's been assigned through external code it might
|
|
185
181
|
# be a plain list; normalise it to a ListValue
|
|
186
|
-
|
|
187
|
-
value = ListValue(self, values=value)
|
|
182
|
+
value = self.normalize(value)
|
|
188
183
|
|
|
189
184
|
result = []
|
|
190
185
|
block_errors = {}
|
|
@@ -224,6 +219,21 @@ class ListBlock(Block):
|
|
|
224
219
|
|
|
225
220
|
return ListValue(self, bound_blocks=result)
|
|
226
221
|
|
|
222
|
+
def normalize(self, value):
|
|
223
|
+
if isinstance(value, ListValue):
|
|
224
|
+
return value
|
|
225
|
+
elif isinstance(value, list):
|
|
226
|
+
return ListValue(
|
|
227
|
+
self, values=[self.child_block.normalize(x) for x in value]
|
|
228
|
+
)
|
|
229
|
+
else:
|
|
230
|
+
raise TypeError(
|
|
231
|
+
f"Cannot handle {value!r} (type {type(value)!r}) as a value of a ListBlock"
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
def empty_value(self):
|
|
235
|
+
return ListValue(self, values=[])
|
|
236
|
+
|
|
227
237
|
def _item_is_in_block_format(self, item):
|
|
228
238
|
# check a list item retrieved from the database JSON representation to see whether it follows
|
|
229
239
|
# the new format (https://github.com/wagtail/rfcs/blob/main/text/065-listblock.md) for a list item
|