template_from_string 的替代方案,用于处理调用自定义 Twig 函数的字符串
Alternative to template_from_string for processing strings with calls to custom Twig functions
除了使用 template_from_string()
评估包含对自定义 Twig 函数(或与此相关的任何其他复杂 Twig 代码)的调用的字符串之外,还有其他方法吗?
这是我现在拥有的代码的简化版本。
{% set content = {
'item_1' : {
'images' : {
'src': 'assets/images/img_1-600.jpg',
'srcset': "{{ assets('assets/images/img_1-600.jpg') }} 600w, {{ assets('assets/images/img_1-1200.jpg') }} 1200w",
}
}
# additional items follow
}
{% for data in content %}
<img src="{{ data.images.src }}" srcset="{{ include(template_from_string(data.images.srcset)) }}" alt="">
{% endfor %}
assets()
函数只是 return 是给定路径的静态资产的修订版本(即 assets('assets/images/img_1-600.jpg)
呈现为类似 'assets/images/img_1-600-a4c2254a6d.jpg)
.
问题始于 img srcset
属性,该属性可能变得相当复杂并且通常包含对需要 return 静态资产修订值的多个资产的引用。
现在我知道我可以修改 assets()
函数来支持那种复杂的场景,但我想保持简单,让 assets()
只处理 1:1 转换.
通过使用 Twig 提供的功能来实现这一点的唯一方法似乎是 template_from_string() 结合 include,这本身并不可怕,但对于评估和渲染这样的简单操作来说确实有点笨重一个字符串。
更不用说 template_from_string
需要默认加载 StringLoaderExtension()
,出于性能原因我想再次避免使用它。
为了避免任何额外的插件,您可以直接连接变量
{% set content = {
'item_1' : {
'images' : {
'src': 'assets/images/img_1-600.jpg',
'srcset': assets('assets/images/img_1-600.jpg')~' 600w,'~assets('assets/images/img_1-1200.jpg')~' 1200w',
}
}
} %}
虽然连接方法不是一个坏主意,但经过深思熟虑后我得出结论,这是使用自定义 Twig 函数更有意义的地方之一。
与简单连接相比,支持使用函数的主要论据是,使用函数无需担心正确格式化模板代码(即忘记资产和大小之间的 space srcset
属性值中的描述符)。
这种方法还完全消除了使用 template_from_string()
或其他扩展依赖项的需要。
这是最终的解决方案。
模板代码,简单明了,有很多概述。
{% set content = {
'item_1' : {
'images' : {
'src': 'assets/images/img-600.jpg',
'srcset': srcset([
[ assets('assets/images/img-600.jpg'), '600w' ],
[ assets('assets/images/img-800.jpg'), '800w' ],
[ assets('assets/images/img-1000.jpg'), '1000w' ],
[ assets('assets/images/img-1200.jpg'), '1200w' ]
]),
}
}
# additional items follow
}
{% for data in content %}
<img src="{{ data.images.src }}" srcset="{{ data.images.srcset }}" alt="">
{% endfor %}
实际的 Twig 函数称为 srcset
,用于根据上述模板中提供的数据为 srcset
属性生成值。
public function srcset(array $srcset)
{
$output = [];
foreach ($srcset as $set) {
// Both parameters need to exist or the set isn't added to the output...
if (!(isset($set[0]) && isset($set[1]))) {
// ... just some exception handling that isn't of relevance for the question
// ...
continue;
}
$output[] = sprintf('%s %s', $set[0], $set[1]);
}
return implode(', ', $output);
}
除了使用 template_from_string()
评估包含对自定义 Twig 函数(或与此相关的任何其他复杂 Twig 代码)的调用的字符串之外,还有其他方法吗?
这是我现在拥有的代码的简化版本。
{% set content = {
'item_1' : {
'images' : {
'src': 'assets/images/img_1-600.jpg',
'srcset': "{{ assets('assets/images/img_1-600.jpg') }} 600w, {{ assets('assets/images/img_1-1200.jpg') }} 1200w",
}
}
# additional items follow
}
{% for data in content %}
<img src="{{ data.images.src }}" srcset="{{ include(template_from_string(data.images.srcset)) }}" alt="">
{% endfor %}
assets()
函数只是 return 是给定路径的静态资产的修订版本(即 assets('assets/images/img_1-600.jpg)
呈现为类似 'assets/images/img_1-600-a4c2254a6d.jpg)
.
问题始于 img srcset
属性,该属性可能变得相当复杂并且通常包含对需要 return 静态资产修订值的多个资产的引用。
现在我知道我可以修改 assets()
函数来支持那种复杂的场景,但我想保持简单,让 assets()
只处理 1:1 转换.
通过使用 Twig 提供的功能来实现这一点的唯一方法似乎是 template_from_string() 结合 include,这本身并不可怕,但对于评估和渲染这样的简单操作来说确实有点笨重一个字符串。
更不用说 template_from_string
需要默认加载 StringLoaderExtension()
,出于性能原因我想再次避免使用它。
为了避免任何额外的插件,您可以直接连接变量
{% set content = {
'item_1' : {
'images' : {
'src': 'assets/images/img_1-600.jpg',
'srcset': assets('assets/images/img_1-600.jpg')~' 600w,'~assets('assets/images/img_1-1200.jpg')~' 1200w',
}
}
} %}
虽然连接方法不是一个坏主意,但经过深思熟虑后我得出结论,这是使用自定义 Twig 函数更有意义的地方之一。
与简单连接相比,支持使用函数的主要论据是,使用函数无需担心正确格式化模板代码(即忘记资产和大小之间的 space srcset
属性值中的描述符)。
这种方法还完全消除了使用 template_from_string()
或其他扩展依赖项的需要。
这是最终的解决方案。
模板代码,简单明了,有很多概述。
{% set content = {
'item_1' : {
'images' : {
'src': 'assets/images/img-600.jpg',
'srcset': srcset([
[ assets('assets/images/img-600.jpg'), '600w' ],
[ assets('assets/images/img-800.jpg'), '800w' ],
[ assets('assets/images/img-1000.jpg'), '1000w' ],
[ assets('assets/images/img-1200.jpg'), '1200w' ]
]),
}
}
# additional items follow
}
{% for data in content %}
<img src="{{ data.images.src }}" srcset="{{ data.images.srcset }}" alt="">
{% endfor %}
实际的 Twig 函数称为 srcset
,用于根据上述模板中提供的数据为 srcset
属性生成值。
public function srcset(array $srcset)
{
$output = [];
foreach ($srcset as $set) {
// Both parameters need to exist or the set isn't added to the output...
if (!(isset($set[0]) && isset($set[1]))) {
// ... just some exception handling that isn't of relevance for the question
// ...
continue;
}
$output[] = sprintf('%s %s', $set[0], $set[1]);
}
return implode(', ', $output);
}