Plantillas

Has escrito las vistas de autenticación para tu aplicación, pero si estás ejecutando el servidor e intentas ir a cualquiera de las URLs, verás un error TemplateNotFound. Esto se debe a que las vistas están llamando a render_template(), pero aún no has escrito las plantillas. Los archivos de plantillas se almacenan en el directorio templates dentro del paquete flaskr.

Las plantillas son archivos que contienen datos estáticos así como marcadores de posición para datos dinámicos. Una plantilla se renderiza con datos específicos para producir un documento final. Flask utiliza la biblioteca de plantillas Jinja para renderizar las plantillas.

En tu aplicación, usarás plantillas para renderizar HTML que se mostrará en el navegador del usuario. En Flask, Jinja está configurado para autoescapar cualquier dato que se renderice en las plantillas HTML. Esto significa que es seguro renderizar la entrada del usuario; cualquier carácter que haya introducido que pueda estropear el HTML, como < y > será escapado con valores seguros que se vean igual en el navegador pero que no causen efectos no deseados.

Jinja se ve y se comporta principalmente como Python. Se utilizan delimitadores especiales para distinguir la sintaxis de Jinja de los datos estáticos de la plantilla. Todo lo que esté entre {{ y }} es una expresión que se enviará al documento final. {% y %} denota una declaración de flujo de control como if y for. A diferencia de Python, los bloques se denotan mediante etiquetas de inicio y fin en lugar de indentación, ya que el texto estático dentro de un bloque podría cambiar la indentación.

La disposición de la base

Cada página de la aplicación tendrá el mismo diseño básico alrededor de un cuerpo diferente. En lugar de escribir toda la estructura HTML en cada plantilla, cada plantilla extenderá una plantilla base y anulará secciones específicas.

flaskr/templates/base.html
<!doctype html>
<title>{% block title %}{% endblock %} - Flaskr</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<nav>
  <h1>Flaskr</h1>
  <ul>
    {% if g.user %}
      <li><span>{{ g.user['username'] }}</span>
      <li><a href="{{ url_for('auth.logout') }}">Log Out</a>
    {% else %}
      <li><a href="{{ url_for('auth.register') }}">Register</a>
      <li><a href="{{ url_for('auth.login') }}">Log In</a>
    {% endif %}
  </ul>
</nav>
<section class="content">
  <header>
    {% block header %}{% endblock %}
  </header>
  {% for message in get_flashed_messages() %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  {% block content %}{% endblock %}
</section>

g está disponible automáticamente en las plantillas. En función de si se establece g.user (desde load_logged_in_user), se muestra el nombre de usuario y un enlace de cierre de sesión, o se muestran enlaces para registrarse e iniciar sesión. url_for() también está disponible automáticamente, y se utiliza para generar URLs a las vistas en lugar de escribirlas manualmente.

Después del título de la página, y antes del contenido, la plantilla hace un bucle sobre cada mensaje devuelto por get_flashed_messages(). Has utilizado flash() en las vistas para mostrar los mensajes de error, y este es el código que los mostrará.

Hay tres bloques definidos aquí que serán anulados en las otras plantillas:

  1. {% block title %} cambiará el título mostrado en la pestaña del navegador y el título de la ventana.

  2. {% block header %} es similar a title pero cambiará el título mostrado en la página.

  3. {% block content %} es donde va el contenido de cada página, como el formulario de acceso o una entrada del blog.

La plantilla base está directamente en el directorio templates. Para mantener los demás organizados, las plantillas de un plano se colocarán en un directorio con el mismo nombre que el plano.

Registro

flaskr/templates/auth/register.html
{% extends 'base.html' %}

{% block header %}
  <h1>{% block title %}Register{% endblock %}</h1>
{% endblock %}

{% block content %}
  <form method="post">
    <label for="username">Username</label>
    <input name="username" id="username" required>
    <label for="password">Password</label>
    <input type="password" name="password" id="password" required>
    <input type="submit" value="Register">
  </form>
{% endblock %}

{% extends 'base.html' %} indica a Jinja que esta plantilla debe reemplazar los bloques de la plantilla base. Todo el contenido renderizado debe aparecer dentro de las etiquetas {% block %} que anulan los bloques de la plantilla base.

Un patrón útil utilizado aquí es colocar {% block title %} dentro de {% block header %}. Esto establecerá el bloque title y luego emitirá el valor del mismo en el bloque header, para que tanto la ventana como la página compartan el mismo título sin escribirlo dos veces.

Las etiquetas input están usando el atributo required aquí. Esto le dice al navegador que no envíe el formulario hasta que esos campos sean rellenados. Si el usuario está usando un navegador antiguo que no soporta ese atributo, o si está usando algo más que un navegador para hacer peticiones, todavía quieres validar los datos en la vista Flask. Es importante siempre validar completamente los datos en el servidor, incluso si el cliente hace alguna validación también.

Iniciar sesión

Es idéntica a la plantilla de registro, excepto por el título y el botón de envío.

flaskr/templates/auth/login.html
{% extends 'base.html' %}

{% block header %}
  <h1>{% block title %}Log In{% endblock %}</h1>
{% endblock %}

{% block content %}
  <form method="post">
    <label for="username">Username</label>
    <input name="username" id="username" required>
    <label for="password">Password</label>
    <input type="password" name="password" id="password" required>
    <input type="submit" value="Log In">
  </form>
{% endblock %}

Registrar un usuario

Ahora que las plantillas de autenticación están escritas, puedes registrar un usuario. Asegúrate de que el servidor sigue funcionando (flask run si no lo está), y luego ve a http://127.0.0.1:5000/auth/register.

Prueba a hacer clic en el botón «Registrarse» sin rellenar el formulario y comprueba que el navegador muestra un mensaje de error. Prueba a eliminar los atributos required de la plantilla register.html y vuelve a hacer clic en «Registrarse». En lugar de que el navegador muestre un error, la página se recargará y se mostrará el error de flash() en la vista.

Rellena un nombre de usuario y una contraseña y serás redirigido a la página de inicio de sesión. Intenta introducir un nombre de usuario incorrecto, o el nombre de usuario correcto y una contraseña incorrecta. Si te conectas obtendrás un error porque todavía no hay una vista index a la que redirigir.

Continuar con Archivos estáticos.