kopia lustrzana https://github.com/wagtail/wagtail
Add ability to set default configurable attributes to image tags
- Allow users to override the default attributes given to an image - Update tests to account for new tags - Add documentation for custom image attributes - Recommend that loading=lazy & decoding=async be considered for performance in front-end sitespull/9061/head
rodzic
36e4e9b93d
commit
5108b5f82a
|
|
@ -7,6 +7,7 @@ Changelog
|
|||
|
||||
* Add basic keyboard control and screen reader support for page listing re-ordering (Paarth Agarwal, Thomas van der Hoeven)
|
||||
* Add `PageQuerySet.private` method as an alias of `not_public` (Mehrdad Moradizadeh)
|
||||
* Allow setting default attributes on image tags (Jake Howard)
|
||||
* Fix: Prevent `PageQuerySet.not_public` from returning all pages when no page restrictions exist (Mehrdad Moradizadeh)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -83,3 +83,9 @@ TEMPLATES = [{
|
|||
To support high volumes of traffic with excellent response times, we recommend a caching proxy. Both [Varnish](https://varnish-cache.org/) and [Squid](http://www.squid-cache.org/) have been tested in production. Hosted proxies like [Cloudflare](https://www.cloudflare.com/) should also work well.
|
||||
|
||||
Wagtail supports automatic cache invalidation for Varnish/Squid. See [](frontend_cache_purging) for more information.
|
||||
|
||||
### Image attributes
|
||||
|
||||
For some images, it may be beneficial to lazy load images, so the rest of the page can continue to load. It can be configured site-wide [](adding_default_attributes_to_images) or per-image [](image_tag_alt). For more details you can read about the [`loading='lazy'` attribute](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading#images_and_iframes) and the [`'decoding='async'` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-decoding) or this [web.dev article on lazy loading images](https://web.dev/lazy-loading-images/).
|
||||
|
||||
This optimisation is already handled for you for images in the admin site.
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ Wagtail 4.1 is designated a Long Term Support (LTS) release. Long Term Support r
|
|||
* Add basic keyboard control and screen reader support for page listing re-ordering (Paarth Agarwal, Thomas van der Hoeven)
|
||||
* Add `PageQuerySet.private` method as an alias of `not_public` (Mehrdad Moradizadeh)
|
||||
|
||||
* Allow setting default attributes on image tags [](adding_default_attributes_to_images) (Jake Howard)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Prevent `PageQuerySet.not_public` from returning all pages when no page restrictions exist (Mehrdad Moradizadeh)
|
||||
|
||||
|
||||
## Upgrade considerations
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ Wagtail does not allow deforming or stretching images. Image dimension ratios wi
|
|||
|
||||
Wagtail provides two shortcuts to give greater control over the `img` element:
|
||||
|
||||
**1. Adding attributes to the {% image %} tag**
|
||||
### 1. Adding attributes to the {% image %} tag
|
||||
|
||||
Extra attributes can be specified with the syntax `attribute="value"`:
|
||||
|
||||
|
|
@ -171,7 +171,9 @@ Extra attributes can be specified with the syntax `attribute="value"`:
|
|||
|
||||
You can set a more relevant `alt` attribute this way, overriding the one automatically generated from the title of the image. The `src`, `width`, and `height` attributes can also be overridden, if necessary.
|
||||
|
||||
**2. Generating the image "as foo" to access individual properties**
|
||||
You can also add default attributes to all images (a default class or data attribute for example) - see [](adding_default_attributes_to_images).
|
||||
|
||||
### 2. Generating the image "as foo" to access individual properties
|
||||
|
||||
Wagtail can assign the image data to another variable using Django's `as` syntax:
|
||||
|
||||
|
|
@ -228,6 +230,35 @@ Therefore, if you'd added the field `author` to your AbstractImage in the above
|
|||
|
||||
(Due to the links in the database between renditions and their parent image, you _could_ access it as `{{ tmp_photo.image.author }}`, but that has reduced readability.)
|
||||
|
||||
(adding_default_attributes_to_images)=
|
||||
|
||||
## Adding default attributes to all images
|
||||
|
||||
We can configure the `wagtail.images` application to specify additional attributes to add to images. This is done by setting up a custom `AppConfig` class within your project folder (i.e. the package containing the top-level settings and urls modules).
|
||||
|
||||
To do this, create or update your existing `apps.py` file with the following:
|
||||
|
||||
```python
|
||||
from wagtail.images.apps import WagtailImagesAppConfig
|
||||
|
||||
|
||||
class CustomImagesAppConfig(WagtailImagesAppConfig):
|
||||
default_attrs = {"decoding": "async", "loading": "lazy"}
|
||||
```
|
||||
|
||||
Then, replace `wagtail.images` in `settings.INSTALLED_APPS` with the path to `CustomUsersAppConfig`:
|
||||
|
||||
```python
|
||||
INSTALLED_APPS = [
|
||||
...,
|
||||
"myapplication.apps.CustomImagesAppConfig",
|
||||
# "wagtail.images",
|
||||
...,
|
||||
]
|
||||
```
|
||||
|
||||
Now, images created with `{% image %}` will additionally have `decoding="async" loading="lazy"` attributes. This also goes for images added to Rich Text and `ImageBlock` blocks.
|
||||
|
||||
## Alternative HTML tags
|
||||
|
||||
The `as` keyword allows alternative HTML image tags (such as `<picture>` or `<amp-img>`) to be used.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class WagtailImagesAppConfig(AppConfig):
|
|||
label = "wagtailimages"
|
||||
verbose_name = _("Wagtail images")
|
||||
default_auto_field = "django.db.models.AutoField"
|
||||
default_attrs = {}
|
||||
|
||||
def ready(self):
|
||||
register_signal_handlers()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from contextlib import contextmanager
|
|||
from io import BytesIO
|
||||
from typing import Union
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.core import checks
|
||||
from django.core.cache import InvalidCacheBackendError, caches
|
||||
|
|
@ -826,7 +827,11 @@ class AbstractRendition(ImageFileMixin, models.Model):
|
|||
|
||||
def img_tag(self, extra_attributes={}):
|
||||
attrs = self.attrs_dict.copy()
|
||||
|
||||
attrs.update(apps.get_app_config("wagtailimages").default_attrs)
|
||||
|
||||
attrs.update(extra_attributes)
|
||||
|
||||
return mark_safe("<img{}>".format(flatatt(attrs)))
|
||||
|
||||
def __html__(self):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# -*- coding: utf-8 -*
|
||||
import os
|
||||
import unittest.mock
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.core import serializers
|
||||
from django.test import TestCase
|
||||
|
|
@ -55,6 +57,19 @@ class TestImageChooserBlock(TestCase):
|
|||
|
||||
self.assertHTMLEqual(html, expected_html)
|
||||
|
||||
def test_render_with_custom_default_attrs(self):
|
||||
block = ImageChooserBlock()
|
||||
with unittest.mock.patch.object(
|
||||
apps.get_app_config("wagtailimages"),
|
||||
"default_attrs",
|
||||
new={"decoding": "async", "loading": "lazy"},
|
||||
):
|
||||
html = block.render(self.bad_image)
|
||||
self.assertHTMLEqual(
|
||||
html,
|
||||
'<img alt="missing image" src="/media/not-found" width="0" height="0" decoding="async" loading="lazy">',
|
||||
)
|
||||
|
||||
def test_render_missing(self):
|
||||
block = ImageChooserBlock()
|
||||
html = block.render(self.bad_image)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import os
|
||||
import unittest.mock
|
||||
|
||||
from django import template
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.core import serializers
|
||||
from django.template import engines
|
||||
|
|
@ -99,6 +101,19 @@ class TestImagesJinja(TestCase):
|
|||
with self.assertRaises(template.TemplateSyntaxError):
|
||||
self.render('{{ image(myimage, "fill-200×200") }}', {"myimage": self.image})
|
||||
|
||||
def test_custom_default_attrs(self):
|
||||
with unittest.mock.patch.object(
|
||||
apps.get_app_config("wagtailimages"),
|
||||
"default_attrs",
|
||||
new={"decoding": "async", "loading": "lazy"},
|
||||
):
|
||||
self.assertHTMLEqual(
|
||||
self.render(
|
||||
'{{ image(myimage, "width-200") }}', {"myimage": self.bad_image}
|
||||
),
|
||||
'<img alt="missing image" src="/media/not-found" width="0" height="0" decoding="async" loading="lazy">',
|
||||
)
|
||||
|
||||
def test_chaining_filterspecs(self):
|
||||
self.assertHTMLEqual(
|
||||
self.render(
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue