The [built-in accessibility checker](authoring_accessible_content) now enforces a new `alt-text-quality` rule, which tests alt text for the presence of known bad patterns such as file extensions. This rule is enabled by default, but can be disabled if necessary.
This feature was implemented by Albina Starykova, with support from the Wagtail accessibility team.
* Support a [`HOSTNAMES` parameter on `WAGTAILFRONTENDCACHE`](frontendcache_multiple_backends) to define which hostnames a backend should respond to (Jake Howard, sponsored by Oxfam America)
### Specifying a dict of distribution IDs for CloudFront cache invalidation is deprecated
Previous versions allowed passing a dict for `DISTRIBUTION_ID` within the `WAGTAILFRONTENDCACHE` configuration for a CloudFront backend, to allow specifying different distribution IDs for different hostnames. This is now deprecated; instead, multiple distribution IDs should be defined as [multiple backends](frontendcache_multiple_backends), with a `HOSTNAMES` parameter to define the hostnames associated with each one. For example, a configuration such as:
Models registered with a `ModelViewSet` will now automatically have their {class}`~django.contrib.auth.models.Permission` objects registered in the Groups administration area. Previously, you need to use the [`register_permissions`](register_permissions) hook to register them.
If you have a model registered with a `ModelViewSet` and you registered the model's permissions using the `register_permissions` hook, you can now safely remove the hook.
If the viewset has {attr}`~wagtail.admin.viewsets.model.ModelViewSet.inspect_view_enabled` set to `True`, all permissions for the model are registered. Otherwise, the "view" permission is excluded from the registration.
To customize which permissions get registered for the model, you can override the {meth}`~wagtail.admin.viewsets.model.ModelViewSet.get_permissions_to_register` method.
This behavior now applies to snippets as well. Previously, the "view" permission for snippets is always registered regardless of `inspect_view_enabled`. If you wish to register the "view" permission, you can enable the inspect view:
```py
class FooViewSet(SnippetViewSet):
...
inspect_view_enabled = True
```
Alternatively, if you wish to register the "view" permission without enabling the inspect view (i.e. the previous behavior), you can override `get_permissions_to_register` like the following:
```py
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
### Changes to report views with the new Universal Listings UI
The report views have been reimplemented to use the new Universal Listings UI, which introduces AJAX-based filtering and support for the `wagtail.admin.ui.tables` framework.
As a result, a number of changes have been made to the `ReportView` and `PageReportView` classes, as well as their templates.
If you have custom report views as documented in [](adding_reports), you will need to make the following changes.
#### Set up the results-only view
Set the `index_url_name` and `index_results_url_name` attributes on the view class:
```diff
class UnpublishedChangesReportView(PageReportView):
If you are only extending the templates to add your own markup for the listing table, you need to change the `template_name` into `results_template_name` on the view class.
```diff
class UnpublishedChangesReportView(PageReportView):
After renaming the template (e.g. `reports/unpublished_changes_report.html` to `reports/unpublished_changes_report_results.html`), you will need to make a few changes to the template's contents:
- The template should extend from `wagtailadmin/reports/base_page_report_results.html`.
- The `listing` and `no_results` blocks should be renamed to `results` and `no_results_message`, respectively.
{% include "reports/include/_list_unpublished_changes.html" %}
{% endblock %}
-{% block no_results %}
+{% block no_results_message %}
<p>No pages with unpublished changes.</p>
{% endblock %}
```
If you need to completely customize the view's template, you can still override the `template_name` attribute on the view class. Note that both `ReportView` and `PageReportView` now use the `wagtailadmin/reports/base_report.html` template, which now extends the `wagtailadmin/generic/listing.html` template. The `wagtailadmin/reports/base_page_report.html` template is now unused and should be replaced with `wagtailadmin/reports/base_report.html`.