Я обновлю нашу ветку до 2.11. В настоящее время мы используем следующий код:
{% set neededFunction = 'someting_dynamic' %}
{% import _self as functions %}
{% if attribute(functions, neededFunction ) is defined %}
{# do something #}
{% else %}
{# do something else #}
{% endif %}
, но после обновления «attribute (functions, requiredFunction)» всегда терпит неудачу. Я думаю, потому что _self сейчас не объект. Но что я могу сделать сейчас, чтобы проверить, существует ли динамическая c именованная функция?
update:
Я попробовал следующее:
{% set neededFunction = 'someting_dynamic' %}
{% import 'myTemplate' as functions %}
{% if attribute(functions, neededFunction ) is defined %}
{# do something #}
{% endif %}
{% if functions.neededFunction is defined %}
{# do something #}
{% endif %}
{% if functions.someting_dynamic is defined %}
{# do something #}
{% endif %}
только последняя работает. Но это не динамично c
обновление: Попробуйте решить проблему с подходом DarkBee.
Теперь есть одна последняя проблема:
Перед тем, как скомпилировать макрос, я хочу проверить, существует ли макрос. Если нет, я хочу вызвать макрос по умолчанию. Но у меня проблема в том, что функция $ не скомпилирована. Могу ли я получить значение скомпилированного содержимого из парсера?
Мой TokenParser:
class DynamicMacro extends \Twig\TokenParser\AbstractTokenParser
{
const MAX_MACROS = 2;
/**
* @var Node
*/
private $firstAvailableNode;
/**
* {@inheritDoc}
*/
public function getTag()
{
return 'dynamic_macro';
}
/**
* {@inheritDoc}
*/
public function parse(Token $token)
{
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();
for ($i = 1; $i <= self::MAX_MACROS; $i++) {
if (!$stream->test(Token::BLOCK_END_TYPE)) {
$this->checkMacro( $token, $name );
}
}
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
return $this->getFirstAvailableNode();
}
private function checkMacro( Token $token, string $name )
{
$stream = $this->parser->getStream();
$stream->expect(\Twig_Token::PUNCTUATION_TYPE);
$function = $stream->expect(\Twig_Token::NAME_TYPE)->getValue();
$arguments = $this->parser->getExpressionParser()->parseArguments(true);
/** @todo: $function -> 'fx' has to be compiled */
if (is_null($this->firstAvailableNode) && $this->parser->hasMacro($function)){
$node = new DynamicMacroNode($name, $function, $arguments, $token->getLine(), $this->getTag());
$this->setFirstAvailableNode($node);
}
}
/**
* @return Node
*/
public function getFirstAvailableNode(): Node
{
if(is_null($this->firstAvailableNode))
return new EmptyNode();
return $this->firstAvailableNode;
}
/**
* @param Node $node
*/
public function setFirstAvailableNode(Node $node)
{
if (is_null($this->firstAvailableNode))
$this->firstAvailableNode = $node;
}
}
Отрезанная ветка:
{% import _self as foo_macro %}
{% set fx = 'foo_function' %}
{% set fxdef = 'foo_function_default' %}
{% dynamic_macro foo_macro.fx('bar', 'foo', 42, fx).fxdef('bar', 'foo', 42, fx) %}
{% macro foo_function_default(bar, foo, int, function) %}
Bar: {{ bar }}<br />
Foo: {{ foo }}<br />
Int: {{ int }}<br />
Fx: {{ function }}<br />
{% endmacro %}