mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-14 19:36:43 +00:00
Added support for unconsumed macro arguments
This commit is contained in:
@@ -20,6 +20,10 @@ Macros differs from native PHP functions in a few ways:
|
||||
|
||||
* Arguments of a macro are always optional.
|
||||
|
||||
* If more positional arguments are passed to the macro than accepted by the macro,
|
||||
they end up in the special ``varargs`` variable as a list of values. This variable
|
||||
is always available in the macro body.
|
||||
|
||||
But as with PHP functions, macros don't have access to the current template
|
||||
variables.
|
||||
|
||||
|
||||
+5
-1
@@ -93,7 +93,7 @@ access the variable attribute:
|
||||
don't put the braces around them.
|
||||
|
||||
If a variable or attribute does not exist, you will receive a ``null`` value
|
||||
when the ``strict_variables`` option is set to ``false``; alternatively, if ``strict_variables``
|
||||
when the ``strict_variables`` option is set to ``false``; alternatively, if ``strict_variables``
|
||||
is set, Twig will throw an error (see :ref:`environment options<environment_options>`).
|
||||
|
||||
.. sidebar:: Implementation
|
||||
@@ -541,6 +541,10 @@ macro call:
|
||||
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
|
||||
{% endmacro %}
|
||||
|
||||
Inside macros, you have access to special variable ``varargs``. If more positional arguments
|
||||
are passed to the macro than accepted by the macro, they end up in the special ``varargs`` variable
|
||||
as a list of values.
|
||||
|
||||
.. _twig-expressions:
|
||||
|
||||
Expressions
|
||||
|
||||
+49
-19
@@ -16,8 +16,19 @@
|
||||
*/
|
||||
class Twig_Node_Macro extends Twig_Node
|
||||
{
|
||||
const VARARGS_NAME = 'varargs';
|
||||
|
||||
public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
{
|
||||
foreach ($arguments as $argumentName => $argument) {
|
||||
if (self::VARARGS_NAME === $argumentName) {
|
||||
throw new Twig_Error_Syntax(sprintf(
|
||||
'The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments',
|
||||
self::VARARGS_NAME, $name, self::VARARGS_NAME
|
||||
), $argument->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
@@ -30,7 +41,7 @@ class Twig_Node_Macro extends Twig_Node
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write(sprintf("public function get%s(", $this->getAttribute('name')))
|
||||
->write(sprintf('public function get%s(', $this->getAttribute('name')))
|
||||
;
|
||||
|
||||
$count = count($this->getNode('arguments'));
|
||||
@@ -46,36 +57,55 @@ class Twig_Node_Macro extends Twig_Node
|
||||
}
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
if ($count) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
|
||||
$compiler->raw('...$__varargs__');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw(")\n")
|
||||
->write("{\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
if (!count($this->getNode('arguments'))) {
|
||||
$compiler->write("\$context = \$this->env->getGlobals();\n\n");
|
||||
} else {
|
||||
$compiler
|
||||
->write("\$context = \$this->env->mergeGlobals(array(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
foreach ($this->getNode('arguments') as $name => $default) {
|
||||
$compiler
|
||||
->write('')
|
||||
->string($name)
|
||||
->raw(' => $__'.$name.'__')
|
||||
->raw(",\n")
|
||||
;
|
||||
}
|
||||
$compiler
|
||||
->write("\$context = \$this->env->mergeGlobals(array(\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
foreach ($this->getNode('arguments') as $name => $default) {
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("));\n\n")
|
||||
->addIndentation()
|
||||
->string($name)
|
||||
->raw(' => $__'.$name.'__')
|
||||
->raw(",\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->addIndentation()
|
||||
->string(self::VARARGS_NAME)
|
||||
->raw(' => ')
|
||||
;
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
$compiler->raw("\$__varargs__,\n");
|
||||
} else {
|
||||
$compiler
|
||||
->raw('func_num_args() > ')
|
||||
->repr($count)
|
||||
->raw(' ? array_slice(func_get_args(), ')
|
||||
->repr($count)
|
||||
->raw(") : array(),\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->outdent()
|
||||
->write("));\n\n")
|
||||
->write("\$blocks = array();\n\n")
|
||||
->write("ob_start();\n")
|
||||
->write("try {\n")
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
macro with arbitrary arguments
|
||||
--TEMPLATE--
|
||||
{% from _self import test1, test2 %}
|
||||
|
||||
{% macro test1(var) %}
|
||||
{{- var }}: {{ varargs|join(", ") }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro test2() %}
|
||||
{{- varargs|join(", ") }}
|
||||
{% endmacro %}
|
||||
|
||||
{{ test1("foo", "bar", "foobar") }}
|
||||
{{ test2("foo", "bar", "foobar") }}
|
||||
--DATA--
|
||||
return array();
|
||||
--EXPECT--
|
||||
foo: bar, foobar
|
||||
|
||||
foo, bar, foobar
|
||||
@@ -0,0 +1,8 @@
|
||||
--TEST--
|
||||
macro with varargs argument
|
||||
--TEMPLATE--
|
||||
{% macro test(varargs) %}
|
||||
{% endmacro %}
|
||||
--EXCEPTION--
|
||||
Twig_Error_Syntax: The argument "varargs" in macro "test" cannot be defined because the variable "varargs" is reserved for arbitrary arguments in "index.twig" at line 2
|
||||
|
||||
@@ -31,14 +31,23 @@ class Twig_Tests_Node_MacroTest extends Twig_Test_NodeTestCase
|
||||
), array(), 1);
|
||||
$node = new Twig_Node_Macro('foo', $body, $arguments, 1);
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
$declaration = ', ...$__varargs__';
|
||||
$varargs = '$__varargs__';
|
||||
} else {
|
||||
$declaration = '';
|
||||
$varargs = 'func_num_args() > 2 ? array_slice(func_get_args(), 2) : array()';
|
||||
}
|
||||
|
||||
return array(
|
||||
array($node, <<<EOF
|
||||
// line 1
|
||||
public function getfoo(\$__foo__ = null, \$__bar__ = "Foo")
|
||||
public function getfoo(\$__foo__ = null, \$__bar__ = "Foo"$declaration)
|
||||
{
|
||||
\$context = \$this->env->mergeGlobals(array(
|
||||
"foo" => \$__foo__,
|
||||
"bar" => \$__bar__,
|
||||
"varargs" => $varargs,
|
||||
));
|
||||
|
||||
\$blocks = array();
|
||||
|
||||
Reference in New Issue
Block a user