wagtail/docs/releases/6.4.md

24 KiB
Czysty Wina Historia

Wagtail 6.4 release notes - IN DEVELOPMENT

Unreleased

---
local:
depth: 1
---

What's new

Support for background tasks using django-tasks

Wagtail now integrates with the django-tasks library to allow moving computationally-intensive tasks out of the request-response cycle, and improving the performance of the Wagtail admin interface. These tasks include:

In the default configuration, these tasks are executed immediately within the request-response cycle, as they were in previous versions of Wagtail. However, by configuring the TASKS setting with an appropriate backend as per the django-tasks documentation, these tasks can be deferred to a background worker process.

This feature was developed by Jake Howard.

Previews for StreamField blocks

You can now set up previews for StreamField blocks. The preview will be shown in the block chooser, along with a description for the block. This feature can help users choose the right block when writing content inside a StreamField. To enable this feature, see .

This feature was developed by Sage Abdullah and Thibaud Colas.

Headless documentation

The new documentation page curates important information about Wagtails headless capabilities, directly within the developer documentation. This is the foundation for a headless improvements roadmap for Wagtail.

Thank you to Sævar Öfjörð Magnússon and Alex Fulcher for creating this new page at the Wagtail Space NL 2024 sprint.

Alt text improvements

Building upon improvements in past versions, this releases comes with further enhancements to alt text management:

  • The content modeling accessibility considerations now reflect the latest capabilities for alt text.
  • The new ImageBlock alt text is now populated from the images default alt text when selecting a new image.
  • The ImageBlock alt text field is also populated from the images default alt text when converting from an ImageChooserBlock.
  • Alt text quality is now checked by default as was intended with the alt-text-quality content check.

Thank you to Matt Westcott, Thibaud Colas, and Cynthia Kiser for their work on these improvements.

Shorthand for FieldPanel and InlinePanel

Plain strings can now be used in panel definitions as a substitute for FieldPanel and InlinePanel, avoiding the need to import these classes from wagtail.admin.panels:

class MyPage(Page):
    body = RichTextField()
    content_panels = [
        'body',
    ]

This feature was developed by Matt Westcott.

Drag-and-drop support for StreamField and InlinePanel

The StreamField and InlinePanel interfaces now support drag-and-drop reordering of items within a field. This makes it faster to rearrange content within these fields, particularly when there is a lot of content.

This feature was developed by Thibaud Colas and Sage Abdullah, thanks to a sponsorship by Lyst.

Other features

  • Add search terms report (Noah van der Meer, Sage Abdullah)
  • Add the ability to apply basic Page QuerySet optimizations to specific() sub-queries using select_related & prefetch_related, see (Andy Babic)
  • Increase DATA_UPLOAD_MAX_NUMBER_FIELDS in project template (Matt Westcott)
  • Stop invalid Site hostname records from breaking preview (Matt Westcott)
  • Set sensible defaults for InlinePanel heading and label (Matt Westcott)
  • Limit tags autocompletion to 10 items and add delay to avoid performance issues with large number of matching tags (Aayushman Singh)
  • Add the ability to restrict what types of requests a Pages supports via allowed_http_methods (Andy Babic)
  • Only allow selection of valid new parents within the copy Page view (Mauro Soche)
  • Add on_serve_page hook to modify the serving chain of pages (Krystian Magdziarz, Dawid Bugajewski)
  • Add support for WAGTAIL_GRAVATAR_PROVIDER_URL URLs with query string parameters (Ayaan Qadri, Guilhem Saurel)
  • Add get_avatar_url hook to customise user avatars (James Harrington)
  • Set content security policy (CSP) headers to block embedded content when serving images and documents (Jake Howard, with thanks to Ali İltizar for the initial report)
  • Add page as a third parameter to the construct_wagtail_userbar hook (claudobahn)
  • Enable breadcrumbs in revisions compare view (Sage Abdullah)
  • Skip loading of unused JavaScript to speed up 404 page rendering (Sage Abdullah)
  • Replace l18n library with JavaScript Intl API for time zone options in Account view (Sage Abdullah)
  • Use explicit label for defaulting to server language in account settings (Sage Abdullah)
  • Add support for specifying an operator on Fuzzy queries (Tom Usher)
  • Remove support for Safari 15 (Thibaud Colas)
  • Prevent main menu from re-rendering when clicking outside while the menu is closed (Sage Abdullah)
  • Make sure typing text at the bottom of the page editor always scrolls enough to keep the text into view (Jatin Bhardwaj)

