From: Fabien Potencier Date: Sat, 27 Aug 2011 07:26:51 +0000 (+0200) Subject: added the "attribute" function to allow getting dynamic attributes on variables X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=c609060f94d87e0c9aea0bdaf83ba0ae1bcf5a2e;p=web%2Fkonrad%2Ftwig.git added the "attribute" function to allow getting dynamic attributes on variables --- diff --git a/CHANGELOG b/CHANGELOG index f8f26f8..84e7280 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 1.2.0 + * added the "attribute" function to allow getting dynamic attributes on variables * added Twig_Loader_Chain * added Twig_Loader_Array::setTemplate() * added an optimization for the set tag when used to capture a large chunk of static text diff --git a/doc/templates.rst b/doc/templates.rst index d32c6c9..50541b9 100644 --- a/doc/templates.rst +++ b/doc/templates.rst @@ -106,6 +106,11 @@ If a variable or attribute does not exist you will get back a ``null`` value foo[bar] +.. note:: + + If you want to get a dynamic attribute on a variable, use the + ``attribute`` function instead. + Twig always references the following variables: * ``_self``: references the current template; @@ -1480,6 +1485,25 @@ The array can contain any number of values: {{ some_date|date(constant('DATE_W3C')) }} +``attribute`` +~~~~~~~~~~~~~ + +.. versionadded:: 1.2 + The ``attribute`` function was added in Twig 1.2. + +``attribute`` can be used to access a "dynamic" attribute of a variable: + +.. code-block:: jinja + + {{ attribute(object, method) }} + {{ attribute(object, method, arguments) }} + {{ attribute(array, item) }} + +.. note:: + + The resolution algorithm is the same as the one used for the ``.`` + notation, except that the item can be any valid expression. + Extensions ---------- diff --git a/lib/Twig/ExpressionParser.php b/lib/Twig/ExpressionParser.php index db5b6b5..d2e6ccf 100644 --- a/lib/Twig/ExpressionParser.php +++ b/lib/Twig/ExpressionParser.php @@ -252,6 +252,14 @@ class Twig_ExpressionParser return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line); } + if ('attribute' === $name) { + if (count($args) < 2) { + throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attribute)', $line); + } + + return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line); + } + if (null !== $alias = $this->parser->getImportedFunction($name)) { return new Twig_Node_Expression_GetAttr($alias['node'], new Twig_Node_Expression_Constant($alias['name'], $line), $args, Twig_TemplateInterface::METHOD_CALL, $line); } diff --git a/test/Twig/Tests/Fixtures/functions/attribute.test b/test/Twig/Tests/Fixtures/functions/attribute.test new file mode 100644 index 0000000..635ae29 --- /dev/null +++ b/test/Twig/Tests/Fixtures/functions/attribute.test @@ -0,0 +1,10 @@ +--TEST-- +"attribute" function +--TEMPLATE-- +{{ attribute(obj, method) }} +{{ attribute(array, item) }} +--DATA-- +return array('obj' => new Foo(), 'method' => 'foo', 'array' => array('foo' => 'bar'), 'item' => 'foo') +--EXPECT-- +foo +bar