Wagtail now provides a set of utilities for creating data migrations on StreamField data. For more information, see [StreamField data migrations](streamfield_data_migrations). This feature was developed by Sandil Ranasinghe, initially as the [wagtail-streamfield-migration-toolkit](https://github.com/wagtail/wagtail-streamfield-migration-toolkit) add-on package, as part of the Google Summer of Code 2022 initiative, with support from Jacob Topp-Mugglestone, Joshua Munn and Karl Hobley.
Snippets can now be locked by users to prevent other users from editing, through the use of the `LockableMixin`. For more details, see [](wagtailsnippets_locking_snippets).
Wagtail now provides a `fullpageurl` template tag (for both Django templates and Jinja2) to output a page's full URL including the domain. For more details, see [](fullpageurl_tag).
Following feedback from Wagtail users on [rich text UI improvements in Wagtail 4.0](rich_text_improvements_4), we have further refined the behavior of rich text fields to cater for different scenarios:
- Users can now choose between an “inline” floating toolbar, and a fixed toolbar at the top of the editor. Both toolbars display all formatting options.
- The ‘/’ command palette and block picker in rich text fields now contain all formatting options except text styles.
- The ‘/’ command palette and block picker are now always available no matter where the cursor is placed, to support inserting content at any point within text, transforming existing content, and splitting StreamField blocks in the middle of a paragraph when needed.
Thank you to all who provided feedback, participants to our usability testing sessions, and to Nick Lee and Thibaud Colas for the implementation.
A new panel type [](multiple_chooser_panel) is available. This is a variant of `InlinePanel` which improves the editor experience when adding large numbers of linked item - rather than creating and populating each sub-form individually, a chooser modal is opened allowing multiple objects to be selected at once.
This feature was developed by Matt Westcott, and sponsored by [YouGov](https://yougov.com/).
* Test assertion [`WagtailPageTestCase.assertCanCreate`](testing_reference) now supports the kwarg `publish=True` to check publish redirection (Harry Percival, Akua Dokua Asiedu)
* Add full support for secondary buttons with icons in the Wagtail design system - `button bicolor button--icon button-secondary` including the `button-small` variant (Seremba Patrick)
* Add ability to include [`form_fields` as an APIField](form_page_fields_api_field) on `FormPage` (Sævar Öfjörð Magnússon, Suyash Singh, LB (Ben) Johnston)
* Resolve issue where workflow and other notification emails would not include the correct tab URL for account notification management (LB (Ben) Johnston)
* Wagtail's documentation (v2.9 to v4.0) has been updated on [Dash user contributions](https://github.com/Kapeli/Dash-User-Contributions) for [Dash](https://kapeli.com/dash) or [Zeal](https://zealdocs.org/) offline docs applications (Damilola Oladele, Mary Ayobami, Elizabeth Bassey)
* Wagtail's documentation (v2 to v4.0) has been added to [DevDocs](https://devdocs.io/wagtail/) which has offline support and is easily accessible in any browser (Vallabh Tiwari)
* Mention the importance of passing `request` and `current_site` to `get_url` on the [performance](performance_overview) documentation page (Jake Howard)
* Document the hook [`register_image_operations`](register_image_operations) and add an example of a [custom Image filter](custom_image_filters) (Coen van der Kamp)
| `tab_nav_link` | `{% include 'wagtailadmin/shared/tabs/tab_nav_link.html' with classname="..." %}` | `{% include 'wagtailadmin/shared/tabs/tab_nav_link.html' with classes="..." %}` |
| `side_panel_button` | `{% include 'wagtailadmin/shared/side_panels/includes/side_panel_button.html' with classname="..." %}` | `{% include 'wagtailadmin/shared/side_panels/includes/side_panel_button.html' with classes="..." %}` |
### `InlinePanel` JavaScript function is now a class
The (internal, undocumented) `InlinePanel` JavaScript function, used to initialise client-side behaviour for inline panels, has been converted to a class. Any user code that calls this function should now replace `InlinePanel(...)` calls with `new InlinePanel(...)`. Additionally, child form controls are now initialised automatically, and so it is no longer necessary to call `initChildControls`, `updateChildCount`, `updateMoveButtonDisabledStates` or `updateAddButtonState`.
Python code that uses the `InlinePanel` panel type is not affected by this change.
The [`wagtailuserbar`](wagtailuserbar_tag) template tag now initialises the userbar as a [Web Component](https://developer.mozilla.org/en-US/docs/Web/Web_Components), with a `wagtail-userbar` custom element using shadow DOM to apply styles without any collisions with the host page.
For any site customising the position of the userbar, target the styles to `wagtail-userbar::part(userbar)` instead of `.wagtail-userbar`. For example:
### Support for legacy versions of `azure-mgmt-cdn` and `azure-mgmt-frontdoor` packages will be dropped
If you are using the front-end cache invalidator module (`wagtail.contrib.frontend_cache`) with Azure CDN or Azure Front Door, the following packages need to be updated:
* For Azure CDN: upgrade `azure-mgmt-cdn` to version 10 or above
* For Azure Front Door: upgrade `azure-mgmt-frontdoor` to version 1 or above
Support for older versions will be dropped in a future release.