Herencia de plantillas

La parte más poderosa de Jinja es la herencia de plantillas. La herencia de plantillas te permite construir una plantilla base «esqueleto» que contiene todos los elementos comunes de tu sitio y define bloques que las plantillas hijas pueden sobrescribir.

Suena complicado pero es muy básico. Lo más fácil es entenderlo empezando con un ejemplo.

Plantilla base

Esta plantilla, a la que llamaremos layout.html, define un simple documento esqueleto de HTML que podría utilizar para una simple página de dos columnas. El trabajo de las plantillas «hijas» es llenar los bloques vacíos con contenido:

<!doctype html>
<html>
  <head>
    {% block head %}
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    <title>{% block title %}{% endblock %} - My Webpage</title>
    {% endblock %}
  </head>
  <body>
    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
      {% block footer %}
      &copy; Copyright 2010 by <a href="http://domain.invalid/">you</a>.
      {% endblock %}
    </div>
  </body>
</html>

En este ejemplo, las etiquetas {% block %} definen cuatro bloques que las plantillas hijas pueden rellenar. Todo lo que hace la etiqueta block es indicar al motor de la plantilla que una plantilla hija puede anular esas partes de la plantilla.

Plantilla hija

Una plantilla hija podría tener el siguiente aspecto:

{% extends "layout.html" %}
{% block title %}Index{% endblock %}
{% block head %}
  {{ super() }}
  <style type="text/css">
    .important { color: #336699; }
  </style>
{% endblock %}
{% block content %}
  <h1>Index</h1>
  <p class="important">
    Welcome on my awesome homepage.
{% endblock %}

La etiqueta {% extends %} es la clave aquí. Indica al motor de plantillas que esta plantilla «extiende» otra plantilla. Cuando el sistema de plantillas evalúa esta plantilla, primero localiza el padre. La etiqueta extends debe ser la primera etiqueta de la plantilla. Para mostrar el contenido de un bloque definido en la plantilla principal, utilice {{ super() }}.