El gestor de plantillas usado por Symfony, Twig, utiliza filtros para poder añadir algo de lógica a las variables que usamos en su entorno, el listado completo está en la documentación oficial: https://twig.symfony.com/doc/2.x/filters/index.html
Las buenas prácticas mandan no añadir lógica a las plantillas de twig, además, el mero hecho de hacer un bucle con un contador es bastante poco legible con codificación twig. Es por esto que están estos filtros: para dar formato a una fecha o un número, escapar cadenas, hacer un join en un array...
Estos filtros han ido creciendo a medida que se han ido creando nuevas versiones, de hecho, los tres últimos son tres funciones para trabajar con arrays que ya están en varios lenguajes: filter, map y reduce. Que se corresponden con las tres funciones del mismo nombre de PHP.
El problema de los filtros es que tenemos un número limitado, luego si queremos añadir lógica a twig sin ensuciar el código lo normal es que escribamos nuestro propio filtro, esto es bastante sencillo, para ello necesitaremos implementar una extensión de Twig:
Añadir el paquete twig/extensions
Si está aún en nuestro composer.json, necesitamos el paquete twig/extensions
$ composer require twig/extensions
Crear la Extensión
En el fichero src/Twig/AppExtension.php será donde escribiremos nuestro código en php.
Pongamos un ejemplo en el que necesitamos obtener un resumen de las x primeras palabras de un texto. Para ello necesitaremos hacer una función que en php sería muy sencilla, pero que en twig nos puede dar auténticos dolores de cabeza, así que implementaremos un filtro "resumen" al que le pasaremos el número de palabras como parámetro, y este, por defecto, será 50.
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class AppExtension extends AbstractExtension
{
public function getFilters()
{
return [
new TwigFilter('resumen', [$this, 'resumen']),
];
}
public function resumen($texto, $numPalabras = 30)
{
$palabras = explode(' ', strip_tags($texto));
return implode(' ', array_slice($palabras, 0, $numPalabras)) . (($numPalabras >= count($palabras)) ? '' : '...');
}
}
Registra el servicio
Esta parte es automática si estás utilizando la configuración de Symfony 4 por defecto. Si no es tu caso en el services.yaml deberías añadir:
services:
my_filters.twig_extension:
class: App\Twig\AppExtension
public: false
tags:
- { name: twig.extension }
Te recordamos que a la clase creada, AppExtension, se le puede poner un constructor y añadirle dependencias en el caso de que necesitemos acceder a algún servicio como el entity manager para obtener algún objeto de la base de datos, o cualquier otro.
Uso del filtro
Ahora usar nuestro filtro será así de fácil:
<div class="noticia">
<div class="imagen-noticia"><img src="{{ noticia.imagen.path }}" /></div>
<div class="resumen-noticia">{{ noticia.texto|resumen(100) }} </div>
</div>
La documentación Oficial
Te recordamos que la documentación oficial de Symfony es bastante completa, si necesitas completar este post, siempre puedes recurrir a ella: https://symfony.com/doc/current/templating/twig_extension.html.