Layouts y herencia de templates en Twig

Clase 13 de 17Curso de Symfony Framework

El layout del proyecto

Hasta ahora, cada uno de los templates que usamos fue creado desde cero.

De hecho, si los miras con atención notarás que hay bastante código que se repite, por ejemplo:

Apenas comienza el tag body nos encontramos con:

<style> .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } </style>

¿No se podría tener este código en algún lugar común en lugar de escribirlo cada vez?

Ya en la clase anterior hablamos de incorporar algún logo de nuestro sitio… ¿Vamos a estar incluyéndolo en cada página? ¿Qué sucederá cuando lo cambiemos?

Es claro que necesitamos algo mejor.

Para ello Twig (El motor de templates que usamos) propone el concepto de Layout.

Un layout es un template abstracto que se usa, precisamente, para contener todas aquellas partes que son comunes a una serie de templates.

En el caso de Twig, la implementación de este concepto se logra a través de la _herencia _de templates.

Nota como todos los templates comienzan con:

{% extends 'base.html.twig' %}

Esto significa que el template que estás viendo extiende o hereda de base.html.twig.

Este archivo lo encontrarás en src/templates/base.html.twig

Su contenido es:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{% block title %}Welcome!{% endblock %}</title> {% block stylesheets %}{% endblock %} </head> <body> {% block body %}{% endblock %} {% block javascripts %}{% endblock %} </body> </html>

Nota como la apertura del HTML y los tags principales (head y body) están escritos aquí.

Otro elemento importante de este template son los {% block %}{% endblock %}

Se trata de placeholders que deberán ser rellenados por los templates hijos.

Por ejemplo, si ves templates/company/index.html.twig notarás que están definidos los bloques title ybodyy dentro de ellos se encuentra el contenido específico de esta página.

Es más, si prestas atención notarás que todo el código está metido dentro de algún bloque. Esto no es casual… todo template que extiende otro debe limitarse a sobre-escribir aquellos bloques en los que difiera de su padre.

De modo que, si quisiéramos agregar un logo de nuestro sitio, el mejor lugar para colocarlo sería en base.html.twig, de ese modo, cualquier página que visites lo tendrá:

<body> {% block page_header %} <div id="page_header" style="background: #222222"> <img src="https://static.platzi.com/mf-landings/image/logotipo-platzi-768799552e5f26369e21a807b8a533f7.png"/> </div>{% endblock %} {% block body %}{% endblock %} {% block javascripts %}{% endblock %} </body>

En general es una buena práctica usar bloques pequeños, uno nunca sabe cuándo un template más abajo en la jerarquía querrá cambiarlo.

Algo más que sería interesante es mostrar algún indicador de que estamos logueados (y en tal caso ofrecer la posibilidad de cerrar sesión) o el link al formulario de login.

Para ello podemos usar algo como:

<div id="page_header" style="background: #5eb5e0"> <img src="https://static.platzi.com/mf-landings/image/logotipo-platzi-768799552e5f26369e21a807b8a533f7.png"/> {% if app.user %} {{ app.user }} - <a href="{{ url('app_logout') }}">Salir</a> {% else %} <a href="{{ url('app_login') }}">Ingresar</a> {% endif %} </div>

Y listo, ya tenemos un login/logout que nos acompaña a todos lados (A todos lados donde el template extienda de base, claro).

Podríamos definir incluso diferentes layouts para usar según la ocasión.

Podríamos tener uno para cada tipo de usuario o para cada sección del sitio… incluso podríamos tener layouts que extiendan de otros layouts… las posibilidades son infinitas.

Ahora que conoces el sistema puedes darle tu propio estilo a tu aplicación… ¡adelante!

Cuando termines de estilar tu sitio vuelve aquí que viene algo importante: el envío de los emails.