Symfony2: Get the templating service in a twig extension

November 18th 2014

A while ago I wrote a tutorial on how to write a twig extension.  One of the issues I had, which was also noted in the comments, was I had to inject the whole container into my extension in order to get the templating service.  I could not figure out a solution to getting the templating service in another way and Symfony’s suggested fix for circular references, according to the exception, is to just inject the container.

Solution

There is however a solution, twig functions and filters can be flagged as requiring the current twig environment by using the needs_environment flag.  The twig environment is the class required to render twig templates, so rather than requiring the Symfony2 templating service in the constructor, we can access it on a function level. This means if you want to render a twig template from a twig extension you can do the following:

<?php
.....

class LrotherfieldExtension extends \Twig_Extension
{

   public function getFunctions()
   {
       return [
           new \Twig_SimpleFunction(‘render_test’, [$this, 'render'], [
               'is_safe' => ['html'],
               'needs_environment' => true // Tell twig we need the environment
           ]),
        ];
   }

   // The twig environment gets passed as the first argument to our function
   //  You do not need to pass this manually to the function from the calling twig template
   public function render(Twig_Environment $env)
   {
   // Here we can use the environment to render the twig template
       return $env->render( "LRotherfieldBundle::test.html.twig", []);
   }

   public function getName()
   {
       return 'lrotherfield_extension';
   }

}

Some other cool stuff

Just reading a few lines further into the docs on twig shows that you can also grab the current context http://twig.sensiolabs.org/doc/advanced.html#context-aware-filters.  This allows you to access any variables in the current scope which, although it is very situational, is a pretty cool ability.  There is the ability to run dynamic functions and filters too using * notation which again I don’t have a current use for but it seems pretty awesome.

Luke Rotherfield

Symfony2 Developer in CT USA. Luke is a Symfony2 wizard and has written some sweet libraries of his own. Luke loves Jesus, his gorgeous wife and his two beautiful daughters :)