umanit/twig-image-extension

一个用于简化在Twig模板中集成响应式图片标记的扩展。

1.3.0 2024-03-22 07:37 UTC

This package is auto-updated.

Last update: 2024-09-22 08:53:01 UTC


README

此Twig扩展简化了在Twig模板中集成响应式图片标记的过程。

它使用LiipImagineBundle及其过滤器生成包含所有处理响应式图片所需的HTML标记。

它还提供了一个JavaScript模块,可自动实例化yall.js在渲染的图片上。

安装

使用包管理器composer安装此扩展。

composer require umanit/twig-image-extension

将捆绑包加载到您的Symfony项目中。

<?php

# config/bundles.php
return [
    // ...
    Umanit\TwigImage\UmanitTwigImageBundle::class => ['all' => true],
];

(可选) 如果您想使用yall.js的JavaScript模块,请安装捆绑包资源

bin/console assets:install --symlink

配置

umanit_twig_image:
    allow_fallback: false
    use_liip_default_image: false
    class_selector: lazy
    placeholder_class_selector: lazy-placeholder
    blur_class_selector: lazy-blur

某些函数可以渲染带有图像懒加载功能的HTML标记。您可以使用3个选项(class_selector、placeholder_class_selector和blur_class_selector)自定义使用的类。

后备图像

默认情况下,如果函数调用中给出的图像路径为null、空或指向服务器上缺失的文件,则会抛出异常。您有两个选项可以避免这种情况:

  • twig_image_extension.allow_fallback设置为true
  • twig_image_extension.use_liip_default_image设置为true

twig_image_extension.allow_fallback

如果提供的路径指向缺失的文件,将渲染默认图像。默认图像有四种尺寸:

  • 小:320像素宽
  • 中:640像素宽
  • 大:1280像素宽
  • 超大:2560像素宽(主要用于Retina屏幕)

如果需要渲染默认图像,将使用提供的Liip过滤器猜测大小

  • 2x结尾的过滤器将提供超大默认图像
  • xlxxl结尾的过滤器将提供大默认图像
  • xsxxs结尾的过滤器将提供小默认图像
  • 任何其他过滤器名称将默认为中等尺寸

twig_image_extension.use_liip_default_image