Bug fixes

  • Improve handling of translations for bulk page action confirmation messages (Matt Westcott)
  • Ensure custom rich text feature icons are correctly handled when provided as a list of SVG paths (Temidayo Azeez, Joel William, LB (Ben) Johnston)
  • Ensure manual edits to StreamField values do not throw an error (Stefan Hammer)
  • Fix sub-menus within the main menu cannot be closed on mobile (Bojan Mihelac)
  • Fix animation overflow transition when navigating through subpages in the sidebar page explorer (manu)
  • Ensure form builder supports custom admin form validation (John-Scott Atlakson, LB (Ben) Johnston)
  • Ensure form builder correctly checks for duplicate field names when using a custom related name (John-Scott Atlakson, LB (Ben) Johnston)
  • Normalize StreamField.get_default() to prevent creation forms from breaking (Matt Westcott)
  • Prevent out-of-order migrations from skipping creation of image/document choose permissions (Matt Westcott)
  • Use correct connections on multi-database setups in database search backends (Jake Howard)
  • Ensure Cloudfront cache invalidation is called with a list, for compatibility with current botocore versions (Jake Howard)
  • Show the correct privacy status in the sidebar when creating a new page (Joel William)
  • Prevent generic model edit view from unquoting non-integer primary keys multiple times (Matt Westcott)
  • Ensure comments are functional when editing Page models with read_only FieldPanels in use (Strapchay)
  • Ensure the accessible labels and tooltips reflect the correct private/public status on the live link button within pages after changing the privacy (Ayaan Qadri)
  • Fix empty th (table heading) elements that are not compliant with accessibility standards (Jai Vignesh J)
  • Ensure MultipleChooserPanel using images or documents work when nested within an InlinePanel when no other choosers are in use within the model (Elhussein Almasri)
  • Ensure MultipleChooserPanel works after doing a search in the page chooser modal (Matt Westcott)
  • Ensure new ListBlock instances get created with unique IDs in the admin client for accessibility and mini-map element references (Srishti Jaiswal)
  • Return never-cache HTTP headers when serving pages and documents with view restrictions (Krystian Magdziarz, Dawid Bugajewski)
  • Implement get_block_by_content_path on ImageBlock to prevent errors on commenting (Matt Westcott)
  • Add aria-expanded attribute to new column button on TypedTableBlock to reflect menu state (Ayaan Qadri, Scott Cranfill)
  • Allow page models to extend base Page panel definitions without importing wagtail.admin (Matt Westcott)
  • Fix crash when loading the dashboard with only the "unlock" or "bulk delete" page permissions (Unyime Emmanuel Udoh, Sage Abdullah)
  • Improve deprecation warning for WidgetWithScript by raising it with stacklevel=3 (Joren Hammudoglu)
  • Correctly place comment buttons next to date / datetime / time fields. (Srishti Jaiswal)
  • Add missing FilterField("created_at") to AbstractDocument to fix ordering by created_at after searching in the documents index view (Srishti Jaiswal)
  • Add missing heading and breadcrumbs in Account view (Sage Abdullah)
  • Reduce confusing spacing below StreamField blocks help text (Rishabh Sharma)
  • Prevent redundant calls to Site.find_for_request() from Page.get_url_parts() (Andy Babic)
  • Prevent error on listings when searching and filtering by locale (Matt Westcott, Sage Abdullah)
  • Add missing space in panels check warning message (Stéphane Blondon)
  • Prevent StreamChildrenToListBlockOperation from duplicating data across multiple StreamField instances (Joshua Munn)

