added a dump function to help debugging templates
authorFabien Potencier <fabien.potencier@gmail.com>
Sun, 18 Dec 2011 17:08:58 +0000 (18:08 +0100)
committerFabien Potencier <fabien.potencier@gmail.com>
Sun, 18 Dec 2011 17:30:06 +0000 (18:30 +0100)
CHANGELOG
doc/functions/dump.rst [new file with mode: 0644]
doc/functions/index.rst
lib/Twig/Environment.php
lib/Twig/Extension/Debug.php [new file with mode: 0644]
test/Twig/Tests/Fixtures/functions/dump.test [new file with mode: 0644]
test/Twig/Tests/integrationTest.php

index 175e98a..47630e5 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 * 1.5.0
 
+ * added a dump function to help debugging templates
  * added a nl2br filter
  * added a random function
  * added a way to change the default format for the date filter
diff --git a/doc/functions/dump.rst b/doc/functions/dump.rst
new file mode 100644 (file)
index 0000000..b9d53d2
--- /dev/null
@@ -0,0 +1,52 @@
+``dump``
+========
+
+.. versionadded:: 1.5
+    The dump function was added in Twig 1.5.
+
+The ``dump`` function dumps information about a template variable. This is
+mostly useful to debug a template that does not behave as expected by
+introspecting its variables:
+
+.. code-block:: jinja
+
+    {{ dump(user) }}
+
+.. note::
+
+    The ``debug`` function is only available when Twig ``debug`` mode is set.
+
+In an HTML context, wrap the output with a ``pre`` tag to make it easier to
+read:
+
+.. code-block:: jinja
+
+    <pre>
+        {{ dump(user) }}
+    </pre>
+
+.. tip::
+
+    Using a ``pre`` tag is not needed when `XDebug`_ is enabled and
+    ``html_errors`` is ``on``; as a bonus, the output is also nicer with
+    XDebug enabled.
+
+You can debug several variables by passing them as additional arguments:
+
+.. code-block:: jinja
+
+    {{ dump(user, categories) }}
+
+If you don't pass any value, all variables from the current context are
+dumped:
+
+.. code-block:: jinja
+
+    {{ dump() }}
+
+.. note::
+
+    Internally, Twig uses the PHP `var_dump`_ function.
+
+.. _`XDebug`: http://xdebug.org/docs/display
+.. _`var_dump`: http://php.net/var_dump
index 5159283..6cba2d4 100644 (file)
@@ -11,3 +11,4 @@ Functions
     attribute
     block
     parent
+    dump
index 7d22787..de29d5a 100644 (file)
@@ -104,6 +104,9 @@ class Twig_Environment
             'escaper'   => new Twig_Extension_Escaper((bool) $options['autoescape']),
             'optimizer' => new Twig_Extension_Optimizer($options['optimizations']),
         );
+        if ($this->debug) {
+            $this->extensions[] = new Twig_Extension_Debug();
+        }
         $this->strictVariables    = (bool) $options['strict_variables'];
         $this->runtimeInitialized = false;
         $this->setCache($options['cache']);
diff --git a/lib/Twig/Extension/Debug.php b/lib/Twig/Extension/Debug.php
new file mode 100644 (file)
index 0000000..d8891de
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2011 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Extension_Debug extends Twig_Extension
+{
+    /**
+     * Returns a list of global functions to add to the existing list.
+     *
+     * @return array An array of global functions
+     */
+    public function getFunctions()
+    {
+        // dump is safe if var_dump is overriden by xdebug
+        $isDumpOutputHtmlSafe = extension_loaded('xdebug') && get_cfg_var('xdebug.overload_var_dump') && get_cfg_var('html_errors');
+
+        return array(
+            'dump' => new Twig_Function_Function('twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true)),
+        );
+    }
+
+    /**
+     * Returns the name of the extension.
+     *
+     * @return string The extension name
+     */
+    public function getName()
+    {
+        return 'debug';
+    }
+}
+
+function twig_var_dump($context)
+{
+    ob_start();
+
+    $count = func_num_args();
+    if (1 === $count) {
+        var_dump($context);
+    } else {
+        for ($i = 1; $i < $count; $i++) {
+            var_dump(func_get_arg($i));
+        }
+    }
+
+    return ob_get_clean();
+}
diff --git a/test/Twig/Tests/Fixtures/functions/dump.test b/test/Twig/Tests/Fixtures/functions/dump.test
new file mode 100644 (file)
index 0000000..1b3c453
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+"dump" function
+--TEMPLATE--
+{{ dump() }}
+{{ dump('foo') }}
+{{ dump('foo', 'bar') }}
+--DATA--
+return array('foo' => 'foo', 'bar' => 'bar')
+--CONFIG--
+return array('debug' => true, 'autoescape' => false);
+--EXPECT--
+array(2) {
+  ["foo"]=>
+  string(3) "foo"
+  ["bar"]=>
+  string(3) "bar"
+}
+
+string(3) "foo"
+
+string(3) "foo"
+string(3) "bar"
index 4f26665..fca8047 100644 (file)
@@ -56,7 +56,6 @@ class Twig_Tests_IntegrationTest extends PHPUnit_Framework_TestCase
                 'strict_variables' => true,
             ), $match[2] ? eval($match[2].';') : array());
             $twig = new Twig_Environment($loader, $config);
-            $twig->addExtension(new Twig_Extension_Escaper());
             $twig->addExtension(new TestExtension());
 
             try {