umanit / twig-image-extension
一个用于简化在Twig模板中集成响应式图片标记的扩展。
Requires
- php: ^7.4|^8.0
- ext-mbstring: *
- liip/imagine-bundle: ^2.3
- twig/twig: ^2.12|^3.0
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
结尾的过滤器将提供超大默认图像 - 以
xl
或xxl
结尾的过滤器将提供大默认图像 - 以
xs
或xxs
结尾的过滤器将提供小默认图像 - 任何其他过滤器名称将默认为中等尺寸
twig_image_extension.use_liip_default_image
此参数仅在allow_fallback
设置为false
时用作备份,并需要您使用Liip的默认图像机制(见Liip配置)
用法
以下Twig函数可在您的模板中使用。
- umanit_image_figure_lazy_load
- umanit_image_figure
- umanit_image_picture_lazy_load
- umanit_image_picture
- umanit_image_img
- umanit_image_srcset
- (可选) 实例化yall.js的JavaScript模块
- (可选) 导入CSS文件以在yall.js懒加载图像上实现模糊效果
当使用LiipImagine过滤器时,扩展将读取其配置并自动猜测在标记中应用的正确宽度或高度。如果不可能,扩展将尝试获取原始图像的尺寸。在这两种情况下,结果都保存在缓存中,以避免对相同图像进行多次处理。
当使用的函数是用于懒加载时,会使用lazy
和lazy-placeholder
类,但可以根据配置部分进行自定义。
在 <img />
标签中添加了 width
和 height
属性,基于 src
过滤器计算出的尺寸(除了 downscale
和 upscale
过滤器,它们将回退到原始图像大小)。这样做可以避免布局突然移动,从而提供更好的用户体验。
要使用 htmlAlt
,必须加载 css 文件 umanit-alt-text.css
。它隐藏了用于显示 html alt 内容的 div
。
umanit_image_figure_lazy_load
生成一个包含 img
的 figure
标签和它的 noscript
版本。添加了 lazy
、lazy-placeholder
和 lazy-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
生成一个包含 img
的 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', '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 个 source
的 picture
标签。如果需要,每个 source
都可以有一个 media
和 sizes
属性。添加了 lazy
和 lazy-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 个 source
的 picture
标签。如果需要,每个 source
都可以有一个 media
和 sizes
属性。
参数
示例
点击显示
无 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.js 的 load
事件中被调用。
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 请求。对于重大更改,请首先打开一个问题来讨论您想要更改的内容。