Added support for directly call macros defined in the same template
authorMartin Hasoň <martin.hason@gmail.com>
Sat, 11 May 2013 18:04:07 +0000 (20:04 +0200)
committerMartin Hasoň <martin.hason@gmail.com>
Mon, 29 Jul 2013 21:14:04 +0000 (23:14 +0200)
CHANGELOG
doc/templates.rst
lib/Twig/ExpressionParser.php
test/Twig/Tests/Fixtures/macros/auto_importing_in_same_file.test [new file with mode: 0644]

index 0736a2b..9db9382 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 * 1.13.2 (2013-XX-XX)
 
+ * in the template can be directly called macros defined in the same template
  * added support for named arguments for macros
  * fixed fatal error that should be an exception when macro does not exist in template
 
index c144702..81dcd35 100644 (file)
@@ -505,6 +505,7 @@ Macros
 
 .. versionadded:: 1.13.2
     Support for macro call with named arguments was added in Twig 1.13.2.
+    Support for directly call macros defined in the same template was added in Twig 1.13.2.
 
 Macros are comparable with functions in regular programming languages. They
 are useful to reuse often used HTML fragments to not repeat yourself.
@@ -527,6 +528,21 @@ Macros can be defined in any template, and need to be "imported" via the
 
     <p>{{ forms.input('username') }}</p>
 
+Macros defined in the same template can be directly called:
+
+.. code-block:: jinja
+
+    {% macro submit(name) %}
+        <input type="submit" value="{{ name }}" />
+    {% endmacro %}
+
+    <p>{{ submit('Send') }}</p>
+
+.. note::
+
+    If the macro name matches the name of a function, it need to be "imported"
+    via the :doc:`import<tags/import>`.
+
 Alternatively, you can import individual macro names from a template into the
 current namespace via the :doc:`from<tags/from>` tag and optionally alias them:
 
index 8565f1b..09d16dd 100644 (file)
@@ -323,7 +323,15 @@ class Twig_ExpressionParser
                     return new Twig_Node_Expression_MacroCall($alias['node'], $alias['name'], $this->createArrayFromArguments($args), $line);
                 }
 
-                $class = $this->getFunctionNodeClass($name, $line);
+                try {
+                    $class = $this->getFunctionNodeClass($name, $line);
+                } catch (Twig_Error_Syntax $e) {
+                    if (!$this->parser->hasMacro($name)) {
+                        throw $e;
+                    }
+
+                    return new Twig_Node_Expression_MacroCall(new Twig_Node_Expression_Name('_self', $line), $name, $this->createArrayFromArguments($args), $line);
+                }
 
                 return new $class($name, $args, $line);
         }
diff --git a/test/Twig/Tests/Fixtures/macros/auto_importing_in_same_file.test b/test/Twig/Tests/Fixtures/macros/auto_importing_in_same_file.test
new file mode 100644 (file)
index 0000000..4ebb930
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+Auto importing macros in the same file
+--TEMPLATE--
+{% macro test(a) %}
+{{ a }}
+{%- endmacro %}
+
+{% macro foo(a) %}
+foo: {{ test(a) }}
+{%- endmacro %}
+
+{{ test('foo') }}
+{{ foo('foo') }}
+{{ test(a = 'bar') }}
+--DATA--
+return array();
+--EXPECT--
+foo
+foo: foo
+bar