Outils pour utilisateurs

Outils du site


dev:python:flask:templates

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
dev:python:flask:templates [2026/03/28 11:07] yoanndev:python:flask:templates [2026/04/10 06:09] (Version actuelle) yoann
Ligne 1: Ligne 1:
 {{tag>dev python flask templates jinja2}} {{tag>dev python flask templates jinja2}}
  
-:TODO_DOCUPDATE: 
  
 ====== Flask : Utilisation des templates ====== ====== Flask : Utilisation des templates ======
Ligne 8: Ligne 7:
 ===== Généralités ===== ===== Généralités =====
  
-Grossièrement, le **template** est une page web à trous. Il contient des sections statiques en HTML/javascript directement interprétables par le navigateur web et des section non remplies désignées **placeholders**. Le contenu des **placeholders** est généré par l'application à l'exécution pour obtenir un comportement dynamique.+Grossièrement, le **template** est une page web à trous. Il contient des sections invariantes en HTML/javascript directement interprétables par le navigateur web et des sections dynamiques ou non remplies désignées **placeholders**. Le contenu des **placeholders** est généré par l'application à l'exécution pour obtenir un comportement dynamique.
  
 **Flask** s'appuie sur le moteur **Jinja2** pour la gestion des templates. Plusieurs éléments syntaxiques sont disponibles pour délimiter les sections à l'attention du moteur de templates : **Flask** s'appuie sur le moteur **Jinja2** pour la gestion des templates. Plusieurs éléments syntaxiques sont disponibles pour délimiter les sections à l'attention du moteur de templates :
  
-  * ''%%{{ }}%%'' Affiche le résultat du code Python ;+  * ''%%{{ }}%%'' Affiche le résultat du code Python (balises HTML échappées) ;
   * ''%%{% %}%%'' Code Python à interpréter ;   * ''%%{% %}%%'' Code Python à interpréter ;
   * ''%%{# #}%%'' Commentaires.   * ''%%{# #}%%'' Commentaires.
Ligne 18: Ligne 17:
  
  
-<code html>+<code html [highlight_lines_extra="8,9"]>
 <!DOCTYPE html> <!DOCTYPE html>
 <html lang="en"> <html lang="en">
Ligne 70: Ligne 69:
  
  
-===== La fonction url_for() =====+===== La fonction helper url_for() =====
  
-Depuis le template on peut utiliser la fonction helper **''url_for()''** pour créer un lien vers une autre page : l'argument est le **nom de la fonction** associée à la route : 
  
-Dans notre projet Flask, on a une fonction nommée par exemple ''new_universe'' :+Si les liens vers les autres pages sont définis en dur dans les templates, ils deviendront invalides lorsque les routes de l'application Flask seront modifiées. 
 + 
 +C'est pourquoi il est recommandé d'utiliser la fonction helper **''url_for()''** pour définir les liens vers les autres pages/actions. 
 + 
 +L'argument à fournir est un **nom fonction** associée à la vue ( associée à une route de l'application Flask). 
 + 
 + 
 +Dans notre projet Flask, on a une fonction nommée par exemple ''create_universe'' :
  
 <code python> <code python>
 @app.route('/create/universe', methods=['GET', 'POST']) @app.route('/create/universe', methods=['GET', 'POST'])
-def new_universe():+def create_universe():
     if request.method == 'POST':     if request.method == 'POST':
 ... ...
Ligne 87: Ligne 92:
 <code html> <code html>
 ... ...
- <a href="{{ url_for('new_universe') }}" class="active tm-paging-link">+</a>+ <a href="{{ url_for('create_universe') }}" class="active tm-paging-link">+</a>
 ... ...
 </code> </code>
  
-===== Le système de filtre =====+===== Héritage =====
  
 +La notion d'héritage appliquée au template va permettre de **factoriser** le code. La factorisation augmente la qualité du code et simplifie la maintenance.
 +  * On définit un template parent contenant des **placeholders** ;
 +  * Chaque enfant héritant du document parent devra définit le contenu des **placeholders** ; 
  
-===== Notion d'héritage pour les templates ===== 
  
-Le document de base contient du code HTML pouvant être partagé par d'autres pages (factorisation).+  * En général on définit un document ''base.html'' contenant la structure générale du site/application web ; 
 +  * Chaque enfant complète les placeholders pour produire la réponse (la page web complète à retourner au client).
  
