January 13, 2015 Fabien Potencier

When I started to work on Symfony2, Twig didn't exist. Anyway, to ease using PHP as a templating engine, I created the Symfony Templating Component.

Later on, not very satisfied with using PHP as a templating language, I decided to create a new templating language, Twig, based on the Python Jinja2 language. And Symfony2 became the first popular framework to adopt a non-PHP templating engine in core. Of course, I had no idea if it would become a popular choice amongst Symfony developers, and so Symfony2 lets you use both PHP and Twig in your applications.

Fast forward to 2015; it's clear that Twig won the heart of Symfony2 developers and the heart of many PHP developers; Twig is now also used by many Open-Source CMSes besides Symfony.

But what would Twig as a First-Class Citizen mean in Symfony2 then? To be able to support PHP and Twig in Symfony, we added an abstraction layer. As a developer, you mostly interact with this abstraction via the templating service; that allows one application to use PHP and Twig. As you can imagine, this abstraction adds a layer of complexity and it comes with some performance impact.

For Symfony 3.0, I'd like to extract the Templating Component into an independent library (for the few people using PHP with Symfony) but I'd also like for Twig to be front and center in the framework. The good news is that most of the work has already been done in Symfony 2.7.

Using Twig in Symfony 2.6¶ In Symfony 2.6, you cannot use Twig "directly"; you must instead use the templating sub-system via the templating service. Moreover, as some Twig extensions depends on PHP helpers, the PHP templating system is always loaded even if not configured in the templating.engines option. So, the minimal code you can write to render a Twig template reads as follows: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <? php require_once __DIR__ . '/../autoload.php.dist' ; use Symfony\Component\HttpKernel\Kernel ; use Symfony\Component\HttpFoundation\Request ; use Symfony\Component\Config\Loader\LoaderInterface ; use Symfony\Bundle\FrameworkBundle\FrameworkBundle ; use Symfony\Bundle\TwigBundle\TwigBundle ; class SimpleKernel extends Kernel { public function registerBundles () { return array ( new FrameworkBundle (), new TwigBundle ()); } public function registerContainerConfiguration ( LoaderInterface $loader ) { $loader -> load ( function ( $container ) { $container -> loadFromExtension ( 'framework' , array ( 'secret' => '$ecret' , 'router' => array ( 'resource' => '' ), 'templating' => array ( 'engines' => array ( 'twig' )), )); }); } } $kernel = new SimpleKernel ( 'prod' , false ); $kernel -> boot (); $c = $kernel -> getContainer (); $c -> get ( 'request_stack' ) -> push ( Request :: create ( '/' )); echo $c -> get ( 'templating' ) -> render ( 'index.html.twig' ); As you can see, the Twig bundle has been enabled and the templating.engines sets Twig as the only engine.

Using Twig without the Templating sub-system¶ As of Symfony 2.7, the templating configuration can be removed altogether and Twig can be used directly: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <? php require_once __DIR__ . '/../autoload.php.dist' ; use Symfony\Component\HttpKernel\Kernel ; use Symfony\Component\HttpFoundation\Request ; use Symfony\Component\Config\Loader\LoaderInterface ; use Symfony\Bundle\FrameworkBundle\FrameworkBundle ; use Symfony\Bundle\TwigBundle\TwigBundle ; class SimpleKernel extends Kernel { public function registerBundles () { return array ( new FrameworkBundle (), new TwigBundle ()); } public function registerContainerConfiguration ( LoaderInterface $loader ) { $loader -> load ( function ( $container ) { $container -> loadFromExtension ( 'framework' , array ( 'secret' => '$ecret' , )); }); } } $kernel = new SimpleKernel ( 'prod' , false ); $kernel -> boot (); $c = $kernel -> getContainer (); $c -> get ( 'request_stack' ) -> push ( Request :: create ( '/' )); echo $c -> get ( 'twig' ) -> render ( 'index.html.twig' ); Using Twig directly has some drawbacks: you cannot use some base controller class shortcuts (like render() or renderResponse() ), the web profiler does not display the time it took to render templates anymore, the "@bundle" notation cannot be used when referencing templates, and some other smaller things. Luckily, all those issues will be fixed in the coming weeks.