Tag Archives: config.yml

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.