# Wagtail 7.3 release notes - IN DEVELOPMENT

_Unreleased_

```{contents}
---
local:
depth: 1
---
```

## What's new

### Settings and custom block layouts for StructBlock

The `StructBlock.Meta` class now supports a `form_layout` attribute that allows you to customize the order and grouping of child blocks in the editing interface. You can provide a list of block names to specify the order, or use the new `BlockGroup` class to create collapsible groups of blocks, including a special "settings" group that is hidden by default. Refer to [](structblock_custom_order_and_grouping) for more details.

This feature was developed by Sage Abdullah, with support from the Wagtail UI team and reference to previous work by Andy Babic.

### llms.txt for docs

The developer documentation and the [Wagtail user guide](https://guide.wagtail.org/) now publish their contents in the [llms.txt format](https://llmstxt.org/). Those files can be used to provide context to Large Language Models on Wagtail projects. For both sites, this includes `llms.txt` files with an index of the site contents, large `llms-full.txt` files with full documentation contents, and Markdown variants of every page (with full docstrings contents):

 * [llms.txt](../llms.txt){.external}
 * [llms-full.txt](../llms-full.txt){.external}
 * Add `.md` at the end of any documentation page URL to view the Markdown output of that page. Examples: [7.3 release notes in Markdown](7.3.html.md){.external}, [StreamField block reference in Markdown](../reference/streamfield/blocks.html.md){.external}
 * [User guide llms.txt](https://guide.wagtail.org/llms.txt)
 * [User guide llms-full.txt](https://guide.wagtail.org/llms-full.txt)

This feature was developed by Thibaud Colas.

### Other features

 * Resize overly large avatar images on upload (Harshit Ranjan)
 * Add natural keys for `Page` and `Collection` models (Samya Aggarwal)
 * Add Loom oEmbed provider (Nick Ivons)
 * Add [`ModelViewSet.pk_path_converter`](ModelViewSet.pk_path_converter) with defaults for `IntegerField` and `UUIDField` primary keys (Seb Corbin)
 * Improve accessibility for sidebar menu with visual active (expanded) menu item indicators (Vignesh Shivhare)
 * Add [`before_edit_setting`](before_edit_setting) / [`after_edit_setting`](after_edit_setting) hooks (Baptiste Mispelon)
 * Lower default AVIF encoding quality from 80 to 73 (Thibaud Colas)
 * Provide a structured rendering of `StreamBlock` in comparison view (Taras Panasiuk)

### Bug fixes

 * Do not try to resolve locale during fixture load (Jake Howard, Seb Corbin)
 * Gracefully handle oEmbed responses with a non-200 status or missing type (Shivam Kumar, Bhavesh Sharma)
 * Keep action button labelled as "Publish" rather than "Schedule to publish" if go-live date has passed (Vishrut Ramraj)
 * Pass accumulated icons to each `register_icons` hook (Joey Jurjens, Sage Abdullah)
 * Skip revisions that are missing the specified field in StreamField migrations (Joshua Munn)
 * Preserve listing search and filter parameters when redirecting from bulk actions (Sage Abdullah)
 * Ensure that object references within `TypedTableBlock` are counted in the reference index (Aman Bora)
 * Fix slug auto-generation when slug field is omitted from page edit form (Pravin Kamble)
 * Ensure `request.is_preview` and `request.preview_mode` are set for password-required responses (Ishtpreet Singh)
 * Optimise storage of redirect paths containing Unicode characters and ensure percent-encoded characters are matched case-insensitively (Andy Babic, Florin Barnea, Aman Bora, Matt Westcott)

### Documentation

 * Recommend running `purge_embeds` after an embed provider changes policies (Paul Souders)
 * Document `WAGTAILIMAGES_FORMAT_CONVERSIONS` in the settings docs (David Buxton)
 * Wording changes to Draftail extension docs to improve searchability (Lasse Schmieding)
 * Fix StreamField param name (Baptiste Mispelon)
 * Clarify that `before_delete_page` and similar hooks only trigger on the individual page view, not bulk actions (Shivam Kumar)
 * Clarify template location in custom user model documentation (Akhil Muraleedharan)
 * Improve signposting for contributor docs (Matt Westcott)
 * Add mention of novalidate attribute in form builder docs (Thibaud Colas)
 * Fix formatting for `PageQuerySet.prefetch_related` performance note (Lasse Schmieding)
 * Fix path to `search.html` in tutorial (Lee Hart)
 * Grammar fixes to contributor guidelines (Biswajeet Yadav)
 * Mention punctuation is unsupported in paths for [`RoutablePageMixin`](routable_page_mixin) (Tibor Leupold)
 * Various typo and grammar fixes (Mustansir Dabhiya)

### Maintenance

 * Dropped support for Django 5.1
 * Updated NPM packages (LB (Ben) Johnston)
 * Rationalize front-end linting tasks and run concurrently (LB (Ben) Johnston)
 * Add a basic set of Storybook stories for the Stimulus Autosize controller (LB (Ben) Johnston)
 * Remove use of `_WAGTAILSEARCH_FORCE_AUTO_UPDATE` in search tests (Matt Westcott)
 * Add unit test for `SubmitController` error handling (LB (Ben) Johnston)
 * Improve nightly release upload scripts (Jake Howard)
 * Upload redundant `latest.whl` nightly build for ease of use with package managers (Sage Abdullah)
 * Move MANIFEST.in settings into pyproject.toml (Pravin Kamble)
 * Fix linting rules B006 (mutable data structures for argument defaults) and B904 (`raise ... from err` within an `except` clause) (Vivek Subramani, Matt Westcott)
 * Remove jQuery dependency for image URL generator (LB (Ben) Johnston)
 * Upgrade to django-modelcluster 6.4.1 for Django 6.0 compatibility (Matt Westcott)
 * Refactor CreateView/EditView validation logic to support non-form validation (Matt Westcott)
 * Formalized support for Django 6.0 (Pravin Kamble)
 * Add `no-jquery` ESLint plugin to start final deprecation of jQuery (LB (Ben) Johnston)


## Upgrade considerations - changes affecting all projects

### Loading of fixtures containing models referencing `Locale`

Previously, when loading fixtures of Page models or other models extending `TranslatableMixin`, missing `locale_id` values would be automatically filled with the default Locale. This could break the setup of TransactionTestCase, and so this functionality has now been removed. Fixtures must now specify an explicit `locale_id` value.

### New default AVIF quality

The `WAGTAILIMAGES_AVIF_QUALITY` default quality for AVIF image conversions has been lowered from 80 to 73, to provide more comparable perceptual quality to the JPEG default of 85, at smaller file sizes. If your site sets `WAGTAILIMAGES_JPEG_QUALITY` lower or higher than the default of 85, consider setting `WAGTAILIMAGES_AVIF_QUALITY` to a correspondingly lower or higher value to maintain consistent quality across formats.

## Upgrade considerations - deprecation of old functionality

## Upgrade considerations - changes affecting Wagtail customizations

## Upgrade considerations - changes to undocumented internals

### Image URL generator changes

The URL `wagtailimages:generate_url` and its associated view class `GenerateURLView` have been replaced. The new dynamic image URL generator UI uses Stimulus, with the URL `wagtailimages:url_generator_output` and the same `URLGeneratorView` as the page itself with async requests now returning HTML partials. Any overrides to those views or their template `wagtailimages/url_generator.html` will need to be adapted.

### Refactored validation logic for generic model `CreateView` and `EditView`

The form validation logic in `wagtail.admin.views.generic.models.CreateView` (aliased as `wagtail.admin.views.generic.CreateView`, and also subclassed as `wagtail.snippets.views.snippets.CreateView`) and `wagtail.admin.views.generic.models.EditView` (aliased as `wagtail.admin.views.generic.EditView`, and also subclassed as `wagtail.snippets.views.snippets.EditView`) has been refactored to better support validation conditions not handled by the form object (such as formsets displayed alongside the form, or a 'locked' status on the model). Any user code that overrides the `post`, `form_valid`, `form_invalid` and/or `get_error_message` methods to implement additional validation will need to be updated. These views now implement a new method `is_valid(form)`, which by default delegates to `form.is_valid()`. To signal a validation error, this method should set the attribute `self.produced_error_message` to the desired error message string, and return `False`. For a generic validation error, this error message string can be obtained from `self.get_error_message()`.
