From 865a7039f8f93e0ad9e76c129481a0bbf9259aa3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 18 Dec 2011 18:08:58 +0100 Subject: [PATCH] added a dump function to help debugging templates --- CHANGELOG | 1 + doc/functions/dump.rst | 52 +++++++++++++++++++++++++ doc/functions/index.rst | 1 + lib/Twig/Environment.php | 3 + lib/Twig/Extension/Debug.php | 53 ++++++++++++++++++++++++++ test/Twig/Tests/Fixtures/functions/dump.test | 22 +++++++++++ test/Twig/Tests/integrationTest.php | 1 - 7 files changed, 132 insertions(+), 1 deletions(-) create mode 100644 doc/functions/dump.rst create mode 100644 lib/Twig/Extension/Debug.php create mode 100644 test/Twig/Tests/Fixtures/functions/dump.test diff --git a/CHANGELOG b/CHANGELOG index 175e98a..47630e5 100644 --- 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 index 0000000..b9d53d2 --- /dev/null +++ b/doc/functions/dump.rst @@ -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 + +
+        {{ dump(user) }}
+    
+ +.. 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 diff --git a/doc/functions/index.rst b/doc/functions/index.rst index 5159283..6cba2d4 100644 --- a/doc/functions/index.rst +++ b/doc/functions/index.rst @@ -11,3 +11,4 @@ Functions attribute block parent + dump diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 7d22787..de29d5a 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -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 index 0000000..d8891de --- /dev/null +++ b/lib/Twig/Extension/Debug.php @@ -0,0 +1,53 @@ + 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 index 0000000..1b3c453 --- /dev/null +++ b/test/Twig/Tests/Fixtures/functions/dump.test @@ -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" diff --git a/test/Twig/Tests/integrationTest.php b/test/Twig/Tests/integrationTest.php index 4f26665..fca8047 100644 --- a/test/Twig/Tests/integrationTest.php +++ b/test/Twig/Tests/integrationTest.php @@ -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 { -- 1.7.2.5