1515use Symfony \UX \Image \Renderer \ImageRendererInterface ;
1616use Symfony \UX \Image \Renderer \ImageRenderOptions ;
1717use Symfony \UX \Image \Renderer \RenderedImage ;
18+ use Twig \Extension \RuntimeExtensionInterface ;
19+ use Twig \Extra \Html \HtmlExtension ;
1820
1921/**
2022 * Runtime helpers used by the ux_image Twig component.
2123 *
2224 * @author Simon André <smn.andre@gmail.com>
2325 */
24- final class ImageRuntime
26+ final class ImageRuntime implements RuntimeExtensionInterface
2527{
2628 public function __construct (private ImageRendererInterface $ renderer )
2729 {
2830 }
2931
30- public function render (ImageAsset $ asset , ?ImageRenderOptions $ options = null ): RenderedImage
32+ /**
33+ * @param array<string, mixed> $args
34+ */
35+ public function render (array $ args = []): string
36+ {
37+ $ asset = $ args ['src ' ] ?? null ;
38+ unset($ args ['src ' ]);
39+
40+ if (null === $ asset ) {
41+ return '' ;
42+ }
43+ if (!$ asset instanceof ImageAsset) {
44+ throw new \TypeError (\sprintf ('The "src" argument must be an instance of "%s", "%s" given. ' , ImageAsset::class, get_debug_type ($ asset )));
45+ }
46+
47+ $ options = array_intersect_key ($ args , array_flip (['sizes ' , 'alt ' , 'lazy ' , 'fetchpriority ' , 'class ' , 'decoding ' , 'variant ' , 'srcset ' ]));
48+ $ attributes = array_diff_key ($ args , $ options );
49+ foreach ($ attributes as $ name => $ value ) {
50+ $ attributes [$ name ] = HtmlExtension::htmlAttrValue ($ name , $ value );
51+ }
52+ $ options ['attributes ' ] = $ attributes ;
53+ $ options ['fetchpriority ' ] ??= false === ($ options ['lazy ' ] ?? true ) ? 'high ' : 'auto ' ;
54+
55+ return $ this ->renderPicture ($ asset , $ options );
56+ }
57+
58+ private function renderAsset (ImageAsset $ asset , ?ImageRenderOptions $ options = null ): RenderedImage
3159 {
3260 return $ this ->renderer ->render ($ asset , $ options );
3361 }
@@ -63,7 +91,7 @@ public function renderConfigured(ImageAsset $asset, array $options = []): Render
6391 $ srcset = $ options ['srcset ' ] ?? null ;
6492 $ attributes = $ options ['attributes ' ] ?? [];
6593
66- return $ this ->render ($ asset , new ImageRenderOptions (
94+ return $ this ->renderAsset ($ asset , new ImageRenderOptions (
6795 sizes: \is_string ($ sizes ) ? $ sizes : null ,
6896 alt: \is_string ($ alt ) ? $ alt : '' ,
6997 lazy: \is_bool ($ lazy ) ? $ lazy : true ,
@@ -83,32 +111,32 @@ class: \is_string($class) ? $class : '',
83111 */
84112 public function getSources (ImageAsset $ asset ): array
85113 {
86- return $ this ->render ($ asset )->sources ;
114+ return $ this ->renderAsset ($ asset )->sources ;
87115 }
88116
89117 /**
90118 * Returns the fallback src URL using the first jpeg variant or the asset path.
91119 */
92120 public function getFallbackSrc (ImageAsset $ asset ): string
93121 {
94- return $ this ->render ($ asset )->fallbackSrc ;
122+ return $ this ->renderAsset ($ asset )->fallbackSrc ;
95123 }
96124
97125 /**
98126 * Returns srcset string for the fallback <img> tag.
99127 */
100128 public function getFallbackSrcset (ImageAsset $ asset ): ?string
101129 {
102- return $ this ->render ($ asset )->fallbackSrcset ;
130+ return $ this ->renderAsset ($ asset )->fallbackSrcset ;
103131 }
104132
105133 public function getWidth (ImageAsset $ asset ): ?int
106134 {
107- return $ this ->render ($ asset )->width ;
135+ return $ this ->renderAsset ($ asset )->width ;
108136 }
109137
110138 public function getHeight (ImageAsset $ asset ): ?int
111139 {
112- return $ this ->render ($ asset )->height ;
140+ return $ this ->renderAsset ($ asset )->height ;
113141 }
114142}
0 commit comments