Plans, vues et templates

Plans et vues

Une fonction « vue » est le code que vous écrivez pour répondre à des requêtes faites à votre application. Flask utilise des patterns pour faire correspondre l’URL d’une requête entrante avec la vue qui doit la traiter. La vue retourne les données que Flask convertit en une réponse. Flask peut aussi travailler dans l’autre sens et générer une URL correspondant à une vue en fonction de son nom et de ses arguments.

Avertissement

Ne faites pas de copier-coller sans comprendre ce que vous faites ! Le but est d'apprendre Flask. Nous n'avons aucun doute que vous êtes fort en copier-coller. Si vous avez une question, les étudiants moniteurs et assistants sont là pour ça !

Créer un plan (blueprint)

Une classe Blueprint est une façon d’organiser un groupe de vues liées et du code associé. Plutôt que d’enregistrer les vues et le code associé directement avec une application, elles sont enregistrées à un plan. Ensuite, le plan est enregistré dans l’application dès qu’il est disponible dans la fonction qui contient l’usine à applications.

mobility/airport.py

from flask import Blueprint

bp = Blueprint('airport', __name__)

Ceci créée une classe Blueprint dénommée airport. Comme l'objet application, le plan doit connaître l'endroit où il a été défini. C'est pour cela que __name__ est passé comme deuxième argument. L'url_prefix est ajouté au début de tous les URLs associés à ce plan.

Importez et enregistrez le plan depuis l’usine à applications en utilisant app.register_blueprint(). Placez ensuite le nouveau code à la fin de la fonction usine à applications avant de retourner l’application.

mobility/__init__.py

def create_app():
    app = ...

    # existing code omitted

    from . import airport
    app.register_blueprint(airport.bp)

    return app

Une première vue

Ensuite, vous allez écrire le code relatif à la vue. Dans un premier temps, nous allons simplement renvoyer une page HTML statique comme celle que vous avez conçue lors de la phase précédente (cette première page n'aura donc pas grand-chose à voir avec les aéroports à moins que vous ne soyez fan d'aviations ...). Pour cela, copier votre page dans le dossier mobility. Le code ci-dessous s'attend à ce que votre page s'appelle "index.html, si ce n'est pas le cas, renommez-la., ou changé le nom du fichier dans le code ci-dessous

mobility/index.html

Votre page HTML (Vous devez reprendre votre page précédente)
<!DOCTYPE html>
<html>

<head>
    <title>First Web Page</title>
</head>

<body>
    Hello World!
</body>

</html>

mobility/airport.py

from flask import (
   Blueprint, render_template
)

bp = Blueprint('airport', __name__)

# Define the routes code
@bp.route('/')
def show_page():
   page_html = "Fichier non trouvé"
   with open("mobility/index.html") as f:
       page_html = f.read()
   return page_html

Voici ce que la fonction show_page fait:

  1. @bp.route associe l’URL / avec la fonction de vue airport_list.

  2. Elle renvoie le contenu du fichier mapage.html se trouvant dans le dossier template. Pour vous en assurez lancer votre serveur et consulter l'URL suivante : http://127.0.0.1:5000

Un deuxième page plus dynamique

Renvoyer des pages HTML "statique" crée à l'avance est limitant. Flask offre un système de templates qui permet de créer des pages HTMLs dynamiquement.

Les templates

Les templates sont des fichiers qui contiennent du texte ainsi que des variables qui peuvent être remplacées de façon dynamique. Un template est combiné 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 qui 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 qu'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.

Pour commencer, nous allons voir un exemple simple d'utilisation des templates. Nous allons voir comment passer une valeur Python dans l'HTML. Le code ci-dessous est un exemple simple de template. On peut voir que le template a besoin d'une donnée name.

mobility/templates/simple_template.html

<!DOCTYPE html>
<html>

<head>
    <title>First Web Page</title>
</head>

<body>
    Hello {{ name }}!
</body>

</html>

Le code ci-dessous montre comment fournir cet argument au template. Cela se fait à travers la fonction render_template. Lancer le serveur, et regardé le résultat.

mobility/airport.py

from flask import (
Blueprint, render_template
)

bp = Blueprint('airport', __name__)

# Define the routes code
@bp.route('/')
def airport_list():
   name_for_template = "UCLouvain"
   return render_template("simple_template.html", name=name_for_template)

Le système de template est riche, il support les if et les for. C'est maintenant à vous de jouer. À partir du code Python suivant,

mobility/airport.py

from flask import (
Blueprint, render_template
)

bp = Blueprint('airport', __name__)

# Define the routes code
@bp.route('/')
def airport_list():
   names_for_template = ["UCLouvain", "ULB", "Charleroi"]
   return render_template("simple_template.html", names=names_for_template)

on vous demande d'écrire une template qui permet ce rendu:

../../_images/for_loop_template.png

mobility/templates/simple_template.html

Solution (Essayez d'abord par vous-même)
<!DOCTYPE html>
<html>
    <body>
            {% for name in names %}
            <p> Hello {{ name }}! </p>
            {% endfor %}
    </body>
</html>
`{% for name in names} permet de parcourir tous les noms.
Les balises <p> permettent d'écrire un hello par ligne.

Évitez d'accéder d'utiliser directement les index de names, par exemple names[0]. À la place, on vous demande d'utiliser une boucle for. N'oubliez pas la commande pour lancer votre serveur :

$ flask --app=mobility --debug run

L'URL à utiliser est http://127.0.0.1:5000

Revenons à nos aéroports ...

Nous allons maintenant réaliser notre fameuse page aéroport, à partir du code Python suivant :

mobility/airport.py

from flask import (
      Blueprint, render_template
)

bp = Blueprint('airport', __name__)

# Define the routes code
@bp.route('/')
def airport_list():
    airports = [{"iata":"LGG", "name":"Liege Airport"},
                {"iata":"BRU", "name":"Bruxelles"}]
    return render_template("airport.html", airports=airports)

On vous demande d'écrire une template qui permet d'obtenir le résultat suivant :

../../_images/airport_no_css.png

mobility/templates/airport.html

Solution (Essayez d'abord par vous-même)
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>My App</title>
   </head>
   <body>
      <div>
         <h1>Mobility</h1>
      </div>
      <h2>Airport list</h2>
        <table>
            <tr>
                <th>IATA code</th>
                <th>Name</th>
            </tr>
            {% for airport in airports %}
            <tr>
                <td>{{ airport['iata'] }}</td>
                <td>{{ airport['name'] }}</td>
            </tr>
            {% endfor %}
        </table>
   </body>
</html>

Dans ce modèle HTML :

{% for airport in airports %} ouvre une boucle qui parcourt chaque aéroport dans la liste des aéroports que nous avions définie dans la vue.

{% endfor %} indique la fin de la boucle.

Avertissement

Avant d'avancer, vérifiez que vous avez un site qui produit la liste des aéroports ci-dessus à partir d'une liste Python.

Allez à la section fichiers statiques.