Un mes de Symfony. Junio 2019
Lista de las principales novedades de Symfony durante junio de 2019

Ya está aquí el verano, su ola de calor y el habitual resumen de todo lo que ha sucedido con Symfony durante el último mes para que estéis al tanto de las últimas novedades. Este mes no han sido muchas y la mayoría de ellas están relacionadas con Twig como veréis a continuación.
Anuncio del Mailer Component
Como sabréis, la versión 4.3 de Symfony nos trajo tres nuevos componentes: Mime Component, HttpClient component y el Mailer Component. Este último actúa como complemento al componente Mime permitiéndonos enviar los emails que creemos con él y simplificando la configuración de las distintas plataformas de envío de correos que existen actualmente: Gmail, SendGrid o AmazonSES.
Por ejemplo, si nuestra aplicación emplea AmazonSES, podremos instalar su componente asociado:
composer require symfony/amazon-mailer
lo cual añadirá las variables de entorno necesarias a nuestro archivo .env
:
AWS_ACCESS_KEY=...
AWS_SECRET_KEY=...
MAILER_DSN=smtp://$AWS_ACCESS_KEY:$AWS_SECRET_KEY@ses
y nos permitirá inyectar dicho componente normalmente para enviar correos por medio de esta plataforma:
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;class SomeService
{
private $mailer; public function __construct(MailerInterface $mailer)
{
$this->mailer = $mailer;
} public function sendNotification()
{
$email = (new Email())
->from('hello@example.com')
->to('you@example.com')
->subject('Time for Symfony Mailer!')
->text('Sending emails is fun again!')
->html('<p>See Twig integration for better HTML integration!</p>'); $this->mailer->send($email);
}
}
A la pregunta sobre si este componente terminará por remplazar al famoso SwiftMailer la respuesta es sí, previsiblemente Swiftmailer será “deprecado” con la versión 4.4 y remplazado finalmente en la versión 5 de Symfony prevista para noviembre de este año.
Twig añade los filtros filter, map y reduce
Tras el auge de los filtros filter, map y reduce en otros lenguajes de programación, le ha llegado el turno a Twig de implementar estos filtros para modificar colecciones además de la posibilidad de emplear arrow functions para trabajar con ellas 👏
Para los que no conozcáis estos filtros os dejo un breve resumen de cómo podéis emplearlos en twig.
Filter
El filtro filter (valga la redundancia) permite eliminar los elementos de una colección que no cumplen una determinada condición. Por ejemplo:
{% for product in products|filter(product => product.price > 10) %}
{# ... #}
{% endfor %}
Además, también es posible recibir la clave del elemento a comprobar escribiendo la función recibida por filter del siguiente modo:
{% for product in products|filter((key, product) => product.price > 10 and key % 2 == 0) %}
{# ... #}
{% endfor %}
Notad además que los argumentos de la arrow function pueden recibir cualquier nombre:
{% for product in products|filter((k, p) => p.price > 10 and k % 2 == 0) %}
{# ... #}
{% endfor %}
en el caso de que queráis acortar el código de la misma.
Finalmente, la adición de este filtro supone que el uso de if
en un bucle pasa a estar deprecado, es decir, en vez de escribir esto:
{% for user in users if u.name is not empty %}
escribiremos esto:
{% for user in users|filter(user => user.name is not empty) %}
Map
El filtro map nos permite aplicar una misma transformación a todos los elementos de una colección del mismo modo que podemos hacer en PHP con array_map
. Por ejemplo
{% set people = [
{first: "Alice", last: "Dupond"},
{first: "Bob", last: "Smith"},
] %}
{{ people|map(p => p.first ~ ' ' ~ p.last)|join(', ') }}
Reduce
Finalmente el filtro reduce permite reducir una colección a un único valor aplicando una determinada función que recibe dos valores: el elemento actual y el valor acumulado hasta ese momento. Por ejemplo, si queremos calcular el valor de la suma de todos los elementos de una colección podremos escribir:
{% set values = [1, 2, 6] %}{% set sum = values|reduce((ac, currentElement) => ac + currentElement) %} Valor total {{ sum }} (9)
Macros en Twig
Para los que no los conozcáis, las macros son una característica de Twig desde la versión 2.11 que nos permiten evitar tener que escribir código repetido.
Por ejemplo, podemos definir una macro que pinte una caja gris con el contenido que le pasemos como argumento:
{% macro gray_box(content) %}
<div class="gray-box">
{{ content|raw }}
</div>
{% endmacro %}
El problema es que hasta la última versión de Twig, para usar las macros es necesario importarlas al comienzo del archivo twig aunque las definamos en el mismo archivo, lo cual era un poco extraño 🤪
Sin embargo, a partir de ahora, si definimos una macro en un archivo, podemos usarla sin tener que importarla empleando la variable especial _self
:
{% macro gray_box(content) %}
<div class="gray-box">
{{ content|raw }}
</div>
{% endmacro %}....{{ _self.gray_box('<p>Lorem ipsum</p>') }}
Si queréis leer más sobre esta característica de Twig podéis hacerlo en la documentación oficial:
Lanzamiento de Twig 3
Twig 3 será lanzado para finales de este año 2019, y aunque muchas de sus novedades también será incluidas también en las versiones 1.x y 2.x la recomendación es preparar el código para ser compatible con dicha actualización.
Para ello, el principal cambio que deberemos hacer será comenzar a emplear clases basadas en su namespace
, es decir, pasar de:
namespace App\Twig;
class AppExtension extends \Twig_Extension
{
public function getFilters()
{
return [
new \Twig_SimpleFilter('...', [$this, '...'])
];
}
// ...
}
a
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class AppExtension extends AbstractExtension
{
public function getFilters()
{
return [
new TwigFilter('...', [$this, '...']),
];
}
// ...
}
Este será el cambio principal que deberemos hacer salvo que estemos empleando funcionalidad avanzada de Twig, en cuyo caso la recomendación es que revisemos los avisos de deprecaciones en los logs para corregirlas.
Mejoras en el control de espacios en blanco en Twig
Símbolo ~
Finalmente se ha añadido una nueva forma de controlar el HTML generado en nuestros templates mediante el símbolo ~.
Básicamente, actúa del mismo modo que el símbolo -
salvo que no elimina los saltos de línea. Vamos a ver cómo se usan estos símbolos con un ejemplo.
Supongamos que tenemos el siguiente código de Twig.
<ul>
<li>
{% if some_expression %}
{{ some_variable }}
{% endif %}
</li>
</ul>
El HTML generado a partir de él tendría el siguiente aspecto:
<ul>
<li>
Lorem Ipsum
</li>
</ul>
Sin embargo, si queremos que dicho HTML respete el tabulado y los espacios en blanco, tendremos que emplear el símbolo -
para conseguirlo, el cual elimina todos los espacios en blanco a la izquierda y la derecha de la etiqueta:
<ul>
<li>
{%- if some_expression %}
{{- some_variable -}}
{% endif -%}
</li>
</ul>
Obteniendo:
<ul>
<li>Lorem Ipsum</li>
</ul>
Sin embargo, como veis, también se elimina el salto de línea después de la etiqueta <li>
, lo cual podemos solucionar si empleamos el nuevo símbolo ~:
<ul>
<li>
{%~ if some_expression %}
{{ some_variable -}}
{% endif ~%}
</li>
</ul>
Lo cual generará:
<ul>
<li>
Lorem Ipsum
</li>
</ul>
Filtro spaceless
Otro de los cambios que ha sufrido Twig este mes es la deprecación de la etiqueta spaceless
en favor del filtro spaceless
, el cual funciona exactamente del mismo modo, es decir, elimina los espacios blanco entre las etiquetas HTML donde se aplique:
{{ some_var|spaceless }}
o, en su defecto, pasaremos de usarlo así:
{% spaceless %}
{# some HTML content here #}
{% endspaceless %}
a:
{% apply spaceless %}
{# some HTML content here #}
{% endapply %}
Y eso es todo por este mes. Nos vemos en julio!