Wagtail 6.4 release notes¶
February 3, 2025
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:
Updating the search index
Updating or creating entries for the reference index
Calculating image focal points
Purging frontend caching URLs
Deleting image and document files when the model is deleted
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 picker, 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 Configuring block previews.
This feature was developed by Sage Abdullah and Thibaud Colas.
Headless documentation¶
The new Headless support documentation page curates important information about Wagtail’s 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 release comes with further enhancements to alt text management:
The content modeling accessibility considerations now reflect the latest capabilities for alt text.
The new
ImageBlockalt text is now populated from the image’s default alt text when selecting a new image.The
ImageBlockalt text field is also populated from the image’s default alt text when converting from an ImageChooserBlock.Alt text quality is now checked by default, as was intended with the
alt-text-qualitycontent 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.
Search terms report¶
For users of promoted search results, a new search terms report is available in the admin interface. This report shows terms that website users have searched for, and how many times they have been searched. This can help you understand what your users are looking for, and adjust your search promotions accordingly.
This feature was developed by Noah van der Meer and Sage Abdullah.
Performance optimizations¶
Following from a recent audit, this release comes with performance improvements focused on the user interface.
Prevent main menu from re-rendering when clicking outside while the menu is closed (Sage Abdullah)
Skip loading of unused JavaScript to speed up 404 page rendering (Sage Abdullah)
Remove support for Safari 15 (Thibaud Colas)
Limit tags autocompletion to 10 items and add delay to avoid performance issues with large number of matching tags (Aayushman Singh)
Other features¶
Add the ability to apply basic Page QuerySet optimizations to
specific()sub-queries usingselect_related&prefetch_related, see Page QuerySet reference (Andy Babic)Increase
DATA_UPLOAD_MAX_NUMBER_FIELDSin project template (Matt Westcott)Stop invalid Site hostname records from breaking preview (Matt Westcott)
Set sensible defaults for InlinePanel heading and label (Matt Westcott)
Add the ability to restrict what types of requests a Page supports via
allowed_http_methods(Andy Babic)Only allow selection of valid new parents within the copy Page view (Mauro Soche)
Add
on_serve_pagehook to modify the serving chain of pages (Krystian Magdziarz, Dawid Bugajewski)Add support for
WAGTAIL_GRAVATAR_PROVIDER_URLURLs with query string parameters (Ayaan Qadri, Guilhem Saurel)Add
get_avatar_urlhook 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
pageas a third parameter to theconstruct_wagtail_userbarhook (claudobahn)Enable breadcrumbs in revisions compare view (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
Fuzzyqueries (Tom Usher)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)
Prevent error on lazily loading StreamField blocks after the stream has been modified (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_onlyFieldPanels 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
MultipleChooserPanelusing images or documents work when nested within anInlinePanelwhen no other choosers are in use within the model (Elhussein Almasri)Ensure
MultipleChooserPanelworks after doing a search in the page chooser modal (Matt Westcott)Ensure new
ListBlockinstances 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_pathonImageBlockto prevent errors on commenting (Matt Westcott)Add
aria-expandedattribute to new column button onTypedTableBlockto reflect menu state (Ayaan Qadri, Scott Cranfill)Allow page models to extend base
Pagepanel definitions without importingwagtail.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
WidgetWithScriptby raising it withstacklevel=3(Joren Hammudoglu)Correctly place comment buttons next to date / datetime / time fields. (Srishti Jaiswal)
Add missing
FilterField("created_at")toAbstractDocumentto fix ordering bycreated_atafter 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()fromPage.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
StreamChildrenToListBlockOperationfrom duplicating data across multiple StreamField instances (Joshua Munn)Prevent database error when calling permission_order.register on app ready (Daniel Kirkham, Matt Westcott)
Prevent syntax error on MySQL search when query includes symbols (Matt Westcott)
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 Adding reports 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 startcommand to the management commands reference page (Damilola Oladele)Refine the The project template 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_FIELDSwhen 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_safetoformat_htmlfor 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
AbstractEmailFormorAbstractFormpages (John-Scott Atlakson, LB (Ben) Johnston)Reword
BlogTagIndexPageexample for clarity (Clifford Gama)Change title of blog index page in tutorial to avoid slug issues (Thibaud Colas)
Fix
wagtailcacheandwagtailpagecacheexamples to not use quotes for thefragment_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
HTTPMethodinPage.handle_options_request()docs (Sage Abdullah)Improve Theory 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 the 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/InlinePanelwhere appropriate (Unyime Emmanuel Udoh)Update example for customizing “p-as-heading” accessibility check without overriding built-in checks (Cynthia Kiser)
Document
get_templatemethod on StreamField blocks (Matt Westcott)Revert incorrect example of appending a
RichTextBlockto aStreamField(Matt Westcott)
Maintenance¶
Close open files when reading within utils/setup.py (Ataf Fazledin Ahamed)
Avoid redundant
ALLOWED_HOSTScheck inSite.find_for_request(Jake Howard)Update
CloneControllerto ensure thatadded/clearedevents are not dispatched as cancelable (LB (Ben) Johnston)Remove unused
uuidUMD 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-undeflinter directives withglobalcomments (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
PreviewControllerusage to leverage Stimulus actions instead of callingpreventDefaultmanually (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
ZoneControllerusage (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 a
delayvalue inTagControllerto 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
EditViewto make better use of genericEditView(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_itemsfromwagtail.admin.menu.MenuItem(Srishti Jaiswal)Only call
openpyxlat runtime to improve performance for projects that do not useReportView,SpreadsheetExportMixinandwagtail.contrib.redirects(Sébastien Corbin)Adopt the update value
mpinstead ofmmfor ‘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
venvinstead ofpipenvin 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_revertview to be a subclass ofEditView(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
Background tasks run at end of current transaction¶
Note
The behaviour described here no longer applies as of django-tasks 0.10. Tasks are now enqueued immediately (and executed immediately if ImmediateBackend is in use), and the ENQUEUE_ON_COMMIT setting is no longer available.
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 |
|
Element to append new child forms |
|
Child form element |
|
Deleted form element |
|
|
|
Management field (total forms) |
|
Management field (min forms) |
|
Management field (max forms) |
|
Management field (Delete, within child form) |
|
Add child |
|
Delete child |
|
Usage of nested id structures are no longer required but can be left in place for easier debugging.