首页 > 解决方案 > 我应该如何将 wagtail-lazyimages 与 Wagtail 的 RichTextField 集成?

问题描述

我正在尝试为我的博客文章图片实现延迟加载,但我正在为我的博客文章使用 RichTextField,因此我无法像Wagtail-LazyImages文档建议那样指定每个图片标签。

根据关于 RichTextField internals 的 Wagtail Docs,图像可以存储为,<embed embedtype="image" id="10" alt="A pied wagtail" format="left" />但在渲染时被翻译为<img alt="A pied wagtail" class="richtext-image left" height="294" src="/media/images/pied-wagtail.width-500_ENyKffb.jpg" width="500">意味着并非像 LazyImages 正在寻找的所有显式标记用法。

这更像是一个概念性问题,因为我只是不确定在流程中的哪个位置与 Wagtail 的 RTF 处理挂钩。

我可以利用 register_rich_text_features 钩子为惰性图像创建一个新的“功能”,然后使用惰性图像类吗?

标签: djangolazy-loadingwagtail

解决方案


我通过在文件中子类化格式(更改富文本表示)解决了这个问题image_formats.py。我覆盖了它用占位符image_to_html替换'src'属性并添加'data-src'属性的方法。

不要忘记在关闭标签之前添加像lazysizes这样的延迟加载库。</body>

from django.utils.html import format_html
from django.utils.html import escape
from wagtail.images.formats import Format, register_image_format
from wagtail.images.shortcuts import get_rendition_or_not_found

class LazyImageFormat(Format):
    def image_to_html(self, image, alt_text, extra_attributes=None):

        if extra_attributes is None:
            extra_attributes = {}
        rendition = get_rendition_or_not_found(image, self.filter_spec)

        #Placeholder scaling based on image height. Needed ONLY if you use this SVG "loading" placeholder.
        svg_width = rendition.width//2
        svg_height = rendition.height//2
        load_scale = rendition.height//100

        #Overwriting 'src' and adding 'data-src' attribute. 'src' - can be any placeholder value
        extra_attributes['src'] = format_html('''data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {} {}'%3E%3Ccircle cx='{}' cy='{}' fill='none' stroke='%23393939' stroke-width='{}' r='{}' stroke-dasharray='{} {}' transform='rotate(175 50 50)'%3E%3CanimateTransform attributeName='transform' type='rotate' repeatCount='indefinite' dur='2s' values='0 {} {};360 {} {}' keyTimes='0;1'/%3E%3C/circle%3E%3C/svg%3E''',
            rendition.width, rendition.height, svg_width, svg_height, 5*load_scale, 15*load_scale, 70*load_scale, 25*load_scale, svg_width, svg_height, svg_width, svg_height)
        extra_attributes['data-src'] = rendition.url

        extra_attributes['alt'] = escape(alt_text)
        if self.classnames:
            extra_attributes['class'] = "%s" % escape(self.classnames)

        return rendition.img_tag(extra_attributes)

#register our custom LazyImageFormat and add 'lazyload' class 
register_image_format(LazyImageFormat('lazy_fullwidth', 'Centered-1000 lazy', 'richtext-image centered lazyload', 'width-1000'))
register_image_format(LazyImageFormat('lazy_original', 'Original lazy', 'richtext-image centered lazyload', 'original'))

推荐阅读