added Twig_Template instance support to the include tag
authorFabien Potencier <fabien.potencier@gmail.com>
Thu, 10 Jun 2010 08:08:38 +0000 (10:08 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Thu, 10 Jun 2010 08:08:38 +0000 (10:08 +0200)
CHANGELOG
doc/02-Twig-for-Template-Designers.markdown
lib/Twig/Node/Include.php
test/Twig/Tests/Node/IncludeTest.php
test/fixtures/tags/include/template_instance.test [new file with mode: 0644]
test/fixtures/tags/inheritance/template_instance.test [new file with mode: 0644]

index aff29d3..cb0ebfa 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@ Backward incompatibilities:
  * removed the sandboxed attribute of the include tag (use the new sandbox tag instead)
  * refactored the Node system (if you have custom nodes, you will have to update them to use the new API)
 
+ * added Twig_Template instance support to the include tag
  * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %})
  * added a grammar sub-framework to ease the creation of custom tags
  * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface)
index 2d841ee..e3336ee 100644 (file)
@@ -321,7 +321,13 @@ Twig supports dynamic inheritance by using a variable as the base template:
     {% extends some_var %}
 
 If the variable evaluates to a `Twig_Template` object, Twig will use it as the
-parent template.
+parent template:
+
+    // {% extends layout %}
+
+    $layout = $twig->loadTemplate('some_layout_template.twig');
+
+    $twig->display('template.twig', array('layout' => $layout));
 
 ### Conditional Inheritance (as of Twig 0.9.7)
 
@@ -649,7 +655,7 @@ The `set` tag can also be used to 'capture' chunks of HTML (new in Twig
 The `extends` tag can be used to extend a template from another one. You can
 have multiple of them in a file but only one of them may be executed at the
 time. There is no support for multiple inheritance. See the section about
-Template inheritance above.
+Template inheritance above for more information.
 
 ### Block
 
@@ -687,6 +693,21 @@ them as an array:
 >When including a template created by an end user, you should consider
 >sandboxing it. More information in the "Twig for Developers" chapter.
 
+The template name can be any valid Twig expression:
+
+    [twig]
+    {% include some_var %}
+    {% include ajax ? 'ajax.html' : 'not_ajax.html' %}
+
+And if the variable evaluates to a `Twig_Template` object, Twig will use it
+directly:
+
+    // {% include template %}
+
+    $template = $twig->loadTemplate('some_template.twig');
+
+    $twig->display('template.twig', array('template' => $template));
+
 ### Import
 
 Twig supports putting often used code into macros. These macros can go into
index b3c9f78..d2ca928 100644 (file)
@@ -26,12 +26,28 @@ class Twig_Node_Include extends Twig_Node
 
     public function compile($compiler)
     {
-        $compiler
-            ->addDebugInfo($this)
-            ->write('$this->env->loadTemplate(')
-            ->subcompile($this->expr)
-            ->raw(')->display(')
-        ;
+        $compiler->addDebugInfo($this);
+
+        if ($this->expr instanceof Twig_Node_Expression_Constant) {
+            $compiler
+                ->write("\$this->env->loadTemplate(")
+                ->subcompile($this->expr)
+                ->raw(")->display(")
+            ;
+        } else {
+            $compiler
+                ->write("\$template = ")
+                ->subcompile($this->expr)
+                ->raw(";\n")
+                ->write("if (!\$template")
+                ->raw(" instanceof Twig_Template) {\n")
+                ->indent()
+                ->write("\$template = \$this->env->loadTemplate(\$template);\n")
+                ->outdent()
+                ->write("}\n")
+                ->write('$template->display(')
+            ;
+        }
 
         if (null === $this->variables) {
             $compiler->raw('$context');
index 439c69c..b25b30a 100644 (file)
@@ -46,6 +46,22 @@ class Twig_Tests_Node_IncludeTest extends Twig_Tests_Node_TestCase
         $node = new Twig_Node_Include($expr, null, 0);
         $tests[] = array($node, '$this->env->loadTemplate("foo.twig")->display($context);');
 
+        $expr = new Twig_Node_Expression_Conditional(
+                        new Twig_Node_Expression_Constant(true, 0),
+                        new Twig_Node_Expression_Constant('foo', 0),
+                        new Twig_Node_Expression_Constant('foo', 0),
+                        0
+                    );
+        $node = new Twig_Node_Include($expr, null, 0);
+        $tests[] = array($node, <<<EOF
+\$template = (true) ? ("foo") : ("foo");
+if (!\$template instanceof Twig_Template) {
+    \$template = \$this->env->loadTemplate(\$template);
+}
+\$template->display(\$context);
+EOF
+        );
+
         $expr = new Twig_Node_Expression_Constant('foo.twig', 0);
         $vars = new Twig_Node_Expression_Array(array('foo' => new Twig_Node_Expression_Constant(true, 0)), 0);
         $node = new Twig_Node_Include($expr, $vars, 0);
diff --git a/test/fixtures/tags/include/template_instance.test b/test/fixtures/tags/include/template_instance.test
new file mode 100644 (file)
index 0000000..6ba064a
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+"include" tag accepts Twig_Template instance
+--TEMPLATE--
+{% include foo %} FOO
+--TEMPLATE(foo.twig)--
+BAR
+--DATA--
+return array('foo' => $twig->loadTemplate('foo.twig'))
+--EXPECT--
+BAR FOO
diff --git a/test/fixtures/tags/inheritance/template_instance.test b/test/fixtures/tags/inheritance/template_instance.test
new file mode 100644 (file)
index 0000000..b2c48d9
--- /dev/null
@@ -0,0 +1,14 @@
+--TEST--
+"extends" tag accepts Twig_Template instance
+--TEMPLATE--
+{% extends foo %}
+
+{% block content %}
+{% parent %}FOO
+{% endblock %}
+--TEMPLATE(foo.twig)--
+{% block content %}BAR{% endblock %}
+--DATA--
+return array('foo' => $twig->loadTemplate('foo.twig'))
+--EXPECT--
+BARFOO