Создайте и установите значение переменной ветки, используя index.loop в имени переменной - PullRequest
0 голосов
/ 17 июня 2019

Мне нужно определить имя переменной ветки, которая может включать значение index.loop в имени переменной, чтобы позже я мог вызвать это в другом цикле.

Я пытаюсь что-то сделатькак:

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

Позже я смогу позвонить:

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

Моя проблема в том, что я не могу определить правильный синтаксис для определения переменной (myVar ~ index.loop).

Любые предложения, с благодарностью.

Спасибо

1 Ответ

0 голосов
/ 18 июня 2019

Здесь необходимо решить две проблемы:

  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 #}

Как я уже сказал, специальная переменная _context не отправляется непосредственно в функцию, даже если needs_context установлено в значение true. Twig копирует текущее содержимое _context внутри _parent, так что цикл получает собственную частную область видимости переменных, и вы не можете перезаписать любое оригинальное значение из _context

...