Sign In
Sign In
  1. Accueil
  2. CONSTRUIRE
  3. Data Manipulation
  4. Data Manipulation - Avancé
CONSTRUIRE
49 articles
Categories
Bulk translate
Les étapes dans le Flow Builder11
Start Intent1
🪄 Generate with AI4
Answers
File Upload
LiveChat Handover7
Ticket Handover1
API
Data Manipulation2
Data Manipulation - Avancé
Data Manipulation : exemples
Variables
Logic & Conditions2
User Input
[Obsolète] Mode Draft et Advanced Builder10
Trace dans le Flow Builder
Use Cases5

Data Manipulation - Avancé

Cet article présente la syntaxe avancée des modèles Jinja, ses filtres et l'accès aux attributs pour manipuler des variables dans l'étape Data Manipulation.

Mis à jour le 24 septembre 2026

Qu'est-ce que Jinja ?

Jinja est un moteur de modèles (templates) qui permet de mettre en forme du texte ; sa syntaxe s'inspire de Django et de Python.

Les modèles Jinja sont de simples fichiers texte. Un modèle contient des variables et/ou des expressions, remplacées par des valeurs au moment où le modèle est rendu, ainsi que des balises, qui pilotent la logique du modèle.

Vous trouverez la documentation officielle de Jinja ici

Fonctions de base

Manipulez les entrées à l'aide d'instructions simples (filtres et expressions) pour obtenir le résultat souhaité.

Par exemple : obtenir la liste des prix de tous les produits, arrondis à 2 décimales.

Text
products | map(attribute='item.price') | map('round', 2) | list

Vous n'avez besoin de connaître que quelques notions simples :

Accès aux attributs

Vous pouvez accéder aux attributs avec un point ou des crochets (pour les variables)

Python
foo = { bar: 'hey' }
foo.bar # => 'hey'

var1 = 'bar'
foo[var1] # => 'hey'

Affectations

Les affectations utilisent la balise set et peuvent avoir plusieurs cibles :

Python
{% set prices = products | map(attribute='item.price') | list %}
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% set key, value = 'my_key', 'my_value' %}

Expressions