Documentation

  • Move the model reference page from reference/pages to the references section as it covers all Wagtail core models (Srishti Jaiswal)
  • Move the panels reference page from references/pages to the references section as panels are available for any model editing, merge panels API into this page (Srishti Jaiswal)
  • Move the tags documentation to standalone advanced topic for tagging, instead of being inside the reference/pages section (Srishti Jaiswal)
  • Refine the page so that common (page/non-page) class references are at the top and the full page only example has correct heading nesting (Alessandro Chitarrini)
  • Add the wagtail start command to the management commands reference page (Damilola Oladele)
  • Refine the page sections and document common issues encountered when creating custom templates (Damilola Oladele)
  • Refine titles, references and URLS to better align with the documentation style guide, including US spelling (Srishti Jaiswal)
  • Recommend a larger DATA_UPLOAD_MAX_NUMBER_FIELDS when integrating Wagtail into Django (Matt Westcott)
  • Improve code highlighting and formatting for Python docstrings in core models (Srishti Jaiswal)
  • Update all JavaScript inline scripts & some CSS inline style tags to a CSP compliant approach by using external scripts/styles (Aayushman Singh)
  • Update usage of mark_safe to format_html for any script inclusions, to better avoid XSS issues from example code (Aayushman Singh)
  • Update documentation writing guidelines to encourage better considerations of security, accessibility and good practice when writing code examples (Aayushman Singh, LB (Ben) Johnston)
  • Update documentation guidelines on writing links and API reference (Sage Abdullah)
  • Replace absolute URLs with intersphinx links where possible to avoid broken links (Sage Abdullah)
  • Update upgrading guide and release process to better reflect the current practices (Sage Abdullah)
  • Document usage of Custom validation for admin form pages when using AbstractEmailForm or AbstractForm pages (John-Scott Atlakson, LB (Ben) Johnston)
  • Reword BlogTagIndexPage example for clarity (Clifford Gama)
  • Change title of blog index page in tutorial to avoid slug issues (Thibaud Colas)
  • Fix wagtailcache and wagtailpagecache examples to not use quotes for the fragment_name (Shiv)
  • Update tutorial to reflect the move of the "Add child page" action to a top-level button in the header as a '+' icon (Clifford Gama)
  • Fix link to HTTPMethod in Page.handle_options_request() docs (Sage Abdullah)
  • Improve with added & more consistent section headings and admonitions to aid in readability (Clifford Gama)
  • Fix non-functional link to the community guidelines in the Your first contribution page (Ankit Kumar)
  • Introduce tags and filters by name in "Writing templates" docs (Clifford Gama)
  • Fix Django HTML syntax formatting issue on the documents overview page (LB (Ben) Johnston)
  • Separate virtual environment creation and activation steps in tutorial (Ankit Kumar)
  • Update tutorial to use plain strings in place of FieldPanel / InlinePanel where appropriate (Unyime Emmanuel Udoh)
  • Update example for customizing "p-as-heading" accessibility check without overriding built-in checks (Cynthia Kiser)
  • Document get_template method on StreamField blocks (Matt Westcott)

