如何将 Twig 表达式作为参数传递给模板,然后使用模板的上下文执行它?

How to pass an Twig expression as a parameter to a template, and then execute it with template's context?

我定义了一个模板,它为我的表单构建了 select 下拉输入:

<p id="{{key | ucfirst}}">
    <span>{{label}} : </span>
    <select required disabled>
        {% for d in data %}
            <option value="{{attribute(d, optionValue)}}" {{(attribute(d, optionValue) == selectedValue)?'selected'}}>{{attribute(d, optionIntitule)}}</option>
        {% endfor %}
    </select>
    <span><em>{{initialValue | default("")}}</em></span>
</p>

然后我只需要包含它,并传递一些数据:

{% include 'selectForm.twig' with {'label': 'Manager'
                                            , 'key': context.manager.id
                                            , 'initialValue': projet.manager.username
                                            , 'data': users
                                            , 'keyValue': 'id'
                                            , 'keyIntitule': 'username'
                                            , 'selectedValue': projet.manager.id) } 
%}

它工作正常,但我想做更多。例如,我想在选项标签中显示对最终用户更有用的值:<option>Username (email)</option><option>Username</option>

所以我想我不能再使用 attribute 功能了。 我想我可以将 an expression 传递给我的模板,如下所示:

{% include 'selectForm.twig' with {..., 'keyIntitule': "#{d.username (d.email)}"} %}

但是表达式是根据直接上下文而不是模板上下文计算的。所以没用。

I also tried with template_from_string但我没有成功(我以前从未使用过此功能...)

有没有办法将表达式传递给另一个模板,并让它根据自己的上下文计算表达式?

如果您想阻止即时上下文,您可以使用 include function instead of include tag。然后您可以通过这种方式禁用上下文(示例取自文档):

{# only the foo variable will be accessible #}
{{ include('template.html', {foo: 'bar'}, with_context = false) }}

如果您使用对象,您可以将 keyIntitule 设置为 uniqueName 并在用户实体中定义新方法:

public function getUniqueName()
{
    return sprintf('%s (%s)', $this->getUsername(), $this->getEmail());
}

Twig 将调用相应的 getter 方法。在这种情况下 uniqueName 转换为 getUniqueName()

我用 Twig 的 template_from_string 函数找到了解决方案:

{% include 'selectForm.twig' with {..., 'keyIntitule': template_from_string("{{d.username}} ({{d.email}})")} %}

然后我使用 keyIntitule 变量作为模板:

<option value="{{attribute(d, optionValue)}}">{% include(keyIntitule) %}</option>

也适用于:

<option value="{{attribute(d, optionValue)}}">{{ include(keyIntitule) }}</option>