Expose config.yml values globally for Twig templates in Symfony2 applications

Lets suppose you have created a bundle that has some specific configuration in the config.yml file (this is done by exposing semantic configuration). For example the languages supported by the application:

acme_demo:
    languages:
        en: English
        es: Spanish (Español)

twigbg

You could make all your controllers read this language configuration from the container interface and then expose that variable to the templates like this:

// src/Acme/DemoBundle/Controller/AcmeController.php
<?php

namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;

class AcmeController extends Controller
{
    private $languages;

    public function setContainer(ContainerInterface $container = null)
    {
        parent::setContainer($container); // Initialize the container first
        
        $this->languages = $this->container->getParameter('acme_demo.languages');
    }

    public function indexAction()
    {
        return $this->render('AcmeDemoBundle:Default:index.html.twig',
                array('languages' => $this->languages)
        );
    }
}
// src/Acme/DemoBundle/Resources/views/Default/index.html.twig
{% for lang, language in languages %}
                    {{ lang }} - {{ language }}
{% endfor %}

But this would be VERY tedious. A much better approach is to create a Twig extension that exposes that configuration read from the container interface as it would be done inside config.yml in the twig:globals section:

// src/Acme/DemoBundle/Twig/LanguageExposeExtension.php
<?php

namespace Acme\DemoBundle\Twig;

use Symfony\Component\DependencyInjection\ContainerInterface;

class LanguageExposeExtension extends \Twig_Extension
{
    private $container;
    
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }
    
    public function getGlobals()
    {
        return array(
            'languages' => $this->container->getParameter('acme_demo.languages')
        );
    }
    
    public function getName()
    {
        return 'language_expose_extension';
    }
}

And of course register this class as a Twig extension using the twig.extension tag:

// src/Acme/DemoBundle/Resources/config/services.yml
services:
    acme.twig.language_expose_extension:
        class: Acme\DemoBundle\Twig\LanguageExposeExtension
        arguments: [@service_container]
        tags:
            - { name: twig.extension }

Now you can remove the language parameter in the render call because it’s now defined globally for all templates.

You might also like

Twig-extensions in Symfony2
Twig comes with multiple filters that provide functions like round, slice, sort, etc. In case you need...

Use SSH config file to easely connect to servers via alias names
I don't have a very good memory and always have problems remembering my servers names when connecting...

Add Twig syntax highlight in Sublime Text 2
Select the "Preferences->Browse Packages..." menu to open the folder that contains Sublime Text 2 packages. Download...

No splash screen on NetBeans
I'm not a fan of the splash screens the applications, even less on those that place it on top of all...

  1. Henry Cavill

    This post has been my salvation. I am so thankfull. Tx

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.