使用变量名称中的index.loop创建并设置twig变量的值

最后发布: 2019-06-17 15:36:07


问题

我需要定义一个twig变量名,它可以在变量名中包含一个index.loop值,这样我以后可以在另一个循环中调用它。

我想要做的是:

{% for x in x.y.z %}
{% set myVar~index.loop = aValue %}
{% endfor %}

之后,我可以致电:

{% if myVar2 == aValue %}
{{ display some stuff }}
{% endif %}

我的问题是我无法找出正确的语法来定义变量(myVar~index.loop)。

任何建议,非常感谢。

谢谢

symfony drupal twig
回答

这里有两个问题需要解决:

  1. 您需要扩展twig才能创建动态变量

  2. 特殊变量_context不是(直接)发送到循环,而是存储在_context['_parent']


伸展树枝

class MyTwigExtension implements \Twig\Extension\ExtensionInterface {
    /**
     * Returns the token parser instances to add to the existing list.
     *
     * @return \Twig\TokenParser\TokenParserInterface[]
     */
    public function getTokenParsers() {
        return [];
    }

    /**
     * Returns the node visitor instances to add to the existing list.
     *
     * @return \Twig\NodeVisitor\NodeVisitorInterface[]
     */
    public function getNodeVisitors() {
        return [];
    }

    /**
     * Returns a list of filters to add to the existing list.
     *
     * @return \Twig\TwigFilter[]
     */
    public function getFilters() {
        return [];
    }

    /**
     * Returns a list of tests to add to the existing list.
     *
     * @return \Twig\TwigTest[]
     */
    public function getTests() {
        return [];
    }

    /**
     * Returns a list of functions to add to the existing list.
     *
     * @return \Twig\TwigFunction[]
     */
    public function getFunctions() {
        return [
            new \Twig\TwigFunction('set', [ $this, 'setValue'], [ 'needs_context' => true,]),
        ];
    }

    /**
     * Returns a list of operators to add to the existing list.
     *
     * @return array<array> First array of unary operators, second array of binary operators
     */
    public function getOperators() {
        return [];
    }

    /**
    * Set reference to $context so you can modify existing values
    * Test if key _parent is set. If true this means the function was called inside a loop
    **/
    public function setValue(&$context, $key, $value) {
        if (isset($context['_parent'])) $context['_parent'][$key] = $value;
        $context[$key] = $value;
    }
}

添加扩展到树枝

$twig->addExtension(new \MyTwigExtension());

现在您可以使用模板中的功能set ,例如

{% set foo = 'bar' %}
{% do set('my_var_'~foo, 'foo') %}
{{ my_var_bar }} {# output: foo #}

或在循环内

{% for i in 1..10 %}
    {% do set ('my_var_'~i, i) %}
{% endfor %}

{{ my_var_6 }} {# output: 6 #}

正如我所说,即使needs_context设置为true,特殊变量_context也不会直接发送到函数。 Twig_parent复制_context的当前内容,以便循环获得它自己的私有变量范围,并且不能覆盖_context任何原始值。