此参数仅在allow_fallback设置为false时用作备份,并需要您使用Liip的默认图像机制(见Liip配置

用法

以下Twig函数可在您的模板中使用。

  1. umanit_image_figure_lazy_load
  2. umanit_image_figure
  3. umanit_image_picture_lazy_load
  4. umanit_image_picture
  5. umanit_image_img
  6. umanit_image_srcset
  7. (可选) 实例化yall.js的JavaScript模块
  8. (可选) 导入CSS文件以在yall.js懒加载图像上实现模糊效果

当使用LiipImagine过滤器时,扩展将读取其配置并自动猜测在标记中应用的正确宽度或高度。如果不可能,扩展将尝试获取原始图像的尺寸。在这两种情况下,结果都保存在缓存中,以避免对相同图像进行多次处理。

当使用的函数是用于懒加载时,会使用lazylazy-placeholder类,但可以根据配置部分进行自定义。

<img /> 标签中添加了 widthheight 属性,基于 src 过滤器计算出的尺寸(除了 downscaleupscale 过滤器,它们将回退到原始图像大小)。这样做可以避免布局突然移动,从而提供更好的用户体验。

要使用 htmlAlt,必须加载 css 文件 umanit-alt-text.css。它隐藏了用于显示 html alt 内容的 div

umanit_image_figure_lazy_load

生成一个包含 imgfigure 标签和它的 noscript 版本。添加了 lazylazy-placeholderlazy-blur 类,以便与例如 yall.js 集成。

参数

示例

点击显示
无 htmlAlt
    umanit_image_figure_lazy_load(
      image.path,
      'small_thumbnail',
      'tiny_thumbnail',
      ['thumbnail', 'large_thumbnail'],
      'image alt',
      'img img--cover img--zoom',
      '(min-width: 768px) 33.3vw, 100vw',
      'class-figure',
      'Figcaption text',
      'class-figcaption',
      'high',
      'data-container="a"',
      'data-image="b" data-test'
    )

生成的 HTML

<figure class="class-figure" data-container="a">
<img
    alt="image alt"
    class="lazy lazy-placeholder lazy-blur img img--cover img--zoom"
    src="https://domain.tld/media/cache/tiny_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    data-src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    sizes="(min-width: 768px) 33.3vw, 100vw"
    data-srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
    importance="high"
    data-image="b" data-test
>
<noscript>
  <img
      class="img img--cover img--zoom"
      alt="home"
      src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
      sizes="(min-width: 768px) 33.3vw, 100vw"
      srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
      width="600" height="400"
      importance="high"
      data-image="b" data-test
  >
</noscript>
<figcaption class="class-figcaption">Figcaption text</figcaption>
</figure>
有 htmlAlt
    umanit_image_figure_lazy_load(
      image.path,
      'small_thumbnail',
      'tiny_thumbnail',
      ['thumbnail', 'large_thumbnail'],
      'image alt',
      'img img--cover img--zoom',
      '(min-width: 768px) 33.3vw, 100vw',
      'class-figure',
      'Figcaption text',
      'class-figcaption',
      '<p>Html to describe content</p>'
    )

生成的 HTML

<figure class="class-figure">
<img
    alt=""
    aria-describedby="1234567890"
    class="lazy lazy-placeholder lazy-blur img img--cover img--zoom"
    src="https://domain.tld/media/cache/tiny_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    data-src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    sizes="(min-width: 768px) 33.3vw, 100vw"
    data-srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
>
<noscript>
  <img
      class="img img--cover img--zoom"
      alt=""
      aria-describedby="1234567890"
      src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
      sizes="(min-width: 768px) 33.3vw, 100vw"
      srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
      width="600" height="400"
  >
</noscript>
<figcaption class="class-figcaption">Figcaption text</figcaption>
</figure>
<div id="1234567890"><p>Html to describe content</p></div>

用于 aria-describedby 的 id 是一个随机动态生成的值。

umanit_image_figure

生成一个包含 imgfigure 标签。

参数

示例

点击显示
无 htmlAlt
    umanit_image_figure(
      image.path,
      'small_thumbnail',
      ['thumbnail', 'large_thumbnail'],
      'image alt',
      'img img--cover img--zoom',
      '(min-width: 768px) 33.3vw, 100vw',
      'class-figure',
      'Figcaption text',
      'class-figcaption',
      'low',
      'data-container="a"',
      'data-image="b" data-test'
    )

生成的 HTML

<figure class="class-figure" data-container="a">
<img
    alt="image alt"
    class="img img--cover img--zoom"
    src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    sizes="(min-width: 768px) 33.3vw, 100vw"
    srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
    importance="low"
    importance="high"
    data-image="b" data-test
>
<figcaption class="class-figcaption">Figcaption text</figcaption>
</figure>
有 htmlAlt
     umanit_image_figure(
       image.path,
       'small_thumbnail',
       ['thumbnail', 'large_thumbnail'],
       'image alt',
       'img img--cover img--zoom',
       '(min-width: 768px) 33.3vw, 100vw',
       'class-figure',
       'Figcaption text',
       'class-figcaption',
       '<p>Html to describe content</p>'
     )

生成的 HTML

<figure class="class-figure">
<img
    alt=""
    aria-describedby="1234567890"
    class="lazy lazy-placeholder lazy-blur img img--cover img--zoom"
    src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    sizes="(min-width: 768px) 33.3vw, 100vw"
    srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
>
<figcaption class="class-figcaption">Figcaption text</figcaption>
</figure>
<div id="1234567890"><p>Html to describe content</p></div>

用于 aria-describedby 的 id 是一个随机动态生成的值。

umanit_image_picture_lazy_load

生成一个包含 img 和 X 个 sourcepicture 标签。如果需要,每个 source 都可以有一个 mediasizes 属性。添加了 lazylazy-placeholder 类,以便与例如 yall.js 集成。

参数

示例

点击显示
无 htmlAlt
  umanit_image_picture_lazy_load(
    image.path,
    'small_thumbnail',
    'tiny_thumbnail',
    ['thumbnail', 'large_thumbnail'],
    {
      (image.path): {
        'media': '(min-width: 768px)',
        'sizes': '(min-width: 1400px) 25vw, 50vw',
        'filters': ['thumbnail', 'large_thumbnail']
      },
      (image2.path): ['thumbnail', 'large_thumbnail']
    },
    'alt img',
    'img img-fluid',
    'class-picture',
    'high',
    'data-picture data-markup="c"',
    'data-image="d"
  )

生成的 HTML

<picture class="class-picture" data-picture data-markup="c">
<source media="(min-width: 768px)" sizes="(min-width: 1400px) 25vw, 50vw" srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w" width="600" height="400">
<source srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w" width="300" height="200">
<img
    class="img img-fluid"
    alt="alt img"
    src="https://domain.tld/media/cache/tiny_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    data-src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    data-srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
    importance="high"
    data-image="d"
>
</picture>
有 htmlAlt
  umanit_image_picture_lazy_load(
    image.path,
    'small_thumbnail',
    'tiny_thumbnail',
    ['thumbnail', 'large_thumbnail'],
    {
      (image.path): {
        'media': '(min-width: 768px)',
        'sizes': '(min-width: 1400px) 25vw, 50vw',
        'filters': ['thumbnail', 'large_thumbnail']
      },
      (image2.path): ['thumbnail', 'large_thumbnail']
    },
    'alt img',
    'img img-fluid',
    'class-picture',
    '<p>Html to describe content</p>'
  )

生成的 HTML

<picture class="class-picture">
<source media="(min-width: 768px)" sizes="(min-width: 1400px) 25vw, 50vw" srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w" width="600" height="400">
<source srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg2 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg2 2880w" width="300" height="200">
<img
    class="img img-fluid"
    alt=""
    aria-describedby="1234567890"
    src="https://domain.tld/media/cache/tiny_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    data-src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    data-srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
>
</picture>
<div id="1234567890"><p>Html to describe content</p></div>

用于 aria-describedby 的 id 是一个随机动态生成的值。

umanit_image_picture

生成一个包含 img 和 X 个 sourcepicture 标签。如果需要,每个 source 都可以有一个 mediasizes 属性。

参数

示例

点击显示
无 htmlAlt
  umanit_image_picture(
    image.path,
    'small_thumbnail',
    ['thumbnail', 'large_thumbnail'],
    {
      (image.path): {
        'media': '(min-width: 768px)',
        'sizes': '(min-width: 1400px) 25vw, 50vw',
        'filters': ['thumbnail', 'large_thumbnail']
      },
      (image2.path): ['thumbnail', 'large_thumbnail']
    },
    'alt img',
    'img img-fluid',
    'class-picture',
    'low',
    'data-picture data-markup="c"',
    'data-image="d"
  )

生成的 HTML

<picture class="class-picture" data-picture data-markup="c">
<source media="(min-width: 768px)" sizes="(min-width: 1400px) 25vw, 50vw" srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w" width="600" height="400">
<source srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w" width="300" height="200">
<img
    class="img img-fluid"
    alt="alt img"
    src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
    importance="low"
    data-image="d"
>
</picture>
有 htmlAlt
  umanit_image_picture(
    image.path,
    'small_thumbnail',
    ['thumbnail', 'large_thumbnail'],
    {
      (image.path): {
        'media': '(min-width: 768px)',
        'sizes': '(min-width: 1400px) 25vw, 50vw',
        'filters': ['thumbnail', 'large_thumbnail']
      },
      (image2.path): ['thumbnail', 'large_thumbnail']
    },
    'alt img',
    'img img-fluid',
    'class-picture',
    '<p>Html to describe content</p>'
  )

生成的 HTML

<picture class="class-picture">
<source media="(min-width: 768px)" sizes="(min-width: 1400px) 25vw, 50vw" srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w" width="600" height="400">
<source srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg2 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg2 2880w" width="300" height="200">
<img
    class="img img-fluid"
    alt=""
    aria-describedby="1234567890"
    src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
    srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
    width="600" height="400"
>
</picture>
<div id="1234567890"><p>Html to describe content</p></div>

umanit_image_img

生成一个 img 标签。

参数

示例

点击显示
    umanit_image_img(
      image.path,
      'small_thumbnail',
      ['thumbnail', 'large_thumbnail'],
      'image alt',
      'img img--cover img--zoom',
      '(min-width: 768px) 33.3vw, 100vw',
      'low',
      'data-image="b" data-test'
    )

生成的 HTML

<img
  alt="image alt"
  class="img img--cover img--zoom"
  src="https://domain.tld/media/cache/resolve/small_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg"
  sizes="(min-width: 768px) 33.3vw, 100vw"
  srcset="https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w"
  width="600" height="400"
  importance="low"
  data-image="b" data-test
>

umanit_image_srcset

如果要在您的自己的标记中使用它,则生成 srcset 属性的内容。

参数

示例

点击显示
umanit_image_srcset(image.path, ['thumbnail', 'large_thumbnail'])

生成的 HTML

https://domain.tld/media/cache/resolve/thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 260w, https://domain.tld/media/cache/resolve/large_thumbnail/99/30/c1f268bbf1487fb88734f2ba826b.jpeg 2880w

(可选) 实例化yall.js的JavaScript模块

如果您想使用 yall.js 来管理图像的懒加载,该包提供了一个可以在您的应用程序中调用的 JavaScript 模块。

yall.js 需要手动安装:yarn add yall-js

然后您需要导入模块并通过传递 yall 库来实例化它。如果想要添加更多自定义,有一个可选的参数 loadEventCallback。它将在 yall.jsload 事件中被调用。

import yall from 'yall-js';
import umanitImageLazyLoad from '../../public/bundles/umanittwigimage/js/umanit-image-lazy-loading';

umanitImageLazyLoad(yall);

(可选) 导入CSS文件以在yall.js懒加载图像上实现模糊效果

您可以导入 CSS 文件为懒加载图像添加模糊效果。

<link rel="stylesheet" href="{{ asset('css/umanit-image-lazy-loading.css', 'twig_image_bundle') }}">

webpack 中的示例

import '../../public/bundles/umanittwigimage/css/umanit-image-lazy-loading.css';

⚠ 为了最好地使用无 JavaScript 的用户,您应该在 html 元素上添加一个 no-js

<html class="no-js">

最后,在文档的 <head> 中的任何 <link><style> 元素之前添加这一行 <script>

<!-- Remove the no-js class on the <html> element if JavaScript is on -->
<script>document.documentElement.classList.remove("no-js");</script>

有关更多详细信息,请参阅 https://github.com/malchata/yall.js/#what-about-users-without-javascript

贡献

欢迎 Pull 请求。对于重大更改,请首先打开一个问题来讨论您想要更改的内容。

许可

MIT