24 KiB
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:
- 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 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 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 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 image’s default alt text when selecting a new image.
- The ImageBlock alt 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-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 usingselect_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 theconstruct_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
FieldPanel
s 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 anInlinePanel
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
onImageBlock
to prevent errors on commenting (Matt Westcott) - Add
aria-expanded
attribute to new column button onTypedTableBlock
to reflect menu state (Ayaan Qadri, Scott Cranfill) - Allow page models to extend base
Page
panel 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
WidgetWithScript
by raising it withstacklevel=3
(Joren Hammudoglu) - Correctly place comment buttons next to date / datetime / time fields. (Srishti Jaiswal)
- Add missing
FilterField("created_at")
toAbstractDocument
to fix ordering bycreated_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()
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
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
toformat_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
orAbstractForm
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
andwagtailpagecache
examples 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
HTTPMethod
inPage.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 inSite.find_for_request
(Jake Howard) - Update
CloneController
to ensure thatadded
/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 withglobal
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 callingpreventDefault
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 inTagController
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 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_items
fromwagtail.admin.menu.MenuItem
(Srishti Jaiswal) - Only call
openpyxl
at runtime to improve performance for projects that do not useReportView
,SpreadsheetExportMixin
andwagtail.contrib.redirects
(Sébastien Corbin) - Adopt the update value
mp
instead ofmm
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 ofpipenv
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 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
Form builder - validation of fields with custom related_name
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.