-  * On crée un document contenant des sections vides nommées avec la syntaxe 
  
 +Un exemple de document parent avec en surbrillance la définition des placeholders :
 +
 +<code html base.html [highlight_lines_extra="5,23"]>
 +<!DOCTYPE html>
 +<html lang="fr">
 +<head>
 +  <meta charset="utf-8">
 +  <title>{% block title %}{% endblock %}</title>
 +  <meta name="keywords" content="mot1, mot2, mot3, mot4">
 +  <meta name="description" content="ma description de page ici">
 +  <link rel="icon" type="image/png" href="/static/images/favicon-16x16.png" sizes="16x16">
 +  <link rel="icon" type="image/png" href="/static/images/favicon-32x32.png" sizes="32x32">
 +  <link rel="stylesheet" href="style.css">
 +</head>
 +<body>
 +  <header>
 +    <!--contenu statique de l'entete -->
 +  </header>
 +  <nav>
 +    <!-- barre de navigation -->
 +    <a href="#">Accueil</a>
 +    <a href="#">Aide</a>
 +    <a href="#">A propos</a>
 +  </nav>
 +  <div class="content">
 +    {% block content %}{% endblock %}
 +  </div>
 +  <footer>
 +    <!-- contenu statique du pied de page -->
 +  </footer>
 +  <script src="script.js"></script>
 +</body>
 +</html>
 +</code>
 +
 +Un exemple de document enfant :
 +
 +<code html index.html [highlight_lines_extra="7,12"]>
 +{% extends 'base.html' %}
 +{#
 +  Hérite du template "base.html"
 +  doit redéfinir les placeholders : "title" et "content"
 +#}
 +
 +{% block content %}
 +  <aside>
 +      <!-- section messages flash -->
 +  </aside>
 +  <main>
 +    <h1>{% block title %} Accueil {% endblock %}</h1>
 +    <p>{{ msg }}</p>
 +  </main>
 +  <aside>
 +      <!-- section status -->
 +  </aside>
 +{% endblock %}
 +</code>
 +
 +<note>
 +Dans le template enfant, le block "title" est défini à l'intérieur du block "content" : C'est parfaitement supporté par le moteur de template et cela permet de factoriser : le texte "Accueil" sera utilisé à la fois pour le titre de niveau 1 et pour le titre du document HTML dans le template parent.  
 +</note>
 +
 +La [[#rendu_du_template|définition de la route dans l'application Flask]] reste inchangée.
 +
 +===== Boucles et conditions =====
 +
 +Le moteur de template supporte la boucle ''for'' avec la syntaxe suivante :
 +
 +<code html [highlight_lines_extra="16,20"]>
 +{% extends 'base.html' %}
 +{#
 +  Hérite du template "base.html"
 +  doit redéfinir les placeholders : title et content
 +#}
 +
 +{% block content %}
 +  <aside>
 +      <!-- section messages flash -->
 +  </aside>
 +  <main>
 +    <h1>{% block title %} Accueil {% endblock %}</h1>
 +    <p>{{ msg }}</p>
 +    <!-- Affiche tous les commentaires -->
 +    <div style="width: 50%; margin: auto">
 +      {% for comment in comments %}
 +        <div style="padding: 10px; background-color: #EEE; margin: 20px">
 +            <p style="font-size: 24px">{{ comment }}</p>
 +        </div>
 +      {% endfor %}
 +  </main>
 +  <aside>
 +      <!-- section status -->
 +  </aside>
 +{% endblock %}
 +</code>
 +
 +La variable comments devra être fournie par la vue au template : 
 +
 +<code python>
 +    @app.route('/')
 +    @app.route('/home')
 +    def supply_index() -> str:
 +        msg = "Hello World !!!"
 +        comments = [
 +            "commentaire 1",
 +            "commentaire 2",
 +            "commentaire 3",
 +            "commentaire 4",
 +        ]
 +        return render_template('index.html', msg=msg, comments=comments)
 +</code>
 +
 +
 +La structure conditionnelle ''if'' est supportée avec la syntaxe suivante :
 +<code html [highlight_lines_extra="17,21"]>
 +{% extends 'base.html' %}
 +{#
 +  Hérite du template "base.html"
 +  doit redéfinir les placeholders : title et content
 +#}
 +
 +{% block content %}
 +  <aside>
 +      <!-- section messages flash -->
 +  </aside>
 +  <main>
 +    <h1>{% block title %} Accueil {% endblock %}</h1>
 +    <p>{{ msg }}</p>
 +    <!-- Affiche tous les commentaires -->
 +    <div style="width: 50%; margin: auto">
 +      {% for comment in comments %}
 +        {% if loop.index % 2 == 0 %}
 +          {% set bg_color = '#e6f9ff' %}
 +        {% else %}
 +          {% set bg_color = '#eee' %}
 +        {% endif %}
 +        <div style="padding: 10px; background-color: {{ bg_color }}; margin: 20px">
 +            <p style="font-size: 24px">{{ comment }}</p>
 +        </div>
 +      {% endfor %}
 +  </main>
 +  <aside>
 +      <!-- section status -->
 +  </aside>
 +{% endblock %}
 +</code>
 +
 +===== Filtres Jinja2 =====
 +
 +Les filtres Jinja permettent d'appliquer des transformations/opérations sur les variables directement depuis les templates : on peut par exemple passer un texte en majuscules en appliquant le filtre ''upper''. La syntaxe à utiliser est ''%%{{ var | filtre }}%%''
 +
 +<code html>
 +<div style="padding: 10px; background-color: {{bg_color}}; margin: 20px">
 +  <!-- Affiche le commentaire en majuscules -->
 +  <p style="font-size: 24px">{{ comment | upper }}</p>
 +</div>
 +</code>
 +
 +Le filtre ''safe'' est important à connaître : il permet d'autoriser l'interprétation du code HTML provenant des variables. En effet, par défaut, le code contenu dans les variables est échappé par le moteur Jinja2 pour éviter les attaques de type **XSS**((Cross Site Scripting))
 +
 +<code html>
 +{# Ici les balises sont échappées par le moteur Jinja : elles seront affichées comme du texte #}
 +{{ "<h2>CECI NE PRODUIRA PAS UN SOUS-TITRE</h2>" }}
 +
 +{# le filtre safe permet d'interpréter les balises et de produire un titre HTML #}
 +{{ "<h2>SOUS TITRE</h2>" | safe }}
 +</code>
 +
 +<note>
 +Les valeurs saisies ou retournées par l'utilisateur devraient être systématiquement échappées pour limiter les risques d'injection XSS (confère [[https://flask.palletsprojects.com/en/stable/quickstart/#html-escaping|Échappement HTML]]).
 +</note>
  
 ===== Formater la date dans le template ===== ===== Formater la date dans le template =====
dev/python/flask/templates.1774696074.txt.gz · Dernière modification : 2026/03/28 11:07 de yoann