Elles fonctionnent de façon très proche du Python classique ; même si vous ne travaillez pas avec Python, vous devriez vous y retrouver facilement.

  • Littéraux
    La forme la plus simple d'expression est le littéral. Les littéraux représentent des objets Python, comme des chaînes de caractères et des nombres. Voici les littéraux disponibles :

    • "Hello World"Tout ce qui se trouve entre deux guillemets doubles ou simples est une chaîne de caractères. Les chaînes sont utiles chaque fois que vous en avez besoin dans le modèle (par exemple comme arguments d'appels de fonctions et de filtres, ou simplement pour étendre ou inclure un modèle).

    • 42 / 123_456Les entiers sont des nombres sans partie décimale. Le caractère « _ » peut servir à séparer les groupes de chiffres pour plus de lisibilité.

    • 42.23 / 42.1e2 / 123_456.789Les nombres à virgule flottante s'écrivent avec un « . » comme séparateur décimal. Ils peuvent aussi s'écrire en notation scientifique, avec un « e » majuscule ou minuscule pour indiquer l'exposant. Le caractère « _ » peut servir à séparer les groupes de chiffres pour plus de lisibilité, mais pas dans l'exposant.

    • ['list', 'of', 'objects']Tout ce qui se trouve entre deux crochets est une liste. Les listes servent à stocker des données séquentielles que l'on parcourt ensuite.

    • ('tuple', 'of', 'values')Les tuples sont des listes non modifiables (« immuables »). Un tuple qui ne contient qu'un seul élément doit être suivi d'une virgule (('1-tuple',)). Les tuples servent généralement à représenter des ensembles de deux éléments ou plus. Voir l'exemple de liste ci-dessus pour plus de détails.

    • {'dict': 'of', 'key': 'and', 'value': 'pairs'}En Python, un dict est une structure qui associe des clés à des valeurs. Les clés doivent être uniques et ont toujours exactement une valeur.

    • true / false true est toujours vrai et false est toujours faux.

      Remarque : les constantes spéciales true, false et none s'écrivent bien en minuscules. Comme cela a déjà prêté à confusion (True était autrefois interprété comme une variable non définie, donc considérée comme fausse), les trois peuvent désormais aussi s'écrire avec une majuscule (True, False et None). Par souci de cohérence (tous les identifiants sont en minuscules), utilisez toutefois les versions en minuscules.

  • Calcul
    Permet d'effectuer des calculs sur des valeurs. Les opérateurs suivants sont pris en charge :

    • +Additionne deux objets. En général, il s'agit de nombres, mais si les deux objets sont des chaînes ou des listes, vous pouvez ainsi les concaténer. Ce n'est toutefois pas la méthode recommandée pour concaténer des chaînes ! Pour cela, utilisez plutôt l'opérateur ~. {{ 1 + 1 }} vaut 2.

    • -Soustrait le second nombre du premier. {{ 3 - 2 }} vaut 1.

    • /Divise deux nombres. Le résultat est un nombre à virgule flottante. {{ 1 / 2 }} vaut {{ 0.5 }}.

    • //Divise deux nombres et renvoie la partie entière du résultat. {{ 20 // 7 }} vaut 2.

    • %Calcule le reste d'une division entière. {{ 11 % 7 }} vaut 4.

    • *Multiplie l'opérande de gauche par celui de droite. {{ 2 * 2 }} renvoie 4. Permet aussi de répéter une chaîne plusieurs fois : {{ '=' * 80 }} affiche une barre de 80 signes égal.

    • **Élève l'opérande de gauche à la puissance de l'opérande de droite. {{ 2**3 }} renvoie 8. Contrairement à Python, les puissances enchaînées sont évaluées de gauche à droite : {{ 3**3**3 }} est évalué comme (3**3)**3, alors que Python l'évaluerait comme 3**(3**3). Utilisez des parenthèses pour préciser l'ordre voulu.

  • Comparaisons

    • ==Vérifie si deux objets sont égaux.

    • !=Vérifie si deux objets sont différents.

    • > vrai si la partie gauche est supérieure à la partie droite.

    • >= vrai si la partie gauche est supérieure ou égale à la partie droite.

    • < vrai si la partie gauche est inférieure à la partie droite.

    • <= vrai si la partie gauche est inférieure ou égale à la partie droite.

  • Logique

    • andRenvoie vrai si l'opérande de gauche et celui de droite sont vrais.

    • orRenvoie vrai si l'opérande de gauche ou celui de droite est vrai.

    • notInverse une condition (voir ci-dessous).

    • (expr)Les parenthèses regroupent une expression.

      Remarque : les opérateurs is et in acceptent aussi la négation en notation infixe : foo is not bar et foo not in bar au lieu de not foo is bar et not foo in bar. Toutes les autres expressions exigent une notation préfixe : not (foo and bar).

  • Autres opérateurs
    Les opérateurs suivants sont très utiles mais n'entrent dans aucune des deux autres catégories :

    • inTeste l'appartenance à une séquence ou à un dictionnaire. Renvoie vrai si l'opérande de gauche est contenu dans celui de droite. Par exemple, 1 in [1, 2, 3] renvoie true.

    • isEffectue un test.

    • | (pipe, barre verticale)Applique un filtre.

    • ~ (tilde)Convertit tous les opérandes en chaînes et les concatène.
      "Hello " ~ name ~ "!" renvoie Hello John!(si name == ‘John’)

    • ()Appelle un objet appelable : post.render(). Entre les parenthèses, vous pouvez utiliser des arguments positionnels et des arguments nommés, comme en Python :
      post.render(user, full=true).

    • . / []Récupère un attribut d'un objet. (Voir Variables)

Filtres

Les variables peuvent être modifiées par des filtres. Il s'agit d'une bibliothèque de fonctions utilitaires qui effectuent les transformations à votre place. Les filtres sont séparés de la variable par une barre verticale (|) et peuvent recevoir des arguments facultatifs entre parenthèses. Plusieurs filtres peuvent être enchaînés : le résultat de l'un est transmis au suivant.
Par exemple, name | trim | capitalize supprime les espaces autour du nom et met sa première lettre en majuscule.
Les filtres qui acceptent des arguments les placent entre parenthèses, comme pour un appel de fonction. Par exemple : listx | join(', ') assemble une liste en séparant les éléments par des virgules.
Vous pouvez utiliser un if en ligne avec des filtres : 'multiple' if array | count > 1 else 'one'
Beaucoup de filtres de liste renvoient des itérateurs (pour les boucles) plutôt que des listes : pensez à utiliser le filtre list.

Filtres intégrés

  • Liste complète des filtres
    Filtres intégrés de Jinja

  • Filtres les plus utilisés
    5 filtres sont signalés par l'étiquette [must know]. Ce sont les filtres de base à connaître : ils couvrent la plupart des opérations de manipulation de données. Les autres restent utiles, mais vous pourrez les consulter plus tard, le moment venu.

    • default
      Valeur par défaut si l'entrée n'existe pas

      Python
      'hey' | default('my_variable is not defined')
      => "hey"
      
      None | default('my_variable is not defined')
      => "my_variable is not defined"
    • capitalize / title / lower / upper
      Change la casse d'une chaîne

      Python
      'hello' | capitalize
      => "Hello"
      
      'arbitrary code execution' | title
      => "Arbitary Code Execution"
      
      'this is an example' | upper
      => "THIS IS AN EXAMPLE"
      
      'THIS IS AN EXAMPLE' | lower
      => "this is an example"
    • map [must know]
      Deux usages principaux :

      • Extraire des attributs des objets d'une liste

      • Appliquer un filtre à tous les éléments d'une liste

      Python
      products = [
      	{name: 'abc', nested: {price: 2.77}},
      	{name: 'def', nested: {price: 3.82}},
      	{name: 'ghi', nested: {price: 1.39}}
      ] 
      
      products | map(attribute='name') | map('capitalize') | list
      => ['Abc', 'Ghi', 'Def']
      
      products | map(attribute='nested.price') | map('round', 1) | list
      => [2.8, 3.8, 1.4]
    • selectattr / rejectattr [must know]
      Filtre une liste d'objets selon leurs attributs
      Prend en arguments un attribut et un test (voir la section Tests)

      Python
      users = [
      	{name: 'abc', active: True, role: 'admin'},
      	{name: 'def', active: False, role: 'admin'},
      	{name: 'ghi', active: True, role: 'builder'}
      ]
      
      users | selectattr('role', '==', 'admin') | list
      => [
      	{name: "abc", active: True, role: "admin"},
      	{name: "def", active: False, role: "admin"}
      ]
      
      users | selectattr('active') | list
      => [
      	{name: "abc", active: True, role: "admin"},
      	{name: "ghi", active: True, role: "builder"}
      ]
      
      # reverse of select
      users | rejectattr('active') | list
      => [
      	{name: "def", active: False}
      ]
      
      # with a regex
      apps = [
        {name: 'bosv1', database: 'bos-pgsql-v1'},
      	{name: 'boav1', database: 'boa-mango'},
      	{name: 'bosv2', database: 'bos-pgsql-v2'}
      ]
      apps | selectattr('database', 'search', '.*pgsql.*') | list
      => [
      	{name: 'bosv1', database: 'bos-pgsql-v1'},
      	{name: 'bosv2', database: 'bos-pgsql-v2'}
      ]
    • select / reject [must know]
      Prend un test en argument (voir la section Tests)

      Python
      # simple selects
      numbers | select("odd")
      numbers | select("even")
      numbers | select("divisibleby", 3)
      numbers | select("lessthan", 42)
      
      # Reject is reversed of select
      numbers | reject('odd')
      
      # Fin the number of users who are admin (assuming a map of roles)
      ['admin', 'nope', 'admin'] | select("==", "admin") | list
      => ['admin', 'admin'] | count 
      => 2
      
      # filter undefined variables after a map operation
      [undefined, "hey", "oh"] | select('defined') | list
      => ["hey", "oh"]
      
      # select items containing "v1"
      ["prod-v1", "prod_v2", "item_v1"] | select("in", "v1") | list
      => ["prod-v1", "item_v1"]
      
      # with regex
      ["p-v1_lk", "c-v2", "m-v1-lk"] | select("search", ".*v1(-|_)lk") | list
      => ["p-v1_lock", "m-v1-lock"]
    • flatten [must know]
      Après un map, des select ou des manipulations plus complexes, il est fréquent d'obtenir des listes de ce type : `[[1,2], [3,4]]`
      Utilisez flatten pour les fusionner en une seule liste

      Python
      [[1, 2], [3, 4]] | flatten
      => [1, 2, 3, 4]
    • list [must know]
      Convertit une valeur en liste. Vous l'utiliserez souvent, car la plupart des filtres utiles renvoient des itérateurs et non des listes : il faut alors les reconvertir manuellement en listes.

    • join

      Python
      ['abc', 'def', 'ghi'] | join(', ')
      => "abc, def, ghi"
      
      [{name: 'abc'}, {name: 'def'}] | join(', ', attribute='name')
      => "abc, def"
    • dictsort

      Python
      for key, value in mydict | dictsort
      => #sort the dict by key, case insensitive
      
      for key, value in mydict | dictsort(reverse=true)
      => #sort the dict by key, case insensitive, reverse order
      
      for key, value in mydict | dictsort(true)
      => #sort the dict by key, case sensitive
      
      for key, value in mydict | dictsort(false, 'value')
      => #sort the dict by value, case insensitive
    • format
      Met en forme une chaîne (printf)

      Python
      "%s, %s!" | format('Hello', 'world')
      Hello, world!
    • groupby

      Python
      users = [
      	{name: 'pierre', city: 'paris'},
        {name: 'leo', city: 'marseille'},
      	{name: 'lucy', city: 'paris'}
      ] 
      
      # Useful to use with for loops (for city, items in users | groupby('city'))
      users | groupby("city")
      => [
      		["marseille", [
      				{"city":"marseille", "name": "leo"}
      			]
      		],
      		["paris", [
      				{"city": "paris", "name": "pierre"},
      				{"city": "paris", "name": "lucy"}
      			]
      		]
      	]
      
      apps = [
        {name: 'bos', database: 'bos-pgsql-staging'},
      	{name: 'boa', database: 'bos-pgsql-staging'},
      	{name: 'bos', database: 'bos-pgsql-prod'},
      	{anon: true, database: 'Anon-mvp-pgsql-other'}
      ]
      
      apps | groupby("name", default: 'unknown')
      => [
      	["bos", [
      		{name: 'bos', database: 'bos-pgsql-staging'},
      		{name: 'bos', database: 'bos-pgsql-prod'},
      	],
      	["boa", [
      			{name: 'boa', database: 'bos-pgsql-staging'}
      		]
      	],
      	["unknown", [
      			{anon: true, database: 'Anon-mvp-pgsql-other'}
      		]
      	]
      ]
    • int / string

      Python
      '43' | int
      => 43
      
      'h43' | int
      => 0
      
      34 | string
      => '34'
      
      {name: 'hello'} | string
      => "{name: 'hello'}"
    • first / last

      Python
      [1, 2, 3] | first
      => 1
      
      [1, 2, 3] | last
      => 3
    • length / count

      Python
      [1, 2, 3] | length
      => 3
      
      [1, 3, 5, 10] | count # alias
      => 4
    • max / min

      Python
      [1, 2, 3] | min
      => 1
      
      [{code: 1}, {code: 2}] | max(attribute='code')
      => 2
    • random

      Python
      ['a', 'b', 'c'] | random
      => 'c' # random item of the list
    • replace

      Python
      'Hello World' | replace('Hello', 'Goodbye')
      => "Goodbye World"
      
      # Restrict to the first x occurences
      'aaaaargh' | replace('a', 'd,', 2)
      => d,d,aaargh
    • reverse

      Python
      ['a', 'b', 'c'] | reverse | list
      => ['c', 'b', 'a']
    • round

      Python
      42.55 | round
      => 43.0
      
      42.55 | round(1, 'floor')
      => 42.5
      
      42.54 | round(1, 'ceiling')
      => 42.6
    • slice

      Python
      ['a', 'b', 'c'] | slice(3) | list
      => [['a'], ['b'], ['c']]
    • sort

      Python
      ['b', 'a'] | sort | list
      => ["a", "b"]
      
      ['a', 'b'] | sort(reverse=true) | list
      => ["b", "a"]
      
      ['a', 'B', 'A'] | sort(case_sensitive=true) | list
      => ["A", "B", "a"]
      
      [{text: 'b'}, {text: 'a'}] | sort(attribute='text') | list
      => [{text: 'a'}, {text: 'b'}]
    • sum

      Python
      [22, 48] | sum
      => 70
      
      [{price: 22}, {price: 48}] | sum(attribute='price')
      => 70
    • trim

      Python
      "   hello   " | trim
      => "hello"
    • truncate

      Python
      "foo bar baz qux" | truncate(9)
      => "foo..."
      
      # Truncate regardless of words
      "foo bar baz qux" | truncate(9, True)
      => "foo ba..."
      
      # Truncate use a default leeway of 5, the fourth parameter.
      "foo bar baz qux" | truncate(11)
      => "foo bar baz qux"
      "foo bar baz qux" | truncate(11, False, '[...]', 0)
      => "foo bar[...]"
    • unique

Filtres personnalisés

Ces filtres supplémentaires sont développés par ViaSay.

Filtres de date

Les filtres suivants convertissent des chaînes représentant une date ou une durée en objets Python datetime/timedelta.

  • to_date : convertit une chaîne en objet datetime ; prend tzname en paramètre.

Python
{% set departure="20230730T1028" | to_date("Europe/Paris") %}
{% set departure=departure.strftime("%H:%M:%S - %d/%m/%Y") %}
# departure will contain the following value: "10:28:00 - 30/07/2023"
  • to_timedelta : convertit une chaîne de durée en objet timedelta.

Python
{% set time_before_departure="1 day, 17:02:31" | to_timedelta %}
{% set today="20230730T1028" | to_date("Europe/Paris") %}
{% set departure=today + time_before_departure %}
{% set departure=departure.strftime("%H:%M:%S - %d/%m/%Y") %}
# departure will contain the following value:  "03:30:03 - 01/08/2023"
  • timestamp_to_date : convertit un timestamp Unix (entier en millisecondes) en datetime

Python
{% set departure=1691597204000 | timestamp_to_date %}
{% set departure=departure.strftime("%H:%M:%S - %d/%m/%Y") %}
# departure will contain the following value:  "16:06:44 - 09/08/2023"

Attention : vous ne pouvez pas stocker un datetime dans une variable de sortie de l'étape Data Manipulation, sous peine d'erreur d'exécution. Vous devez d'abord le convertir en chaîne avec strftime, comme dans les exemples ci-dessus.

Tests

En plus des filtres, des « tests » sont disponibles. Ils permettent de vérifier une variable par rapport à une expression courante. Pour tester une variable ou une expression, ajoutez is suivi du nom du test après la variable. Par exemple, pour savoir si une variable est définie, écrivez name is defined, qui renvoie true ou false selon que name est défini ou non dans le contexte du modèle.

Les tests peuvent aussi accepter des arguments. Si le test ne prend qu'un seul argument, vous pouvez omettre les parenthèses.

Liste des tests intégrés

Méthodes natives de Python

Vous pouvez utiliser la plupart des méthodes natives des objets Python.

Par exemple, vous pouvez découper une chaîne ou fusionner des dicts :

Python
"abc, def, ghi".split(', ')
=> ['abc', 'def', 'ghi']

{name: 'pierre'}.update({role: 'admin'})
=> {name: 'pierre', role: 'admin'}

Voici les méthodes disponibles pour les principaux types d'objets :

  • String

  • Dict

  • List

Utilisation avancée

Description de toutes les fonctionnalités du moteur de modèles utilisables dans le bloc de code. Elles permettent des manipulations plus avancées avec des boucles, des if multiples, des fonctions, etc. (programmation impérative).

Nous utilisons Jinja 3 pour les modèles. Si vous avez besoin de références ou de précisions après avoir lu ce document, consultez leur documentation officielle.

Jinja étant dérivé de Python, vous retrouverez de nombreuses similitudes et pourrez même utiliser certaines méthodes Python sur certains objets.

Délimiteurs

Il existe plusieurs types de délimiteurs. Les délimiteurs par défaut sont les suivants :

  • {% ... %} pour les instructions (n'affichent aucune valeur)

  • {{ ... }} pour les expressions (affichées dans le résultat du modèle)

  • {# ... #} pour les commentaires, non inclus dans le résultat du modèle

Dans le bloc de code, vous pouvez tous les utiliser, mais le résultat affiché est de toute façon ignoré. Vous utiliserez donc surtout les instructions et les commentaires.

Dans les sorties, les valeurs sont encapsulées dans une expression, pour rester simple.

Affectations

Les affectations utilisent la balise set et peuvent avoir plusieurs cibles :

Python
{% **set** navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% **set** key, value = call_something() %}
  • Portée des variables
    Gardez à l'esprit qu'une variable définie à l'intérieur d'un bloc (sauf un if, qui ne crée pas de portée) n'est pas visible à l'extérieur de ce bloc. Il en va de même pour les boucles. Par conséquent, le modèle suivant ne fera pas ce que vous attendez :

    Python
    {% set iterated = false %}
    {% for item in seq %}
        {{ item }}
        {% set iterated = true %}
    {% endfor %}
    {% if not iterated %} did not iterate {% endif %}

    Ce n'est pas possible. Utilisez plutôt d'autres constructions, comme le bloc else de la boucle ou la variable spéciale loop :

    Python
    {% for item in seq %}
        {{ item }}
    {% else %}
        did not iterate
    {% endfor %}

    Les cas plus complexes peuvent être traités avec des objets namespace, qui permettent de propager des modifications d'une portée à l'autre :

    Python
    {% set ns = namespace(found=false) %}
    {% for item in items %}
        {% if item.check_something() %}
            {% set ns.found = true %}
        {% endif %}
        * {{ item.title }}
    {% endfor %}
    Found item having something: {{ ns.found }}

Liste des structures de contrôle

  • If / elif / else
    L'instruction if est comparable à celle de Python. Dans sa forme la plus simple, elle permet de vérifier qu'une variable est définie, non vide et non fausse :

    Python
    {% if users %}
    	{% set text = 'users' %}
    {% endif %}

    Pour plusieurs branches, elif et else s'utilisent comme en Python. Vous pouvez aussi y employer des expressions plus complexes :

    Python
    {% if kenny.sick %}
        {% set text = 'Kenny is sick.' %}
    {% elif kenny.dead %}
    		{% set text = 'You killed Kenny!  You ****!!!' %}
    {% else %}
    		{% set text = 'Kenny looks okay --- so far' %}
    {% endif %}

    If peut aussi s'utiliser comme expression en ligne :

    Python
    {% set text = 'layout' if layout_template is defined else 'default' %}

    et pour filtrer une boucle :

    Python
    {% for user in users if not user.hidden %}
        {% do usernames.append(user) %}
    {% endfor %}
  • For

    Parcourt chaque élément d'une séquence. Par exemple :

    Python
    {% for user in users %}
      {% do array.append(user | trim | capitalize) %}
    {% endfor %}

    Comme les variables des modèles conservent les propriétés de leurs objets (issues de Python), il est possible de parcourir des conteneurs comme les dicts :

    Python
    {% for key, value in my_dict.items() %}
    		{% array.append([key, value]) %}
    {% endfor %}

    Les dictionnaires Python ne sont pas forcément dans l'ordre où vous souhaitez les afficher. Si l'ordre compte, utilisez le filtre | dictsort.

    Python
    {% for key, value in my_dict | dictsort %}
        {% array.append([key, value]) %}
    {% endfor %}

    À l'intérieur d'un bloc de boucle for, vous avez accès à quelques variables spéciales :

    Variable

    Description

    loop.index

    L'itération en cours de la boucle (à partir de 1).

    loop.index0

    L'itération en cours de la boucle (à partir de 0).

    loop.revindex

    Le nombre d'itérations restantes jusqu'à la fin de la boucle (à partir de 1)

    loop.revindex0

    Le nombre d'itérations restantes jusqu'à la fin de la boucle (à partir de 0)

    loop.first

    Vrai s'il s'agit de la première itération.

    loop.last

    Vrai s'il s'agit de la dernière itération.

    loop.length

    Le nombre d'éléments de la séquence.

    loop.cycle

    Une fonction utilitaire qui alterne entre les valeurs d'une liste.

    loop.depth

    Indique le niveau de profondeur atteint dans une boucle récursive. Commence à 1

    loop.depth0

    Indique le niveau de profondeur atteint dans une boucle récursive. Commence à 0

    loop.previtem

    L'élément de l'itération précédente. Non défini lors de la première itération.

    loop.nextitem

    L'élément de l'itération suivante. Non défini lors de la dernière itération.

    loop.changed(*val)

    Vrai si la fonction a été appelée précédemment avec une valeur différente (ou jamais appelée).

    Dans une boucle for, il est possible d'alterner entre plusieurs chaînes ou variables à chaque passage grâce à la fonction spéciale loop.cycle :

    Python
    {% for row in rows %}
    		{% set css_class = loop.cycle('odd', 'even') %}
        {% do array.append([css_class, row]) %}
    {% endfor %}

    Contrairement à Python, il est impossible d'utiliser break ou continue dans une boucle. Vous pouvez en revanche filtrer la séquence pendant le parcours, ce qui permet d'ignorer certains éléments. L'exemple suivant ignore tous les utilisateurs masqués :

    Python
    {% for user in users if not user.hidden %}
        {% do filtered_users.append(user) %}
    {% endfor %}

    L'avantage est que la variable spéciale loop compte correctement, sans tenir compte des utilisateurs non parcourus.

    Si aucune itération n'a eu lieu, parce que la séquence était vide ou que le filtrage en a retiré tous les éléments, vous pouvez afficher un bloc par défaut avec else :

    Python
    {% for user i users %}
        {% do array.append(user) %}
    {% else %}
        {% do array.append('empty') %}
    {% endfor %}

    En Python, les blocs else s'exécutent chaque fois que la boucle correspondante ne s'est pas interrompue par un break. Comme les boucles ne peuvent de toute façon pas être interrompues, le mot-clé else se comporte ici un peu différemment.

    Il est aussi possible d'utiliser des boucles récursives, pratique pour traiter des données récursives comme des plans de site ou du RDFa. Pour cela, ajoutez le modificateur recursive à la définition de la boucle, puis appelez la variable loop avec le nouvel itérable là où vous voulez lancer la récursion.

    L'exemple suivant construit un plan de site avec des boucles récursives :

    Python
    {% for item in sitemap recursive %}
        {% set title = item.title %}</a>
        {% if item.children %}
            {% do loop(item.children) %}
        {% endif %}
    		{% do array.append(title) %}
    {% endfor %}

    La variable loop désigne toujours la boucle la plus proche (la plus interne). Avec plusieurs niveaux de boucles, vous pouvez réaffecter la variable loop en écrivant {% set outer_loop = loop %} après la boucle à utiliser de façon récursive, puis l'appeler avec {{ outer_loop(…) }}

    Notez que les affectations faites dans une boucle sont effacées à la fin de l'itération et ne survivent pas à la portée de la boucle. Consultez Affectations, portée des variables, pour savoir comment gérer ce cas.

    Si vous voulez simplement vérifier si une valeur a changé depuis l'itération précédente ou va changer à la suivante, utilisez previtem et nextitem :

    Python
    {% for value in values %}
        {% if loop.previtem is defined and value > loop.previtem %}
            The value just increased!
        {% endif %}
        {{ value }}
        {% if loop.nextitem is defined and loop.nextitem > value %}
            The value will increase even more!
        {% endif %}
    {% endfor %}

    Si seule compte la question de savoir si la valeur a changé, changed est encore plus simple :

    Python
    {% for entry in entries %}
        {% if loop.changed(entry.category) %}
            <h2>{{ entry.category }}</h2>
        {% endif %}
        <p>{{ entry.message }}</p>
    {% endfor %}

Liste des fonctions globales

  • range
    Renvoie une liste contenant une progression arithmétique d'entiers. range(i, j) renvoie [i, i+1, i+2, ..., j-1] ; le début vaut 0 par défaut. Si un pas (step) est fourni, il indique l'incrément (ou le décrément). Par exemple, range(4) et range(0, 4, 1) renvoient [0, 1, 2, 3]. La borne de fin est exclue ! Ce sont exactement les indices valides d'une liste de 4 éléments.
    C'est utile pour répéter un bloc du modèle plusieurs fois, par exemple pour remplir une liste. Imaginez que vous avez 7 utilisateurs dans la liste mais que vous souhaitez afficher trois éléments vides pour imposer une hauteur en CSS :

    Python
    <ul>
    {% for user in users %}
        <li>{{ user.username }}</li>
    {% endfor %}
    {% for number in range(10 - users | count) %}
        <li class="empty"><span>...</span></li>
    {% endfor %}
    </ul>
  • lipsum
    Génère du texte lorem ipsum pour le modèle. Par défaut, cinq paragraphes HTML de 20 à 100 mots chacun sont générés. Si html vaut False, du texte brut est renvoyé. Pratique pour produire un contenu simple afin de tester une mise en page.

  • dict
    Une alternative pratique aux littéraux de dict. {'foo': 'bar'} équivaut à dict(foo='bar').

  • cycler
    Parcourt des valeurs en les renvoyant une à une, puis recommence au début une fois la fin atteinte.
    Semblable à loop.cycle, mais utilisable en dehors des boucles ou sur plusieurs boucles. Par exemple, pour afficher une liste de dossiers et de fichiers en leur attribuant alternativement les classes « odd » et « even ».
    Chaque argument positionnel est renvoyé dans l'ordre indiqué à chaque cycle.

    • propriétés

      • current
        Renvoie l'élément courant, c'est-à-dire celui qui sera renvoyé au prochain appel de [next()](https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-globals.cycler.next).

      • next()
        Renvoie l'élément courant, puis fait avancer [current](https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-globals.cycler.current) à l'élément suivant.

      • reset()
        Revient au premier élément.

  • joiner
    Un petit utilitaire qui sert à « joindre » plusieurs sections. On passe une chaîne à un joiner, qui la renvoie à chaque appel sauf le premier (où il renvoie une chaîne vide). Vous pouvez l'utiliser ainsi pour assembler des éléments :

  • namespace
    Crée un nouveau conteneur qui accepte l'affectation d'attributs avec la balise {% set %} :

    Python
    {% set ns = namespace() %}
    {% set ns.foo = 'bar' %}

    Son but principal est de pouvoir transmettre une valeur de l'intérieur d'une boucle vers une portée extérieure. Les valeurs initiales peuvent être fournies sous forme de dict, d'arguments nommés, ou des deux (même comportement que le constructeur dict de Python) :

    Python
    {% set ns = namespace(found=false) %}
    {% for item in items %}
        {% if item.check_something() %}
            {% set ns.found = true %}
        {% endif %}
         {{ item.title }}
    {% endfor %}
    Found item having something: {{ ns.found }}

Macros (fonctions)

Les macros sont comparables aux fonctions des langages de programmation classiques. Elles permettent de regrouper des blocs souvent utilisés dans des fonctions réutilisables, pour ne pas vous répéter (principe « DRY »).

Voici un petit exemple de macro qui affiche un élément de formulaire :

Python
{% set registered_users = [] %}

{% macro register_users(users, bot='', role='basic') -%}
		{% for user in users %}
		  {% do registered_users.append(user.update({role: role, bot: 'a'})) %}
		{% endfor %}
{%- endmacro %}

{% macro filter_sensitive(text, filter='[SENSITIVE]') -%}
		{# bank cards #}
		{% set filtered = text | regex_replace('^4[0-9]{12}(?:[0-9]{3})?$', filter) %}
		{# phone numbers #}
		{% set filtered = filtered | regex_replace('^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$', filter) %}
		
		{{ filtered }}
{%- endmacro %}

La macro peut ensuite être appelée comme une fonction dans le namespace :

Python
register_users([{name: 'pierre'}, {name: 'paul'}], role='admin')
register_users([{name: 'leo'}, {name: 'lucy'}], role='builder', bot='op')

=> registered_users = [
		{name: 'pierre', role: 'admin', bot=''},
		{name: 'paul', role: 'admin', bot=''},
		{name: 'leo', role: 'builder', bot='op'},
		{name: 'lucy', role: 'builder', bot='op'}
]

Dans une macro, vous avez accès à trois variables spéciales :

  • varargs
    Si la macro reçoit plus d'arguments positionnels qu'elle n'en accepte, ceux-ci sont placés dans la variable spéciale varargs, sous forme de liste de valeurs.

  • kwargs
    Comme varargs, mais pour les arguments nommés. Tous les arguments nommés non utilisés sont stockés dans cette variable spéciale.

  • caller
    Si la macro a été appelée depuis une balise call, l'appelant est stocké dans cette variable sous forme de macro appelable.

Les macros exposent aussi certains de leurs détails internes. Les attributs suivants sont disponibles sur un objet macro :

  • name
    Le nom de la macro. {{ input.name }} affiche input.

  • arguments
    Un tuple contenant les noms des arguments acceptés par la macro.

  • catch_kwargs
    Vrai si la macro accepte des arguments nommés supplémentaires (c'est-à-dire si elle utilise la variable spéciale kwargs).

  • catch_varargs
    Vrai si la macro accepte des arguments positionnels supplémentaires (c'est-à-dire si elle utilise la variable spéciale varargs).

  • caller
    Vrai si la macro utilise la variable spéciale caller et peut être appelée depuis une balise call.

Une macro dont le nom commence par un tiret bas (underscore) n'est pas exportée et ne peut pas être importée.

Call

Dans certains cas, il peut être utile de passer une macro à une autre macro. Pour cela, utilisez le bloc spécial call.

Il est aussi possible de renvoyer des arguments au bloc call, ce qui en fait une alternative aux boucles. De manière générale, un bloc call fonctionne exactement comme une macro sans nom.

Cet article vous a-t-il aidé ?

Sur cette page
  • Accès aux attributs
  • Affectations
  • Expressions
  • Filtres
  • Filtres intégrés
  • Filtres personnalisés
  • Tests
  • Méthodes natives de Python
  • Délimiteurs
  • Affectations
  • Liste des structures de contrôle
  • Liste des fonctions globales
  • Macros (fonctions)
  • Call

Made from France 💙

Catégories

  • ANALYTIQUE
  • CONSTRUIRE
  • LOUIS AI
  • INTÉGRER

🔗 Useful Links

  • Sign In
  • Website
  • Terms & Conditions

© 2026

MindsayPropulsé par Mindsay

Rechercher dans le centre d’aide…

Rechercher des articles du centre d’aide