Archivos de Tags: Extension @es

Exponer de forma global valores de config.yml en las plantillas de Twig en aplicaciones Symfony2

Supongamos que has creado un bundle que tiene una configuración específica dentro del fichero config.yml (esto se hace exponiendo configuraciones semánticas). Por ejemplo los idiomas que soporta tu aplicación:

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

twigbg

Podrías hacer que todos los controladores leyeran esa configuración mediante el container interface y expusieran el valor a las plantillas de esta forma:

// 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 %}

Pero esto sería MUY tedioso. Una solución mucho mejor es crear una extensión Twig que exponga esa configuración leída de container interface como si se hubiera definido en el fichero config.yml dentro de la sección twig:globals:

// 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';
    }
}

Por supuesto hay que registrar esta extensión de Twig como un servicio usando el tag twig.extension:

// 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 }

Ahora ya puedes eliminar el parámetro language en la llamada a render porque dicha variable está definida de forma global para todas las plantillas.