Rendu de templates Flask

Concaténer des chaînes HTML dans du code Python est à la fois fastidieux et dangereux (exposé aux vulnérabilités XSS). Flask intègre le moteur de templates Jinja2 pour résoudre ce problème.

Les modèles vous permettent de séparer la logique métier de la présentation des pages, ce qui permet d'écrire du code plus sûr et plus facile à maintenir.


Notions de base de render_template

render_template()C'est la fonction de rendu de modèle la plus couramment utilisée dans Flask.

Son premier paramètre est le nom du fichier de modèle, et les arguments nommés suivants sont transmis au modèle en tant que variables.

Exemple

# Chemin du fichier : app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    # Rendre le modèle templates/index.html, en passant les variables title et name
    return render_template("index.html", title=EXEMPLE Accueil, name="World")

@app.route("/user/<username>")
def profile(username):
    # Transmettre le nom d'utilisateur depuis l'URL au modèle
    return render_template("user.html", username=username, posts=[
        {"title": Introduction à Flask, "date": "2026-05-01"},
        {"title": Modèle Jinja2, "date": "2026-05-10"},
    ])

Les fichiers de modèle sont placés dans le répertoire du projettemplates/Dans le dossier :

example-flask-test/
├── app.py
└── templates/
    ├── index.html
    └── user.html

Le contenu de index.html est :

Exemple (index.html)

<!-- Chemin du fichier : templates/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ title }} - EXEMPLE</title>
</head>
<body>
    <h1>{{ title }} </h1>
     <p>Bonjour {{ name }}.</p>
</body>
</html>

Visitezhttp://127.0.0.1:5000/, le résultat de sortie est :


Syntaxe de base de Jinja2

Trois syntaxes fondamentales dans les modèles Jinja2 :

Syntaxe Objectif Exemple
{{ ... }} Afficher les valeurs des variables, échapper automatiquement le HTML {{ username }}
{% ... %} Instructions de contrôle (if, for, block, etc.) {% if user %}
{# ... #} Commentaires, n'apparaîtront pas dans le résultat rendu {# Ceci est un commentaire #}

Exemple de modèle

Exemple (user.html)

<!-- Chemin du fichier : templates/user.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ username }} - EXEMPLE</title>
</head>
<body>
    <h1>Page d'accueil personnelle de {{ username }}</h1>

    <!-- Conditionnel : si la liste des articles est vide, afficher un message d'invite -->
    {% if posts %}
        <h2>Articles récents :</h2>
        <ul>
        <!-- Parcourir la liste des articles -->
        {% for post in posts %}
            <!-- loop.index est une variable intégrée de Jinja2, commençant à 1 -->
            <li>{{ loop.index }}. {{ post.title }} ({{ post.date }})</li>
        {% endfor %}
        </ul>
    {% else %}
        <p>Aucun article pour le moment</p>
    {% endif %}

    <!-- Utilisation du filtre : upper convertit le texte en majuscules -->
    <p>Nom d'utilisateur en majuscules : {{ username|upper }}</p>
</body>
</html>

Filtres courants

Les filtres servent à modifier le format de sortie des variables, à l'aide du symbole pipe.|Appel.

Filter Fonction Exemple Sortie
upper Convertir en majuscules {{ "hello"|upper }} HELLO
lower Convertir en minuscules {{ "HELLO"|lower }} bonjour
title Mettre la première lettre en majuscule {{ "hello world"|title }} Hello World
longueur Obtenir la longueur {{ [1,2,3]|length }} 3
default Définir la valeur par défaut {{ name|default("anonymous") }} Anonyme (lorsque name est vide)
safe Marquer comme HTML sécurisé (sans échappement) {{ "Gras"|safe }} Rendu en texte gras
join Joindre la liste {{ ["a","b"]|join(",") }} a,b

Avertissement de sécurité:safeLe filtre safe désactive l'échappement automatique ; ne l'utilisez que lorsque vous faites absolument confiance à la source des données. Ne l'utilisez jamais pour les entrées utilisateur.safe。


Échappement automatique — Protection XSS

Jinja2 échappe le HTML par défaut sur toutes les sorties de variables ; il s'agit d'une défense essentielle pour la sécurité web.

Par exemple, si le nom d'utilisateur soumis par l'utilisateur est<script>alert("xss")</script>, lors du rendu du modèle, il est automatiquement converti en texte sûr :

<!-- 模板中直接使用变量 -->
<p>{{ username }}</p>

<!-- 渲染结果(HTML 特殊字符已被转义) -->
&lt;p&gt;&amp;lt;script&amp;gt;alert(&amp;quot;xss&amp;quot;)&amp;lt;/script&amp;gt;&lt;/p&gt;

L'échappement s'applique à.html、.htm、.xml、.xhtml、.svgLe fichier de modèle à la fin.


Héritage de modèle — élimination du code dupliqué

L'héritage de modèle est l'une des fonctionnalités les plus puissantes de Jinja2. Il vous permet de définir une "mise en page de base", puis de remplir le contenu via des modèles enfants.

Cela évite de réécrire sans cesse les parties communes telles que les en-têtes, la navigation, les pieds de page, etc. sur chaque page.

Modèle de base (modèle parent)

