Twig añade nuevos filtros para aplicar el "filter, map, reduce"

Twig es el lenguaje utilizado para crear plantillas en Symfony y miles de otros proyectos PHP. Solo en los últimos seis meses, Twig ha publicado más de 30 versiones en sus ramas 1.x y 2.x, añadiendo un montón de funcionalidades interesantes. En este artículo, te presentamos algunos de los nuevos filtros y etiquetas que ha añadido.

Filtrado, mapeo y reducción

Este patrón, conocido en inglés como "filter, map and reduce" es cada vez más popular en otros lenguajes de programación y otros paradigmas (como por ejemplo la programación funcional). El patrón se usa para transformar colecciones y secuencias de elementos. Ahora puedes aplicarlo en Twig gracias a los nuevos filtros llamados filter, map y reduce y las nuevas "funciones flecha" ("arrow functions" en inglés).

El filtro filter elimina de una secuencia todos los elementos que no cumplan con la expresión indicada. Por ejemplo, para ignorar los productos que no tienen suficiente stock:

{% for product in related_products|filter(product => product.stock > 10) %}
    {# ... #}
{% endfor %}

La "función flecha" recibe como argumento cada elemento de la secuencia. Puedes elegir libremente el nombre de ese argumento, así que no tiene por qué ser el mismo que se usa para iterar la colección:

{% for product in related_products|filter(p => p.id not in user.recentPurchases) %}
    {# ... #}
{% endfor %}

Si también necesitas acceder a la clave y no solo al valor del elemento, define dos argumentos y enciérralos con paréntesis (esto último es obligatorio cuando se usan dos argumentos):

{% set components = all_components|filter(
    (v, k) => v.published is true and not (k starts with 'Deprecated')
) %}

Gracias al nuevo filtro filter, la opción if de los bucles for ya no es necesaria, por lo que la hemos declarado obsoleta:

-{% for product in related_products if product.stock > 10 %}
+{% for product in related_products|filter(p => p.stock > 10) %}
    {# ... #}
{% endfor %}

Si quieres seguir usando la opción for ... if, tendrás que pasar la condición if dentro del bucle for:

{% for product in related_products %}
    {% if product.stock > 10 %}
        {# ... #}
    {% endif %}
{% endfor %}

El filtro map aplica una "función flecha" a todos los elementos de una secuencia, por lo que se similar a la función array_map() de PHP:

{% set people = [
    {first: "Alice", last: "Dupond"},
    {first: "Bob", last: "Smith"},
] %}
 
{{ people|map(p => p.first ~ ' ' ~ p.last)|join(', ') }}
{# resultado: Alice Dupond, Bob Smith #}

El filtro reduce reduce una secuencia iterativamente a un único valor. Este filtro siempre recibe dos argumentos: el primero es el valor resultante anterior (normalmente llamado "carry" en inglés) y el segundo es el elemento actual de la secuencia:

{% set num_products = cart.rows|reduce((previousTotal, row) => previousTotal + row.totalUnits) %}
{{ num_products }} productos en total.

Además de filter, map y reduce, Twig ha añadido recientemente otros filtros y etiquetas interesantes.

Esta funcionalidad fue contribuida por Fabien Potencier en el pull request #2996.

El filtro column

El nuevo filtro column devuelve todos los valores de una columna del array indicado (internamente utiliza la función array_column() de PHP):

Tu amigo/a de más edad tiene {{ max(user.friends|column('age')) }} años.

Esta funcionalidad fue contribuida por Pablo Schläpfer en el pull request #2992.

La etiqueta apply

La etiqueta filter se ha declarado obsoleta para no confundirla con el nuevo filtro del que hemos hablando antes. La nueva etiqueta que la reemplaza es apply, que funciona exactamente igual:

-{% filter upper %}
+{% apply upper %}
    Este texto completo se verá en mayúsculas.
{% endapply %}

Esta funcionalidad fue contribuida por Fabien Potencier en el pull request #2977.

Allowed using Traversable objects

Otro cambio importante relacionado con filtros y etiquetas es que ahora puedes usar objetos que implementen la interfaz Traversable de PHP en cualquier lugar en el que puedas usar iteradores o arrays: la etiqueta with, el argumento with de las etiquetas include y embed, el filtro filter, etc.

Esta funcionalidad fue contribuida por Ondřej Exner en el pull request #3016.

Fuente: Twig Adds Filter, Map and Reduce Features

Comentarios

Publicada el

5 de julio de 2019

Etiquetas

Proyectos Symfony destacados

La plataforma de eCommerce 100% Symfony que rivaliza con Magento y PrestaShop. Ver más

Síguenos en @symfony_es para acceder a las últimas noticias.