Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Twig ❤️

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Las clases de controlador de Symfony no necesitan extender una clase base. Mientras tu función de controlador devuelva un objeto Response, a Symfony no le importa el aspecto de tu controlador. Pero normalmente, extenderás una clase llamadaAbstractController.

¿Por qué? Porque nos da métodos de acceso directo.

Renderización de una plantilla

Y el primer atajo es render(): el método para renderizar una plantilla. Así que devuelve $this->render() y le pasa dos cosas. La primera es el nombre de la plantilla. ¿Qué tal vinyl/homepage.html.twig.

No es necesario, pero es habitual tener un directorio con el mismo nombre que la clase de tu controlador y un nombre de archivo que sea el mismo que el de tu método, pero puedes hacer lo que quieras. El segundo argumento es un array con las variables que quieras pasar a la plantilla. Vamos a pasar una variable llamadatitle y a ponerle el título de nuestra cinta de mezclas: "PB and Jams".

... lines 1 - 4
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
... lines 6 - 8
class VinylController extends AbstractController
{
#[Route('/')]
public function homepage(): Response
{
return $this->render('vinyl/homepage.html.twig', [
'title' => 'PB & Jams',
]);
}
... lines 19 - 34

Hecho aquí. Ah, pero, ¡examen sorpresa! ¿Qué crees que devuelve el método render()? Sí, es lo que siempre repito: un controlador siempre debe devolver un objeto Response. render() es sólo un atajo para renderizar una plantilla, obtener esa cadena y ponerla en un objeto Response. render() devuelve un objeto Response.

Crear la plantilla

Sabemos por lo que hemos dicho antes, que cuando renderizas una plantilla, Twig busca en el directorio templates/. Así que crea un nuevo subdirectorio vinyl/... y dentro de él, un archivo llamado homepage.html.twig. Para empezar, añade un h1 y luego imprime la variable title con una sintaxis especial de Twig: {{ title }}. Y... Añadiré un texto TODO codificado.

<h1>{{ title }}</h1>
{# TODO: add an image of the record #}
<div>
Our schweet track list: TODO
</div>

¡Vamos a ver si esto funciona! Estábamos trabajando en nuestra página web, así que ve allí y... ¡hola Twig!

Sintaxis de Twigs 3

Twig es una de las partes más bonitas de Symfony, y también una de las más fáciles. Vamos a repasar todo lo que necesitas saber... básicamente en los próximos diez minutos.

Twig tiene exactamente tres sintaxis diferentes. Si necesitas imprimir algo, utiliza {{. A esto lo llamo la sintaxis "decir algo". Si digo {{ saySomething }}se imprimiría una variable llamada saySomething. Una vez que estás dentro de Twig, se parece mucho a JavaScript. Por ejemplo, si lo encierro entre comillas, ahora estoy imprimiendo la cadena saySomething. Twig tiene funciones... por lo que llamaría a la función e imprimiría el resultado.

Así que la sintaxis nº 1 -la de "decir algo"- es {{

La segunda sintaxis... no cuenta realmente. Es {# para crear un comentario... y ya está.

<h1>{{ title }}</h1>
{# TODO: add an image of the record #}
<div>
Our schweet track list: TODO
</div>

La tercera y última sintaxis la llamo "hacer algo". Esto es cuando no estás imprimiendo, estás haciendo algo en el lenguaje. Ejemplos de "hacer algo" serían las sentencias if, los bucles for o la configuración de variables.

El bucle for

Vamos a probar un bucle for. Vuelve al controlador. Voy a pegar una lista de pistas... y luego pasaré una variable tracks a la plantilla ajustada a esa matriz.

<?php
... lines 2 - 8
class VinylController extends AbstractController
{
#[Route('/')]
public function homepage(): Response
{
$tracks = [
'Gangsta\'s Paradise - Coolio',
'Waterfalls - TLC',
'Creep - Radiohead',
'Kiss from a Rose - Seal',
'On Bended Knee - Boyz II Men',
'Fantasy - Mariah Carey',
];
return $this->render('vinyl/homepage.html.twig', [
'title' => 'PB & Jams',
'tracks' => $tracks,
]);
}
... lines 29 - 42
}

Ahora, a diferencia de title, tracks es una matriz... así que no podemos imprimirla. Pero, ¡podemos intentarlo! ¡Ja! Eso nos da una conversión de matriz a cadena. No, tenemos que hacer un bucle sobre las pistas.

Añade una cabecera y un ul. Para hacer el bucle, usaremos la sintaxis "hacer algo", que es{% y luego la cosa que quieras hacer, como for, if o set. Te mostraré la lista completa de etiquetas de hacer algo en un minuto. Un bucle for tiene este aspecto:for track in tracks, donde pistas es la variable sobre la que hacemos el bucle y trackserá la variable dentro del bucle.

Después de esto, añade {% endfor %}: la mayoría de las etiquetas "hacer algo" tienen una etiqueta de fin. Dentro del bucle, añade un li y luego utiliza la sintaxis de decir algo para imprimir track.

<h1>{{ title }}</h1>
{# TODO: add an image of the record #}
<div>
Tracks:
<ul>
{% for track in tracks %}
<li>
{{ track }}
</li>
{% endfor %}
</ul>
</div>

Uso de Sub.keys

Cuando lo probemos... ¡qué bien! Pero vamos a ponernos más complicados. De vuelta en el controlador, en lugar de utilizar un simple array, lo reestructuraré para que cada pista sea un array asociativo con las claves song y artist. Pondré ese mismo cambio para el resto.

<?php
... lines 2 - 8
class VinylController extends AbstractController
{
#[Route('/')]
public function homepage(): Response
{
$tracks = [
['song' => 'Gangsta\'s Paradise', 'artist' => 'Coolio'],
['song' => 'Waterfalls', 'artist' => 'TLC'],
['song' => 'Creep', 'artist' => 'Radiohead'],
['song' => 'Kiss from a Rose', 'artist' => 'Seal'],
['song' => 'On Bended Knee', 'artist' => 'Boyz II Men'],
['song' => 'Fantasy', 'artist' => 'Mariah Carey'],
];
... lines 23 - 27
}
... lines 29 - 42
}

¿Qué ocurre si lo probamos? Ah, volvemos a la conversión de "matriz a cadena". Cuando hacemos el bucle, cada pista es ahora una matriz. ¿Cómo podemos leer las claves songy artist?

¿Recuerdas cuando dije que Twig se parece mucho a JavaScript? Pues bien, no debería sorprender que la respuesta sea track.song y track.artist.

... lines 1 - 7
<ul>
{% for track in tracks %}
<li>
{{ track.song }} - {{ track.artist }}
</li>
{% endfor %}
</ul>
... lines 15 - 16

Y... eso hace que nuestra lista funcione.

Ahora que ya tenemos lo básico de Twig, vamos a ver la lista completa de etiquetas "hacer algo", a conocer los "filtros" de Twig y a abordar el importantísimo sistema de herencia de plantillas.

Leave a comment!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.0.2",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "symfony/asset": "6.0.*", // v6.0.3
        "symfony/console": "6.0.*", // v6.0.3
        "symfony/dotenv": "6.0.*", // v6.0.3
        "symfony/flex": "^2", // v2.1.5
        "symfony/framework-bundle": "6.0.*", // v6.0.4
        "symfony/monolog-bundle": "^3.0", // v3.7.1
        "symfony/runtime": "6.0.*", // v6.0.3
        "symfony/twig-bundle": "6.0.*", // v6.0.3
        "symfony/ux-turbo": "^2.0", // v2.0.1
        "symfony/webpack-encore-bundle": "^1.13", // v1.13.2
        "symfony/yaml": "6.0.*", // v6.0.3
        "twig/extra-bundle": "^2.12|^3.0", // v3.3.8
        "twig/twig": "^2.12|^3.0" // v3.3.8
    },
    "require-dev": {
        "symfony/debug-bundle": "6.0.*", // v6.0.3
        "symfony/stopwatch": "6.0.*", // v6.0.3
        "symfony/web-profiler-bundle": "6.0.*" // v6.0.3
    }
}