added the "attribute" function to allow getting dynamic attributes on variables
authorFabien Potencier <fabien.potencier@gmail.com>
Sat, 27 Aug 2011 07:26:51 +0000 (09:26 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Sat, 27 Aug 2011 07:46:06 +0000 (09:46 +0200)
CHANGELOG
doc/templates.rst
lib/Twig/ExpressionParser.php
test/Twig/Tests/Fixtures/functions/attribute.test [new file with mode: 0644]

index f8f26f8..84e7280 100644 (file)
--- 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
index d32c6c9..50541b9 100644 (file)
@@ -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
 ----------
 
index db5b6b5..d2e6ccf 100644 (file)
@@ -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 (file)
index 0000000..635ae29
--- /dev/null
@@ -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