While upgrading twig v1.30 to v3.22.0 i encountered some problem using macros from an external file and calling them by using a variable value as dynamic name.
Given the twig file with the macros:
{# file twig_v3_macros.twig #}
{% macro element1(data) %}
This is my element1 with {{ data.name }} and its value: <b>{{ data.value }}</b><br><br>
{% endmacro %}
{% macro element2(data) %}
This is my element2 with {{ data.name }} and its value: <b>{{ data.value }}</b><br><br>
{% endmacro %}
{% macro element3(data) %}
This is my element3 with {{ data.name }} and its value: <b>{{ data.value }}</b><br><br>
{% endmacro %}
you can import these in a template file like so:
{# file twig_v3_template.twig #}
{% import "twig_v3_macros.twig" as twigmacros %}
{% set myfunction='element1' %}
{% set mydata={ name: 'dataName', value: 'dataValue'} %}
{#
in twig v1.30 you could use the attribute function to dynamically call macros:
{{ attribute(twigmacros, myfunction, [mydata]) }}
The following line breaks in twig 3.22 although it should work
{{ twigmacros.(myfunction)(mydata) }}<br><br>
#}
{# this one works in v3.22, since you directly specify the macro name #}
{{ twigmacros.element1(mydata) }}<br><br>
the php script to use these is mostly:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
require_once '../vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('../includes/templates');
$twig = new \Twig\Environment($loader, [
'debug' => true,
]);
$twig->addExtension(new \Twig\Extension\DebugExtension());
$templateFile = "twig_v3_template.twig";
$objTemplate = $twig->load($templateFile);
$html = $objTemplate->render(
[
'elements' => $arrElements,
]
);
echo $html;
?>
problem description
When using V1.30, you could use the attributes(macroalias, macroname, parameters) function as described in twig attributes function documentation. The page states as well, that this function is deprecated as of twig 3.15 and should be substituted with the dot operator. And using the attributes function in v3.22 results in no output (but no error whatsoever).
from what i understand you should be able to use dynamic names for the methods there as well, so instead of using twigmacros.mymacro(params) you should be able to set a variable with the value mymacro and then call twigmacros.(mymacroname)(params).
unfortunately this does not work but produces an error, which i don't really get right:
Fatal error: Uncaught Twig\Error\SyntaxError: Expected name or number, got value "(" of type punctuation. in includes/templates/twig_v3_template.twig:9
Stack trace:
#0 vendor/twig/twig/src/ExpressionParser.php(421): Twig\ExpressionParser->parseSubscriptExpression(Object(Twig\Node\Expression\NameExpression))
#1 vendor/twig/twig/src/ExpressionParser.php(291): Twig\ExpressionParser->parsePostfixExpression(Object(Twig\Node\Expression\NameExpression))
#2 vendor/twig/twig/src/ExpressionParser.php(177): Twig\ExpressionParser->parsePrimaryExpression()
#3 vendor/twig/twig/src/ExpressionParser.php(72): Twig\ExpressionParser->getPrimary()
#4 vendor/twig/twig/src/Parser.php(130): Twig\ExpressionParser->parseExpression()
#5 vendor/twig/twig/src/Parser.php(83): Twig\Parser->subparse(NULL, false)
#6 vendor/twig/twig/src/Environment.php(522): Twig\Parser->parse(Object(Twig\TokenStream))
#7 vendor/twig/twig/src/Environment.php(550): Twig\Environment->parse(Object(Twig\TokenStream))
#8 vendor/twig/twig/src/Environment.php(380): Twig\Environment->compileSource(Object(Twig\Source))
#9 vendor/twig/twig/src/Environment.php(342): Twig\Environment->loadTemplate('__TwigTemplate_...', 'twig_v3_templat...')
#10 twigtest.php(38): Twig\Environment->load('twig_v3_templat...')
#11 {main}
thrown in includes/templates/twig_v3_template.twig on line 9
the question now is if i am misreading the documentation about the dot operator and that you are not able to dynamically call macros with a name in a variable or if i try using it the wrong way.
It really worked well with the attributes function and i would really be surprised if this would have been removed somehow.
{{ twigmacros.('element1')(mydata) }}does work I would suggest that you open a bug issue about this in Twig's github