Maintenance

  • Close open files when reading within utils/setup.py (Ataf Fazledin Ahamed)
  • Avoid redundant ALLOWED_HOSTS check in Site.find_for_request (Jake Howard)
  • Update CloneController to ensure that added/cleared events are not dispatched as cancelable (LB (Ben) Johnston)
  • Remove unused uuid UMD module as all code is now using the NPM module (LB (Ben) Johnston)
  • Clean up JS comments throughout codebase to be aligned to JSDoc where practical (LB (Ben) Johnston)
  • Replace eslint-disable no-undef linter directives with global comments (LB (Ben) Johnston)
  • Upgrade Node tooling to active LTS version 22 (LB (Ben) Johnston)
  • Remove defunct oEmbed providers (Rahul Samant)
  • Remove obsolete non-upsert-based code for Postgres search indexing (Jake Howard)
  • Remove unused Rangy JS library (LB (Ben) Johnston)
  • Update PreviewController usage to leverage Stimulus actions instead of calling preventDefault manually (Ayaan Qadri)
  • Various performance optimizations to page publishing (Jake Howard)
  • Remove unnecessary DOM canvas.toBlob polyfill (LB (Ben) Johnston)
  • Ensure Storybook core files are correctly running through Eslint (LB (Ben) Johnston)
  • Add a new Stimulus ZoneController (w-zone) to support dynamic class name changes & event handling on container elements (Ayaan Qadri)
  • Migrate jQuery class toggling & drag/drop event handling within the multiple upload views to the Stimulus ZoneController usage (Ayaan Qadri)
  • Test project template for warnings when run against Django pre-release versions (Sage Abdullah)
  • Refactor redirects create/delete views to use generic views (Sage Abdullah)
  • Add JSDoc description, adopt linting recommendations, and add more unit tests for ModalWorkflow (LB (Ben) Johnston)
  • Add support for for a delay value in TagController to debounce async autocomplete tag fetch requests (Aayushman Singh)
  • Add unit tests, Storybook stories & JSDoc items for the Stimulus DrilldownController (Srishti Jaiswal)
  • Enhance sidebar preview performance by eliminating duplicate asset loads on preview error (Sage Abdullah)
  • Remove unused LinkController (w-link) (Sage Abdullah)
  • Refactor settings EditView to make better use of generic EditView (Sage Abdullah)
  • Add a new Stimulus RulesController (w-rules) to support declarative conditional field enabling from other field values in a form (LB (Ben) Johnston)
  • Migrate the conditional enabling of fields in the image URL builder view away from ad-hoc jQuery to use the RulesController (w-rules) approach (LB (Ben) Johnston)
  • Enhance the Stimulus ZoneController (w-zone) to support inactive class and a mechanism to switch the mode based on data within events (Ayaan Qadri)
  • Use the Stimulus ZoneController (w-zone) to remove ad-hoc jQuery for the privacy switch when toggling visibility of private/public elements (Ayaan Qadri)
  • Remove unused is_active & active_menu_items from wagtail.admin.menu.MenuItem (Srishti Jaiswal)
  • Only call openpyxl at runtime to improve performance for projects that do not use ReportView, SpreadsheetExportMixin and wagtail.contrib.redirects (Sébastien Corbin)
  • Adopt the update value mp instead of mm for 'mystery person' as the default Gravatar if no avatar found (Harsh Dange)
  • Refactor search promotions views to use generic views and templates (Sage Abdullah, Rohit Sharma)
  • Use built-in venv instead of pipenv in CircleCI (Sage Abdullah)
  • Add a new Stimulus FormsetController (w-formset) to support dynamic formset insertion/deletion behavior (LB (Ben) Johnston)
  • Enable breadcrumbs by default on admin views using generic templates (Sage Abdullah)
  • Refactor pages revisions_revert view to be a subclass of EditView (Sage Abdullah)
  • Move images and documents get_usage().count() call to view code (Sage Abdullah)
  • Upgrade sass-loader to resolve Sass deprecation warnings (Ayaan Qadri)

Upgrade considerations - changes affecting all projects

DATA_UPLOAD_MAX_NUMBER_FIELDS update

It's recommended that all projects set the DATA_UPLOAD_MAX_NUMBER_FIELDS setting to 10000 or higher.

This specifies the maximum number of fields allowed in a form submission, and it is recommended to increase this from Django's default of 1000, as particularly complex page models can exceed this limit within Wagtail's page editor:

# settings.py
DATA_UPLOAD_MAX_NUMBER_FIELDS = 10_000

On previous releases, form page models (defined through AbstractEmailForm, AbstractForm, FormMixin or EmailFormMixin) did not validate form fields where the related_name was different to the default value of form_fields. As a result, it was possible to create forms with duplicate field names - in this case, only a single field is displayed and captured in the resulting form. As of Wagtail 6.4, validation is now applied on these fields. Existing forms will continue to behave as before and no data will be lost, but editing them will now raise a validation error.

Background tasks run at end of current transaction

