Twig宏内template_from_string无法解析变量的问题求助
解决Twig宏内部使用template_from_string无法解析变量的问题
问题现象
当template_from_string位于Twig的{% macro ... %}宏内部时,模板字符串中的变量(如示例中的{{ AI }})无法被解析;但在宏外部使用时,解析正常。
示例代码如下:
1. example.yaml配置文件
items: item1: item1 item2: | {{ AI }} lorem ipsum dolor sit amet...
2. PHP函数
function AI() { return 'AI<span class="ai-tm">™</span>'; }
3. Timber的functions.php
// Global $context $context['AI'] = AI();
4. Twig模板代码
{# 宏外使用时,template_from_string解析正常 #} <pre>dump(include(template_from_string(items.item2)))</pre> {% macro example_macro(items) %} {# items是从YAML解析的PHP数组,作为参数传入宏 #} {% for item in items %} <p>{{ include(template_from_string(item)) }}</p> {% endfor %} {% endmacro %}
实际输出中,宏内部的{{ AI }}未被解析,仅输出:
<p>lorem ipsum dolor sit amet...</p>
原因分析
Twig宏拥有独立的作用域,默认不会继承全局上下文变量。宏内部只能访问显式传入的参数,因此无法直接获取全局的AI变量,导致template_from_string解析模板字符串时找不到对应变量。
解决方案
方案1:显式传递全局变量到宏中
修改宏的定义,增加参数接收全局变量,并在include时将变量传入模板上下文:
{% macro example_macro(items, AI) %} {% for item in items %} <p>{{ include(template_from_string(item), {'AI': AI}) }}</p> {% endfor %} {% endmacro %}
调用宏时传入全局的AI变量:
{{ _self.example_macro(items, AI) }}
方案2:在宏内部传递全局上下文
利用Twig的_context全局变量,将整个全局上下文传递给include的模板,这样宏内部就能自动继承所有全局变量:
{% macro example_macro(items) %} {% for item in items %} <p>{{ include(template_from_string(item), _context) }}</p> {% endfor %} {% endmacro %}
方案3:将AI注册为Twig全局函数(推荐)
如果希望AI在所有模板(包括宏)中自动可用,可将其注册为Twig全局函数,而非上下文变量:
在Timber的functions.php中修改:
add_filter('timber/twig', function($twig) { $twig->addFunction(new Twig\TwigFunction('AI', 'AI')); return $twig; });
同时更新YAML中的模板字符串为函数调用形式:
item2: | {{ AI() }} lorem ipsum dolor sit amet...
这种方式下,无论在宏内还是宏外,都能正常解析函数调用,无需额外传递变量。
验证结果
应用任意一种方案后,宏内部的template_from_string均可正确解析{{ AI }}(或{{ AI() }}),输出预期内容:
<p>AI<span class="ai-tm">™</span> lorem ipsum dolor sit amet...</p>
内容的提问来源于stack exchange,提问作者Luka Juras
相关产品推荐
相关产品推荐