Exemple

<!-- Chemin du fichier : templates/base.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{% block title %}EXAMPLE Flask Tutorial{% endblock %}</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <header>
        <h1>EXEMPLE Tutoriel Flask</h1>
        <nav>
            <a href="/">Accueil</a> |
            <a href="/about">À propos</a>
        </nav>
    </header>

    <main>
    <!-- le bloc est une zone de remplacement que les templates enfants peuvent remplir ou surcharger -->
    {% block content %}{% endblock %}
    </main>

    <footer>
        <p>&copy; 2026 example.com</p>
    </footer>
</body>
</html>

Template enfant (hérite du template parent)

Exemple

<!-- Chemin du fichier : templates/index.html -->
{% extends "base.html" %}

<!-- Surcharge le bloc title du template parent -->
{% block title %}EXAMPLE Tutoriel - Accueil{% endblock %}

<!-- Remplit le bloc content du template parent -->
{% block content %}
    <h2>Bienvenue sur EXAMPLE</h2>
    <p>{{ greeting }}</p>

    {% if user %}
        <p>Utilisateur actuel : {{ user }}</p>
    {% else %}
        <p><a href="/login">Veuillez d'abord vous connecter</a></p>
    {% endif %}
{% endblock %}
Balises Fonction
{% extends "base.html" %} Déclare que le template actuel hérite de base.html (à placer sur la première ligne)
{% block name %}...{% endblock %} Définir un bloc pouvant être remplacé par les modèles enfants
{{ super() }} Appeler le contenu du bloc du modèle parent portant le même nom à l'intérieur du bloc du modèle enfant.

Après avoir utilisé l'héritage de modèles, il vous suffit de modifierbase.htmlà un seul endroit, et les parties communes de toutes les pages (telles que la navigation, le pied de page) seront automatiquement mises à jour.


Objets intégrés dans les modèles

Les objets Flask suivants peuvent être utilisés directement dans les modèles sans être passés viarender_template()Passez :

Object Description Exemple d'utilisation dans un modèle
request Objet de requête actuel {{ request.path }}
session Données de session actuelles {{ session.get("username") }}
g Variables globales au niveau de la requête {{ g.user }}
config Configuration de l'application {{ config["APP_NAME"] }}
url_for() Fonction de génération d'URL {{ url_for("index") }}
get_flashed_messages() Obtenir les messages flash {% for msg in get_flashed_messages() %}...

Inclure d'autres modèles — include

Utilisation{% include %}Vous pouvez intégrer un autre modèle dans un modèle :

Exemple

<!-- Chemin du fichier : templates/_navbar.html (le préfixe underscore indique un modèle partiel) -->
<nav style="background:#f0f0f0;padding:10px;">
    <a href="/">Accueil</a> |
    <a href="/posts">Articles</a> |
    <a href="/about">À propos</a>
</nav>

Exemple

<!-- Inclure la barre de navigation dans n'importe quel template -->
<!DOCTYPE html>
<html>
<head><title>Page</title></head>
<body>
    {% include "_navbar.html" %}

    <h1>Contenu de la page</h1>
    <p>Ceci est le contenu principal de la page.</p>
</body>
</html>

Bonnes pratiques: L'héritage de template (extends) est utilisé pour la réutilisation de la mise en page au niveau de la page,includeUtilisé pour la réutilisation du code au niveau des composants. Les composants réutilisables tels que les barres de navigation et les barres latérales sont adaptés à include.


Exemple complet : page d'accueil du blog

Intégrez les connaissances ci-dessus dans un scénario concret :

Exemple

# Chemin du fichier : app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    # Simuler les données d'articles dans la base de données.
    articles = [
        {"id": 1, "title": Guide de démarrage de Flask, "author": "example", "views": 1024},
        {"id": 2, "title": Les templates Jinja2 expliqués, "author": "admin", "views": 512},
        {"id": 3, "title": Conception d'API RESTful, "author": "example", "views": 256},
    ]
    return render_template("blog.html", articles=articles)

Exemple

<!-- Chemin du fichier : templates/blog.html -->
{% extends "base.html" %}

{% block title %}EXEMPLE Blog{% endblock %}

{% block content %}
    <h2>Derniers articles</h2>

    {% if articles %}
        {% for article in articles %}
            <!-- Ajouter différents styles en fonction du nombre de vues -->
            <div class="article" {% if article.views > 1000 %}style="background:#fff3cd;"{% endif %}>
                <h3>{{ article.title }}</h3>
                <p>Auteur : {{ article.author }} | Vues : {{ article.views }}</p>
                <!-- Utilisez la variable de boucle pour créer un séparateur -->
                {% if not loop.last %}
                    <hr>
                {% endif %}
            </div>
        {% endfor %}
    {% else %}
        <p>Aucun article pour le moment, veuillez revenir plus tard.</p>
    {% endif %}
{% endblock %}

Variables spéciales de Jinja2

Variable Description
loop.index Index actuel de la boucle, commence à 1
loop.index0 Index actuel de la boucle, commence à 0
loop.first Indique s'il s'agit de la première itération de la boucle
loop.last Indique s'il s'agit de la dernière itération de la boucle
loop.length Longueur totale de la séquence
autres extensions