In the default configuration, tasks managed by django-tasks (see above) run during the request-response cycle, as before. However, they are now deferred until the current transaction (if any) is committed. If ATOMIC_REQUESTS is set to True, this will be at the end of the request. This may lead to a change of behaviour on views that expect to see the results of these tasks immediately, such as a view that creates a page and then performs a search query to retrieve it. To restore the previous behaviour, set "ENQUEUE_ON_COMMIT": False in the TASKS setting:

# settings.py
TASKS = {
    "default": {
        "BACKEND": "django_tasks.backends.immediate.ImmediateBackend",
        "ENQUEUE_ON_COMMIT": False,
    }
}

Django's test framework typically runs tests inside transactions, and so this situation is also likely to arise in tests that perform database updates and then - within the same test - expect these changes to be immediately reflected in search queries, object usage counts, and other processes that are now handled with background tasks. This can be addressed by setting ENQUEUE_ON_COMMIT to False as above in the test settings, or by wrapping the database updates in with self.captureOnCommitCallbacks(execute=True) to ensure that these tasks are completed before the test continues:

def test_search(self):
    home_page = Page.objects.get(slug="home")

    with self.captureOnCommitCallbacks(execute=True):  # Added
        home_page.add_child(instance=EventPage(title="Christmas party"))

    response = self.client.get("/search/?q=Christmas")
    self.assertContains(response, "Christmas party")

Upgrade considerations - changes affecting Wagtail customizations

Added page as a third parameter to the construct_wagtail_userbar hook

In previous releases, implementations of the construct_wagtail_userbar hook were expected to accept two arguments, whereas now page is passed in as a third argument.

Old

@hooks.register('construct_wagtail_userbar')
def construct_wagtail_userbar(request, items):
    pass

New

@hooks.register('construct_wagtail_userbar')
def construct_wagtail_userbar(request, items, page):
    pass

The old style will now produce a deprecation warning.

Upgrade considerations - changes to undocumented internals

Changes to content_panels, promote_panels and settings_panels values on base Page model

Previously, the content_panels, promote_panels and settings_panels attributes on the base Page model were defined as lists of Panel instances. These lists now contain instances of wagtail.models.PanelPlaceholder instead, which are resolved to Panel instances at runtime. Panel definitions that simply extend these lists (such as content_panels = Page.content_panels + [...]) are unaffected; however, any logic that inspects these lists (for example, finding a panel in the list to insert a new one immediately after it) will need to be updated to handle the new object types.

Removal of unused Rangy JS library

The unused JavaScript include wagtailadmin/js/vendor/rangy-core.js has been removed from the editor interface, and functions such as window.rangy.getSelection() are no longer available. Any code relying on this should now either supply its own copy of the Rangy library, or be migrated to the official Document.createRange() browser API.

Deprecation of window.buildExpandingFormset global function

The undocumented global function window.buildExpandingFormset to attach JavaScript insertion / deletion behavior for Django formsets has been deprecated and will be removed in a future release.

Within the Wagtail admin this only impacts a small set of basic expanding formsets in use across Workflow and Group view editing. InlinePanel is not affected.

Previously these expanding formsets required a mix of specific id attribute structures and inline scripts to instantiate with callbacks for handling deletion. User code implementing this functionality through buildExpandingFormset should be updated - the following data attributes can be used to emulate the same behavior. These are likely to change and should not be considered official documentation.

Element Attribute(s)
Containing element data-controller="w-formset"
Element to append new child forms data-w-formset-target="forms"
Child form element data-w-formset-target="child"
Deleted form element data-w-formset-target="deleted" hidden
template element for blank form data-w-formset-target="template"
Management field (total forms) data-w-formset-target="totalFormsInput"
Management field (min forms) data-w-formset-target="minFormsInput"
Management field (max forms) data-w-formset-target="maxFormsInput"
Management field (Delete, within child form) data-w-formset-target="deleteInput"
Add child button data-action="w-formset#add"
Delete child button (within child form) data-action="w-formset#delete"

Usage of nested id structures are no longer required but can be left in place for easier debugging.