Plans, vues et templates ======================== .. rubric:: Plans et vues :name: nosql-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. .. warning:: 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 ! .. container:: section :name: create-a-blueprint .. rubric:: Créer un plan (blueprint) :name: 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. .. container:: literal-block-wrapper docutils :name: id1-blueprint .. container:: code-block-caption ``mobility/airport.py`` .. code-block:: python 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. .. container:: literal-block-wrapper docutils :name: id2-create-app .. container:: code-block-caption ``mobility/__init__.py`` .. code-block:: python def create_app(): app = ... # existing code omitted from . import airport app.register_blueprint(airport.bp) return app .. container:: section :name: the-first-view-register .. rubric:: Une première vue :name: la-première-vue-register 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** .. container:: literal-block-wrapper docutils :name: id3-static .. container:: code-block-caption ``mobility/index.html`` .. raw:: html
Votre page HTML (Vous devez reprendre votre page précédente) .. code-block:: html First Web Page Hello World! .. raw:: html
.. container:: code-block-caption ``mobility/airport.py`` .. code-block:: python 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: #. `@bp.route `__ associe l’URL ``/`` avec la fonction de vue ``airport_list``. #. 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** .. container:: section :name: the-second-view-register .. rubric:: Un deuxième page plus dynamique :name: la-deuxième-vue-register 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. .. container:: section :name: Les templates .. rubric:: Les templates :name: 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*. .. container:: literal-block-wrapper docutils :name: id3 .. container:: code-block-caption ``mobility/templates/simple_template.html`` .. code-block:: html+jinja First Web Page Hello {{ name }}! 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. .. container:: code-block-caption ``mobility/airport.py`` .. code-block:: python 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, .. container:: code-block-caption ``mobility/airport.py`` .. code-block:: python 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: .. image:: ../_images/for_loop_template.png .. container:: code-block-caption ``mobility/templates/simple_template.html`` .. raw:: html
Solution (Essayez d'abord par vous-même) .. code-block:: html+jinja {% for name in names %}

Hello {{ name }}!

{% endfor %} .. code-block:: rst `{% for name in names} permet de parcourir tous les noms. Les balises

permettent d'écrire un hello par ligne. .. raw:: html

É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 : .. code-block:: console $ flask --app=mobility --debug run **L'URL à utiliser est http://127.0.0.1:5000** .. rubric:: Revenons à nos aéroports ... :name: mise-en-commun Nous allons maintenant réaliser notre fameuse page aéroport, à partir du code Python suivant : .. container:: code-block-caption ``mobility/airport.py`` .. code-block:: python 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 : .. image:: ../_images/airport_no_css.png .. container:: code-block-caption ``mobility/templates/airport.html`` .. raw:: html
Solution (Essayez d'abord par vous-même) .. code-block:: html+jinja My App

Mobility

Airport list

{% for airport in airports %} {% endfor %}
IATA code Name
{{ airport['iata'] }} {{ airport['name'] }}
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. .. warning:: Avant d'avancer, vérifiez que vous avez un site qui produit la liste des aéroports ci-dessus à partir d'une liste Python. .. raw:: html
.. only:: html Allez à la section :ref:`fichiers statiques `.