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`_.
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.
Now you must let the Service Container know about your newly created Twig Extension:
# src/Acme/DemoBundle/Resources/config/services.yml
services:
acme.twig.acme_extension:
class: Acme\DemoBundle\Twig\AcmeExtension
tags:
- { name: twig.extension }
<!-- 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>
// 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.
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, ',', '') }}
For a more in-depth look into Twig Extensions, please take a look at the `Twig extensions documentation`_.