Здесь необходимо решить две проблемы:
Вам потребуется расширить twig
для создания динамических переменных
Специальная переменная _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