Cómo escribir una extensión Twig personalizada

La principal motivación para escribir una extensión es mover el código usado frecuentemente a una clase reutilizable como agregar apoyo para la internacionalización. Una extensión puede definir etiquetas, filtros, pruebas, operadores, variables globales, funciones y visitantes de nodo.

La creación de una extensión también hace una mejor separación del código que se ejecuta en tiempo de compilación y el código necesario en tiempo de ejecución. Por lo tanto, hace que tu código sea más rápido.

Truco

Before writing your own extensions, have a look at the `Twig official extension repository`_.

Creando la clase de la extensión

Nota

This cookbook describes how to write a custom Twig extension as of Twig 1.12. If you are using an older version, please read Twig extensions documentation legacy.

Para obtener la funcionalidad personalizada primero debes crear la clase para la extensión Twig. Como ejemplo vas a crear un filtro para dar formato a un precio suministrando un número en el precio:

// src/Acme/DemoBundle/Twig/AcmeExtension.php
namespace Acme\DemoBundle\Twig;

class AcmeExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('price', array($this, 'priceFilter')),
        );
    }

    public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
    {
        $price = number_format($number, $decimals, $decPoint, $thousandsSep);
        $price = '$'.$price;

        return $price;
    }

    public function getName()
    {
        return 'acme_extension';
    }
}

Truco

Along with custom filters, you can also add custom functions and register global variables.

Registrando una extensión como servicio

Now you must let the Service Container know about your newly created Twig Extension:

  • YAML
    # src/Acme/DemoBundle/Resources/config/services.yml
    services:
        acme.twig.acme_extension:
            class: Acme\DemoBundle\Twig\AcmeExtension
            tags:
                    - { name: twig.extension }
    
  • XML
    <!-- src/Acme/DemoBundle/Resources/config/services.xml -->
        <services>
        <service id="acme.twig.acme_extension" class="Acme\DemoBundle\Twig\AcmeExtension">
            <tag name="twig.extension" />
        </service>
        </services>
    
  • PHP
    // src/Acme/DemoBundle/Resources/config/services.php
    use Symfony\Component\DependencyInjection\Definition;
    
    $container
        ->register('acme.twig.acme_extension', '\Acme\DemoBundle\Twig\AcmeExtension')
        ->addTag('twig.extension');
    

Nota

Ten en cuenta que las extensiones Twig no se cargan de manera diferida. Esto significa que hay una mayor probabilidad de que obtengas una CircularReferenceException o ScopeWideningInjectionException si cualquier servicio (o tu extensión Twig —en este caso—) es dependiente del servicio Petición. Para obtener más información, échale un vistazo a Cómo trabajar con ámbitos.

Usando la extensión personalizada

Usar tu recién creada extensión de Twig no es diferente a cualquier otra:

{# produce $5,500.00 #}
{{ '5500'|price }}

Pasando otros argumentos a tu filtro:

{# outputs $5500,2516 #}
{{ '5500.25155'|price(4, ',', '') }}

Aprendiendo más

For a more in-depth look into Twig Extensions, please take a look at the `Twig extensions documentation`_.

Bifúrcame en GitHub