Una de las características que me gusta de Twig (un motor de plantillas como Blade) es la posibilidad de aplicar filtros a las cadenas de textos que mostramos por pantalla. Pero Blade no trae esta funcionalidad. Así que, en este artículo vamos a ver como crear Filtros en Blade.
¿Qué son los Filtros en un motor de plantillas?
Los filtros son funciones que podemos aplicar a las cadenas de texto o variables para darle un formato explicito a lo que vayamos a mostrar.
Por ejemplo, si estamos utilizando Twig como motor de plantillas y queremos mostrar una cadena de texto en minúscula, simplemente tenemos que aplicar el filtro lower
de la siguiente manera:
{{ 'HOLA' | lower }} // hola
También es posible encadenar distintos filtros:
{{ 'MI PRIMER AUTO' | title | truncate(9) }}
// Mi Primer
Como vemos, encademos cada filtro con un pipeline ( | ) y se imprimió la cadena de texto con formato de titulo y solo los primeros 9 caracteres.
Esto es utilizando el motor de plantillas Twig y no es posible hacerlo con Blade de Laravel 😔. Si quisiéramos hacer el ultimo ejemplo pero con Blade, deberíamos hacer algo así:
{{ Str::limit(Str::title('MI PRIMER AUTO'), 9) }}
Queda un poco sucio no? Pero sabemos que Blade es muy flexible y, agregando un poco de código, podemos integrar los filtros en Blade ✊. ¡Vamos a ver como hacerlo!
Analizando el código de Blade
En el proveedor de servicios de las vistas ( Illuminate\Views\ViewServiceProvider
) hay un método llamado registerBladeEngine()
que se encarga de instanciar la clase BladeCompiler
que, como su nombre lo indica, se encarga de la compilación de las plantillas de Blade.
Este método es el que vamos a sobrescribir para agregar los filtros. Así que, vamos a crear nuestro propio proveedor de servicios para las vistas con el siguiente comando:
php artisan make:provider BladeFiltersServiceProvider
Una vez creado, vamos a editarlo y veremos que extiende de la clase ServiceProvider
(como todos los proveedores de servicios que creamos con artisan). Pero para nuestro objetivo vamos a modificar esto haciendo que extienda de la clase ViewServiceProvider
De esta manera, podremos sobrescribir el método registerBladeEngine()
. Así que, nuestro proveedor de servicio quedará de la siguiente forma.
NOTA: No te olvides de agregar nuestro proveedor de servicios en el archivo config/app.php
.
Como podemos ver, el método es igual al original pero con la diferencia que estamos instancia la clase BladeFiltersCompile
en lugar de BladeCompile
, como lo hacia el original. ¿De donde sale esa clase? Es donde esta la magia y que crearemos ahora.
Nuestro propio Compilador Blade
Vamos a desarrollar nuestro propio compilador Blade donde estará la nueva función de filtros. Pero no te asustes! El compilador de Blade es algo simple que solamente interpreta las llaves {{ }}
como echos de PHP y los arroba @
como directivas.
Para nuestro caso, solamente tenemos que extender la función encargada de interpretar las llaves.
Sabemos que si ingresamos el código {{ 'Hola Mundo' }}
el compilador original de Blade lo interpreta como <?php echo e('Hola Mundo'); ?>
. Donde la función e()
escapa el contenido para prevenir inyecciones.
Así que, cualquier cosa que pongamos entre las llaves dobles, va dentro de la función e()
. Significa que, {{ 'cadena' | filtro }}
será <?php echo e('cadena' | filtro); ?>
. Pero por supuesto, esto causaría un error.
Nuestro trabajo es, obtener los filtros, aplicarlos a la cadena de texto y poner el resultado en la función e()
. Vamos a ver como hacerlo.
Primero debemos crear una carpeta dentro de app
llamada Services
y aquí creamos nuestro propio Compilador Blade con el nombre BladeFiltersCompiler.php
. El código de nuestro Compilador de Blade quedaría así:
¡Con esto ya tenemos un compilador de Blade con filtros 💪! Vamos a explicar un poco el código.
Vemos que llamamos al método compileRegularEchos()
del compilador original pero, en lugar de devolver el resultado, lo pasamos a nuestra propia lógica para buscar y analizar filtros dentro de las funciones e()
compiladas anteriormente. Entonces, en cada coincidencia que tenemos para la expresión regular, la pasamos a la función preg_replace_callback()
, donde llamamos al método parseFilters()
. Donde sucede la magia.
En el método parseFilters()
buscamos cualquier filtro potencial. Qué significa eso? Cualquier cosa que comience con el operador |
y que no este dentro de comillas simples, dobles o paréntesis. Por ejemplo:
Si no hay coincidencia, simplemente regresamos con el contenido original, lo que significa que no se reemplazará nada. Pero si hay alguna coincidencia, podemos comenzar a transformar los filtros y sus parámetros en funciones reales.
Debemos tener en cuenta que cada filtro lo interpretamos como métodos de la fachada Str
de Laravel. Por lo tanto, todos los filtros que queramos poner, deben existir como métodos de Str
.
A diferencia de los parámetros de Twig, en vez de enviar cada parámetro entre paréntesis, los vamos a pasar luego de ingresar dos puntos :
, como las reglas de Laravel. Además, podemos pasar parámetros como valores o como variables:
¡Eso es todo, ya podemos utilizar filtro en Blade! 👏
Pero esto no termina acá. ¿Te gustaría crear tus propios filtros fuera de las funciones disponibles Str? Es posible!
Creando Filtros personalizados en Blade
Ahora que ya tenemos toda la lógica de filtros instalada en nuestro proyecto, vamos a combinar esta funcionalidad con la potencia de las macros de Blade para crear filtros personalizados.
Vamos a crear estas macros en un proveedor de servicios. Creamos un proveedor llamado FiltersServiceProvider
y en su método boot()
ponemos el código de nuestra macro (o filtro 😉). Por ejemplo, vamos a crear un filtro personalizado para formatear las fechas.
En boot()
podes crear todos los filtros que quieras. Solo tenes que tener en cuenta que debes registrar el proveedor de servicios en app.php
para que funcionen los filtros personalizados. Luego de registrarlo, lo podemos usar de la siguiente forma:
{{ '31-12-2011' | fecha: 'j F, Y' }}
// 31 Diciembre, 2011
Ahora ya podemos definir nuestros propios filtros y usarlos junto con los métodos incorporados en Str, encadenarlos, pasar parámetros y observar el resultado.
Package de Filtros de Blade
La fuente de este artículo fue tomada del package Blade-filters, donde se puede instalar este mismo código sin la necesidad de crear proveedores de servicios y además viene con algunos filtros personalizados ya incorporados. Les dejo el link: https://github.com/thepinecode/blade-filters.
Conclusión
Vimos como crear filtros en Blade, una gran característica que el motor de plantillas de Laravel no disponía. Además, vimos como extender esta característica y hacerla a un mas potente. Blade es increíble. Espero que les haya gustado y nos vemos en la próxima.