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)
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.