Modèles Jinja2 — Rendu de pages HTML

Dans ce chapitre, vous apprendrez à utiliser le moteur de modèles Jinja2 pour rendre des pages HTML complètes et extraire des mises en page communes.


Des chaînes de caractères aux modèles

Dans le chapitre précédent, les fonctions de vue renvoyaient directement des chaînes avec des balises HTML intégrées dans les lignes, qui ne pouvaient pas être réutilisées et étaient difficiles à maintenir.

render_template()C'est le point d'entrée du rendu de modèles de Flask : il charge les fichiers HTML, injecte des variables et renvoie une réponse HTML complète.

Exemple

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

app = Flask(__name__)

@app.route("/")
def index():
    # render_template('nom du fichier de modèle', nom_variable=valeur, ...)
    return render_template('index.html', title='EXAMPLE Blog')

Flask par défaut, dans le répertoire racine du projettemplates/Trouvez les templates dans le dossier.


Créez des fichiers de template

Créer dans le répertoire racine du projettemplates/dossier, puis créezindex.html。

Exemple

<!-- Chemin du fichier : templates/index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
    <h1>{{ title }}</h1>
    <p>Bienvenue, ceci est une page rendue avec le moteur de templates Jinja2.</p>
</body>
</html>

Aperçu de la syntaxe des templates Jinja2

La syntaxe de Jinja2 est presque exactement la même que la syntaxe des templates Django, et est également similaire à la syntaxe d'interpolation de Vue3.

ObjectifJinja2 / DjangoDescription
Variables de sortie{{ variable }}Prend en charge l'accès aux attributs : {{ user.name }}
Boucles{% for item in list %}...{% endfor %}Prend en charge loop.index
Conditions{% if cond %}...{% endif %}Chaînable : {% elif %}
Héritage{% extends 'base.html' %}Doit être sur la première ligne
Définitions de bloc{% block name %}...{% endblock %}Les templates enfants remplissent les espaces vides du template parent

La syntaxe des templates Jinja2 et Django est presque identique, mais Jinja2 est plus flexible : vous pouvez écrire des expressions Python plus complexes dans les templates, tandis que les templates Django restreignent délibérément certaines capacités pour éviter que la logique métier ne fuie dans les templates.


Héritage de gabarit : base.html

Plusieurs pages partagent la barre de navigation et le pied de page, utilisezl'héritage de template pouréviter le HTML en double.

Création d'un template parent base.html

Exemple

<!-- Chemin du fichier : templates/base.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- block title: le template enfant peut remplacer le titre de la page -->
    <title>{% block title %}EXAMPLE Blog{% endblock %}</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #f5f5f5;
            color: #333;
        }
        .navbar {
            display: flex; justify-content: space-between; align-items: center;
            padding: 16px 40px; background: #fff;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }
        .navbar .logo { font-size: 22px; font-weight: bold; color: #e74c3c; text-decoration: none; }
        .navbar a { margin-left: 20px; text-decoration: none; color: #333; }
        .container { max-width: 960px; margin: 40px auto; padding: 0 20px; }
        .footer { text-align: center; padding: 20px; color: #999; border-top: 1px solid #eee; }
    </style>
    {% block extra_head %}{% endblock %}
</head>
<body>
    <header class="navbar">
        <a href="/" class="logo">EXAMPLE Blog (Flask)</a>
        <nav>
            <a href="/">Accueil</a>
            <a href="/about">À propos</a>
        </nav>
    </header>

    <main class="container">
        <!-- contenu du bloc : le modèle enfant remplit ici le contenu principal de la page -->
        {% block content %}
        {% endblock %}
    </main>

    <footer class="footer">
        <p>© 2024 EXAMPLE Blog. Propulsé par Flask.</p>
    </footer>
</body>
</html>

Les modèles enfants héritent du modèle parent

Exemple

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

{% block title %}EXAMPLE Blog - Accueil{% endblock %}

{% block content %}
<h2>Derniers articles</h2>
<p>La liste des articles sera affichée dans les chapitres suivants.</p>
{% endblock %}

{% extends 'base.html' %}Il doit être écrit sur la première ligne du modèle enfant (à l'exception des commentaires). C'est une exigence stricte de Jinja2 — le moteur de template doit d'abord déterminer la relation d'héritage.


url_for() génère des liens

Ne codez pas les URL en dur, utilisezurl_for()pour rechercher l'adresse par nom de fonction.

Exemple

# Définir le point de terminaison de la route dans views.py
@app.route("/")
def index(): ...

@app.route("/post/<int:post_id>")
def post_detail(post_id): ...

Exemple

[mycode4 type="html"> Dans les modèles, url_for() génère des liens Accueil Article 3 Référencer les fichiers statiques [/mycode4]

La route a changé (par ex.,/post/Remplacer par/article/), dans le modèleurl_for()Générer automatiquement de nouvelles adresses.


Configuration des fichiers statiques

Par défaut, Flask utiliserastatic/le répertoire comme répertoire racine des fichiers statiques.

blog_project/
├── static/
│   ├── css/
│   │   └── style.css
│   ├── js/
│   │   └── main.js
│   └── images/
│       └── logo.png
├── templates/
└── app.py

Dans les modèles, viaurl_for('static', filename='css/style.css')référence.


Résumé du chapitre

Dans ce chapitre, vous avez maîtrisé le cœur des modèles Jinja2 : render_template() pour rendre les modèles, {{ }} pour afficher les variables, {% for/if %} pour le contrôle de flux, base.html + block + extends pour l'héritage de modèles, et url_for() pour générer des liens.

Maintenant, la page du blog est devenue un HTML bien structuré, et les parties communes ont été extraites dans base.html.

autres extensions