Modèles (Templates en anglais)

Vous avez écrit la vue authentification de votre application, mais si vous lancez le serveur et que vous essayez d’aller vers n’importe quel URL, vous verrez une erreur TemplateNotFound. C’est du au fait que les vues appellent la fonction render_template(), mais vous n’avez pas encore écrit de template (modèle en français). Les fichiers contenant ces templates sont stockés dans le répertoire templates dans le package flaskr.

Les templates sont des fichiers qui contiennent du texte ainsi que des variables qui peuvent être remplacées de façon dynamique. Une template est combinée avec des données pour générer un document final. Flask utilise la librairie `Jinja`° pour convertir ces templates en documents.

Dans votre application, vous utiliserez des templates pour générer du HTML qui sera affiché dans le navigateur de l’utilisateur. Avec Flask, Jinja est configuré pour convertir (escape en anglais) toute donnée encodée dans les templates HTML. Cela signifie que vous pouvez utiliser sans contrainte les caractères ont un rôle particulier en HTML, dont < ou > qui seront automatiquement convertis en valeurs qui donnent le même résultat dans les pages HTML sans effet de bord.

Jinja ressemble à et se comporte comme Python. Des délimiteurs spéciaux sont utilisés pour distinguer la syntaxe Jinja de données statiques dans un template. Tout ce qui se trouve entre { et }} est une expression qui sera affichée dans le document final. Les balises {% et %}``dénotent une instruction telle que un ``if ou une boucle for. Contrairement à Python, ces blocs sont délimités par des balises ouvrantes et fermantes plutôt que de l’indentation car celle-ci pourrait changer à l’intérieur d’un texte.

La mise en page de base

Chaque page de l’application aura la même mise en page avec un corps spécifique. Plutôt que d’écrire toute la page HTML dans chaque template, nous utiliserons les principes de l’orienté objet et chaque template va étendre une template de base et surcharger des sections spécifiques.

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 directement accessible dans les templates. Suivant que g.user soit initialisé (depuis load_logged_in_user`), alors soit le nom d’utilisateur et un lien vers la page logout sont affichés, soit ce sont des liens vers les pages register et login. La fonction url_for() est également disponible. Elle est utilisé pour générer les URLs correspondants aux vues plutôt que de les écrire manuellement.

Après la page de titre, et juste avant le contenu, le template itère sur chaque message retourné par la fonction get_flashed_messages(). Vous avez utilisé la conftion flash() dans les vues pour présenter des messages d’erreur et ceci est le code qui les affiche.

Il y a trois blocs qui sont définis ici et qui seront remplacés dans d’autres templates:

  1. {% block title %} change le titre affiché dans l’onglet du navigateur et le titre de la fenêtre.

  2. {% block header %} est similaire à title, mais changera le titre affiché sur la page.

  3. ``{% block content %}` c’est ici que le contenu de chaque page se trouve, comme par exemple le formulaire de login ou un message du blog.

Le template de base se trouver dans le répertoire templates. Pour faciliter l’organisation des différents templates, les templates relatives à un plan seront placés dans un répertoire qui a le même nom que le plan.

Register

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' %} indique à Jinja que ce template doit remplacer les blocs du template de base. Tout le contenu produit par le template doit se trouver dans le bloc {% block %} qui surcharge les blocs du template de base.

Une règle de bonne pratique est d’écrire {% block title %} à l’intérieur de {% block header %}. Cela permet de fixer le bloc de titre directement dans le bloc header de façon à ce que la fenêtre du navigateur et la page aient le même titre sans devoir l’écrire deux fois.

Les balises “input` utilisent ici l’attribut required. Cela indique au navigateur de ne pas soumettre le contenu du formulaire tant que ces champs n’ont pas étés remplis. Si l’utilisateur dispose d’un ancien navigateur qui ne supporte pas cet attribut, ou si il utilise une autre logiciel pour réaliser les requêtes, vous devez quand même valider les données dans la vue Flask. Il est important de toujours valider les donnés sur le servuer, même si le client inclus certains fonctions de validation également.

Login

Ceci est identique au template register, sauf pour le titre et le bouton submit.

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 %}

Register A User

Maintenant que les templates d’authentification ont étés écrits, vous pouvez enregistrer (register en anglais) un utilisateur. Assurez-vous que le serveur fonctionne (lancez flask run sinon) et ensuit allez à l’URL http://127.0.0.1:5000/auth/register.

Essayez de cliquer sur le bouton « Register » sans remplir le formulaire et vérifiez que celui-ci affiche un message d’erreur. Essayez de retirer l’attribut « required » du template register.html et cliquez à nouveau sur « Register ». Plutôt que d’afficher encore une erreur, la page va se recharger et la fonction flash() de la vue va être lancée et son résultat affiché.

Entrez un nom d’utilisateur et un mot de passe et vous serez redirigé vers la page login. Essayez d’entrer un nom d’utilisateur incorrect ou un nom correct avec un mauvais mot de passe. Si vous vous connectez (login), vous recevrez un message d’erreur car il n’y a pas encore de vue index vers laquelle vous rediriger.

Continuez en lisant le document Fichiers statiques.