Sign In
Sign In
  1. Home
  2. CONSTRUIR
  3. Manipulación de datos
  4. Manipulación de datos - Avanzada
CONSTRUIR
49 articles
Categorías
Traducción masiva
Pasos en Flow Builder11
Iniciar Intent1
🪄 Generar con IA4
Respuestas
Carga de archivos
Transferencia a chat en directo7
Transferencia a tickets1
API
Manipulación de datos2
Manipulación de datos - Avanzada
Manipulación de datos - Ejemplos
Variables
Lógica y condiciones2
Entrada del usuario
[Deprecated] Modo borrador y creador avanzado10
Trace en Flow Builder
Use Cases5

Manipulación de datos - Avanzada

Aprende la sintaxis avanzada de plantillas Jinja, los filtros y el acceso a atributos para manipular variables dentro del paso de manipulación de datos.

Updated on 24 de septiembre de 2026

¿Qué es Jinja?

Jinja es un motor de plantillas que permite dar formato al texto; su sintaxis está inspirada en Django y Python.

Las plantillas Jinja son simplemente archivos de texto... Una plantilla contiene variables y/o expresiones, que se reemplazan por valores cuando se renderiza una plantilla; y etiquetas, que controlan la lógica de la plantilla.

Puedes consultar la documentación oficial de Jinja: aquí

Funciones básicas

Manipula las entradas con instrucciones sencillas (filtros y expresiones) para obtener el resultado deseado.

Por ejemplo, obtener la lista de precios de todos los productos y redondearlos a 2 decimales.

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

Solo necesitarás conocer algunas cosas sencillas:

Acceso a atributos

Puedes acceder a los atributos con un punto o corchetes (para las variables)

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

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

Asignaciones

Las asignaciones utilizan la etiqueta set y pueden tener varios destinos:

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

Expresiones

Funcionan de forma muy similar a Python normal; aunque no trabajes con Python, deberías sentirte cómodo con ellas.

  • Literales
    La forma más sencilla de expresión son los literales. Los literales son representaciones de objetos de Python, como cadenas y números. Existen los siguientes literales:

    • "Hello World"Todo lo que se encuentra entre dos comillas dobles o simples es una cadena. Son útiles cuando necesitas una cadena en la plantilla (por ejemplo, como argumentos de llamadas a funciones y filtros, o simplemente para ampliar o incluir una plantilla).

    • 42 / 123_456Los enteros son números completos sin parte decimal. El carácter «_» puede utilizarse para separar grupos y mejorar la legibilidad.

    • 42.23 / 42.1e2 / 123_456.789Los números de coma flotante pueden escribirse utilizando «.» como separador decimal. También pueden escribirse en notación científica, con una «e» mayúscula o minúscula para indicar el exponente. El carácter «_» puede utilizarse para separar grupos y mejorar la legibilidad, pero no puede utilizarse en el exponente.

    • ['list', 'of', 'objects']Todo lo que se encuentra entre dos corchetes es una lista. Las listas son útiles para almacenar datos secuenciales que se recorrerán.

    • ('tuple', 'of', 'values')Las tuplas son como listas que no pueden modificarse («inmutables»). Si una tupla solo tiene un elemento, debe ir seguida de una coma (('1-tuple',)). Las tuplas suelen utilizarse para representar elementos de dos o más componentes. Consulta el ejemplo de la lista anterior para obtener más detalles.

    • {'dict': 'of', 'key': 'and', 'value': 'pairs'}Un diccionario en Python es una estructura que combina claves y valores. Las claves deben ser únicas y siempre tienen exactamente un valor.

    • true / false true siempre es verdadero y false siempre es falso.

      Nota: Las constantes especiales true, false y none están efectivamente en minúsculas. Como esto causó confusión en el pasado (True se expandía a una variable no definida que se consideraba falsa), ahora las tres también pueden escribirse con mayúscula inicial (True, False y None). Sin embargo, por coherencia (todos los identificadores están en minúsculas), deberías utilizar las versiones en minúsculas.

  • Matemáticas
    Permite realizar cálculos con valores. Se admiten los siguientes operadores:

    • +Suma dos objetos. Normalmente, los objetos son números, pero si ambos son cadenas o listas, puedes concatenarlos de esta manera. Sin embargo, esta no es la forma preferida de concatenar cadenas. Para concatenar cadenas, consulta el operador ~.{{ 1 + 1 }} es 2.

    • -Resta el segundo número del primero. {{ 3 - 2 }} es 1.

    • /Divide dos números. El valor devuelto será un número de coma flotante. {{ 1 / 2 }} es {{ 0.5 }}.

    • //Divide dos números y devuelve el resultado entero truncado. {{ 20 // 7 }} es 2.

    • %Calcula el resto de una división entera. {{ 11 % 7 }} es 4.

    • *Multiplica el operando izquierdo por el derecho. {{ 2 * 2 }} devolvería 4. También puede utilizarse para repetir una cadena varias veces. {{ '=' * 80 }} imprimiría una barra de 80 signos de igualdad.

    • **Eleva el operando izquierdo a la potencia del operando derecho. {{ 2**3 }} devolvería 8. A diferencia de Python, las potencias encadenadas se evalúan de izquierda a derecha. {{ 3**3**3 }} se evalúa como (3**3)**3, pero en Python se evaluaría como 3**(3**3). Utiliza paréntesis para indicar explícitamente el orden deseado.

  • Comparaciones

    • ==Compara dos objetos para comprobar si son iguales.

    • !=Compara dos objetos para comprobar si son distintos.

    • > verdadero si el lado izquierdo es mayor que el derecho.

    • >= verdadero si el lado izquierdo es mayor o igual que el derecho.

    • < verdadero si el lado izquierdo es menor que el derecho.

    • <= verdadero si el lado izquierdo es menor o igual que el derecho.

  • Lógica

    • yDevuelve true si los operandos izquierdo y derecho son true.

    • oDevuelve true si el operando izquierdo o el derecho es true.

    • noNiega una expresión (consulta más abajo).

    • (expr)Los paréntesis agrupan una expresión.

      Nota: Los operadores es y in también admiten la negación mediante notación infija: foo is not bar y foo not in bar en lugar de not foo is bar y not foo in bar. Todas las demás expresiones requieren notación prefija: not (foo and bar).

  • Otros operadores
    Los siguientes operadores son muy útiles, pero no encajan en ninguna de las otras dos categorías:

    • inRealiza una prueba de pertenencia a una secuencia o asignación. Devuelve true si el operando izquierdo está contenido en el derecho. 1 in [1, 2, 3] devolvería true, por ejemplo.

    • esRealiza una prueba.

    • | (barra vertical) Aplica un filtro.

    • ~ (tilde) Convierte todos los operandos en cadenas y los concatena.
      "Hello " ~ name ~ "!" devolvería Hello John!(si name == ‘John’)

    • ()Llama a un objeto invocable: post.render(). Dentro de los paréntesis puedes utilizar argumentos posicionales y argumentos con nombre como en Python:
      post.render(user, full=true).

    • . / []Obtiene un atributo de un objeto. (Consulta Variables)

Filtros

Las variables pueden modificarse mediante filtros. Son una biblioteca de funciones auxiliares que realizan transformaciones por ti, para que no tengas que hacerlo manualmente. Los filtros se separan de la variable mediante el símbolo de barra vertical (|) y pueden tener argumentos opcionales entre paréntesis. Se pueden encadenar varios filtros. La salida de un filtro se aplica al siguiente.
Por ejemplo, name | trim | capitalize eliminará todos los espacios en blanco de name y lo pondrá en mayúscula inicial.
Los filtros que aceptan argumentos utilizan paréntesis alrededor de estos, igual que una llamada a una función. Por ejemplo: listx | join(', ')“ unirá una lista utilizando comas.
Puedes utilizar If en línea con filtros 'multiple' if array | count > 1 else 'one'
Muchos filtros de listas devuelven iteradores (para bucles) en lugar de listas; asegúrate de utilizar el filtro list.

Filtros integrados

  • Lista completa de filtros
    Filtros integrados de Jinja

  • Filtros utilizados con frecuencia
    5 filtros están destacados con la etiqueta [must know]. Estos son los filtros básicos que debes conocer y te ayudarán con la mayoría de las operaciones de manipulación de datos. Los demás también serán útiles, pero puedes consultarlos más adelante cuando los necesites.

    • default
      Valor predeterminado si la entrada no existe

      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
      Cambia el uso de mayúsculas y minúsculas de una cadena

      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]
      Hay dos usos principales:

      • Extraer atributos de objetos de una lista

      • Aplicar un filtro a todos los elementos de una lista

      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]
      Filtra una lista de objetos según sus atributos
      Acepta como argumento un atributo y una prueba (consulta la sección de pruebas)

      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]
      Acepta una prueba (consulta la sección de pruebas) como argumento

      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]
      Después de un map, select o una manipulación de datos más compleja, es habitual terminar con listas como esta: `[[1,2], [3,4]]`
      Utiliza flatten para fusionarlas en una sola lista

      Python
      [[1, 2], [3, 4]] | flatten
      => [1, 2, 3, 4]
    • list [must know]
      Convierte un valor en una lista. Lo utilizarás a menudo, ya que la mayoría de los filtros útiles devuelven iteradores en lugar de listas y debes convertirlos manualmente de nuevo en listas.

    • 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
      Da formato a una cadena (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

Filtros personalizados

Estos son filtros adicionales implementados por ViaSay.

Filtros de fecha

Los siguientes filtros permiten convertir cadenas que representan fechas o intervalos en objetos de Python datetime/timedelta.

  • to_date: Analiza una cadena en un objeto datetime; acepta tzname como parámetro.

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: Analiza una cadena timedelta en un objeto 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: Convierte una marca de tiempo Unix (entero en milisegundos) en un 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"

Advertencia: No puedes almacenar un datetime en una variable de salida del paso de manipulación de datos. Esto provocará un error de ejecución. Primero debes convertirlo en una cadena utilizando strftime como se muestra en los ejemplos anteriores.

Pruebas

Además de los filtros, también están disponibles los llamados «tests». Los tests se pueden usar para comprobar una variable con una expresión común. Para comprobar una variable o expresión, se añade es más el nombre del test después de la variable. Por ejemplo, para averiguar si una variable está definida, se puede hacer name is defined, lo que devolverá true o false dependiendo de si name está definida en el contexto de la plantilla actual.

Los tests también pueden aceptar argumentos. Si el test solo acepta un argumento, se pueden omitir los paréntesis.

Lista de tests integrados

Métodos nativos de Python

Puedes usar la mayoría de los métodos nativos de los objetos de Python.

Por ejemplo, puedes dividir una cadena o combinar diccionarios:

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

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

Estos son los métodos disponibles para los principales tipos de objetos:

  • Cadena

  • Diccionario

  • Lista

Uso avanzado

Descripción de todas las funciones proporcionadas por el motor de plantillas que puedes usar en el bloque de código. Esto te permitirá realizar manipulaciones más avanzadas con bucles, varios if, funciones, etc. (también llamada programación imperativa).

Usamos Jinja 3 para las plantillas. Si necesitas referencias o más detalles después de leer este documento, consulta su documentación oficial.

Está derivado de Python, por lo que verás muchas similitudes e incluso podrás usar algunos métodos de Python en ciertos objetos.

Delimitadores

Hay varios tipos de delimitadores. Los delimitadores predeterminados se configuran de la siguiente manera:

  • {% ... %} para sentencias (no imprime ningún valor)

  • {{ ... }} para expresiones (se imprimen en la salida de la plantilla)

  • {# ... #} para comentarios no incluidos en la salida de la plantilla

En el bloque de código puedes usar todos ellos, pero la salida se descartará de todos modos. Por lo tanto, querrás usar sentencias y comentarios.

En las salidas, los valores están envueltos en una expresión para mantener las cosas sencillas.

Asignaciones

Las asignaciones usan la etiqueta set y pueden tener varios destinos:

Python
{% **set** navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% **set** key, value = call_something() %}
  • Comportamiento del ámbito
    Ten en cuenta que no es posible establecer variables dentro de un bloque (excepto if, que no introduce un ámbito) y hacer que aparezcan fuera de él. Esto también se aplica a los bucles. Como resultado, la siguiente plantilla no hará lo que podrías esperar:

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

    No es posible hacer esto. En su lugar, usa construcciones alternativas como el bloque else del bucle o la variable especial loop:

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

    Los casos de uso más complejos se pueden gestionar mediante objetos namespace, que permiten propagar cambios entre ámbitos:

    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 }}

Lista de estructuras de control

  • If / elif / else
    La sentencia if es comparable a la sentencia if de Python. En su forma más sencilla, puedes usarla para comprobar si una variable está definida, no está vacía y no es falsa:

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

    Para varias ramas, elif y else se pueden usar como en Python. También puedes usar expresiones más complejas allí:expresiones también:

    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 también se puede usar como una expresión en línea:

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

    y para el filtrado de bucles:

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

    Itera sobre cada elemento de una secuencia. Por ejemplo:

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

    Como las variables de las plantillas conservan las propiedades de sus objetos (de Python), es posible iterar sobre contenedores como dict:

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

    Es posible que los diccionarios de Python no estén en el orden en que quieres mostrarlos. Si el orden importa, usa el | dictsort filtro.

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

    Dentro de un bloque for, puedes acceder a algunas variables especiales:

    Variables

    Descripción

    loop.index

    La iteración actual del bucle (indexada desde 1).

    loop.index0

    La iteración actual del bucle (indexada desde 0).

    loop.revindex

    El número de iteraciones desde el final del bucle (indexado desde 1).

    loop.revindex0

    El número de iteraciones desde el final del bucle (indexado desde 0).

    loop.first

    True si es la primera iteración.

    loop.last

    True si es la última iteración.

    loop.length

    El número de elementos de la secuencia.

    loop.cycle

    Una función auxiliar para alternar entre una lista de secuencias.

    loop.depth

    Indica la profundidad actual de la representación en un bucle recursivo. Empieza en 1.

    loop.depth0

    Indica la profundidad actual de la representación en un bucle recursivo. Empieza en 0.

    loop.previtem

    El elemento de la iteración anterior. No está definido durante la primera iteración.

    loop.nextitem

    El elemento de la iteración siguiente. No está definido durante la última iteración.

    loop.changed(*val)

    True si se llamó anteriormente con un valor diferente (o no se llamó en absoluto).

    Dentro de un bucle for, es posible alternar entre una lista de cadenas/variables cada vez que se recorre el bucle usando el auxiliar especial loop.cycle:

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

    A diferencia de Python, no es posible usar break o continue en un bucle. Sin embargo, puedes filtrar la secuencia durante la iteración, lo que permite omitir elementos. El siguiente ejemplo omite todos los usuarios ocultos:

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

    La ventaja es que la variable especial loop contará correctamente; por lo tanto, no contará los usuarios sobre los que no se haya iterado.

    Si no se realizó ninguna iteración porque la secuencia estaba vacía o el filtrado eliminó todos sus elementos, puedes mostrar un bloque predeterminado usando else:

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

    Ten en cuenta que, en Python, los bloques else se ejecutan siempre que el bucle correspondiente no haya hecho break. Como los bucles no pueden usar break de todos modos, se eligió un comportamiento ligeramente diferente para la palabra clave else.

    También es posible usar bucles de forma recursiva. Esto resulta útil si trabajas con datos recursivos, como mapas del sitio o RDFa. Para usar bucles recursivamente, básicamente debes añadir el modificador recursive a la definición del bucle y llamar a la variable loop con el nuevo iterable donde quieras realizar la recursión.

    El siguiente ejemplo implementa un mapa del sitio con bucles recursivos:

    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 siempre hace referencia al bucle más cercano (el más interno). Si tenemos más de un nivel de bucles, podemos reasignar la variable loop escribiendo {% set outer_loop = loop %} después del bucle que queremos usar recursivamente. Entonces podemos llamarlo usando {{ outer_loop(…) }}

    Ten en cuenta que las asignaciones realizadas en los bucles se borrarán al final de la iteración y no pueden sobrevivir al ámbito del bucle. Consulta Asignaciones, comportamiento del ámbito para obtener más información sobre cómo gestionar esto.

    Si lo único que quieres hacer es comprobar si algún valor ha cambiado desde la última iteración o cambiará en la siguiente, puedes usar previtem y 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 solo te interesa saber si el valor ha cambiado en algún momento, usar changed es aún más sencillo:

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

Lista de funciones globales

  • range
    Devuelve una lista que contiene una progresión aritmética de enteros. range(i, j) devuelve [i, i+1, i+2, ..., j-1]; el inicio (!) toma 0 de forma predeterminada. Cuando se proporciona step, especifica el incremento (o decremento). Por ejemplo, range(4) y range(0, 4, 1) devuelven [0, 1, 2, 3]. ¡El punto final se omite! Estos son exactamente los índices válidos para una lista de 4 elementos.
    Esto resulta útil para repetir varias veces un bloque de plantilla, por ejemplo, para rellenar una lista. Imagina que tienes 7 usuarios en la lista, pero quieres representar tres elementos vacíos para imponer una altura con 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
    Genera texto lorem ipsum para la plantilla. De forma predeterminada, se generan cinco párrafos de HTML, cada uno de entre 20 y 100 palabras. Si html es False, se devuelve texto normal. Esto resulta útil para generar contenido sencillo para probar el diseño.

  • dict
    Una alternativa práctica a los literales de diccionario. {'foo': 'bar'} es lo mismo que dict(foo='bar').

  • cycler
    Recorre los valores devolviéndolos uno a uno y vuelve a empezar cuando llega al final.
    Similar a loop.cycle, pero se puede usar fuera de los bucles o entre varios bucles. Por ejemplo, representa una lista de carpetas y archivos alternando las clases «odd» y «even».
    Cada argumento posicional se devolverá en el orden proporcionado en cada ciclo.

    • propiedades

      • current
        Devuelve el elemento actual. Equivale al elemento que se devolverá la próxima vez que se llame a [next()](https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-globals.cycler.next).

      • next()
        Devuelve el elemento actual y luego avanza [current](https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-globals.cycler.current) al elemento siguiente.

      • reset()
        Restablece el elemento actual al primero.

  • joiner
    Un pequeño auxiliar que se puede usar para «unir» varias secciones. A un joiner se le pasa una cadena y devolverá esa cadena cada vez que se lo llame, excepto la primera vez (en cuyo caso devuelve una cadena vacía). Puedes usarlo para unir elementos:

  • namespace
    Crea un contenedor nuevo que permite asignar atributos mediante la etiqueta {% set %} :

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

    El objetivo principal es permitir transportar un valor desde el cuerpo de un bucle hasta un ámbito externo. Se pueden proporcionar valores iniciales como un diccionario, como argumentos con nombre o ambos (el mismo comportamiento que el constructor 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 (funciones)

Las macros son comparables a las funciones de los lenguajes de programación habituales. Son útiles para convertir expresiones idiomáticas de uso frecuente en funciones reutilizables y no repetirse («DRY»).

Este es un pequeño ejemplo de una macro que representa un elemento de formulario:

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 puede entonces llamarse como una función en el espacio de nombres:

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'}
]

Dentro de las macros, tienes acceso a tres variables especiales:

  • varargs
    Si se pasan a la macro más argumentos posicionales de los que acepta, terminan en la variable especial varargs como una lista de valores.

  • kwargs
    Como varargs, pero para argumentos con nombre. Todos los argumentos con nombre no consumidos se almacenan en esta variable especial.

  • caller
    Si la macro se llamó desde una etiqueta call , el llamador se almacena en esta variable como una macro invocable.

Las macros también exponen algunos de sus detalles internos. Los siguientes atributos están disponibles en un objeto macro:

  • nombre
    El nombre de la macro. {{ input.name }} imprimirá input.

  • arguments
    Una tupla con los nombres de los argumentos que acepta la macro.

  • catch_kwargs
    Es true si la macro acepta argumentos con nombre adicionales (es decir, si accede a la variable especial kwargs).

  • catch_varargs
    Es true si la macro acepta argumentos posicionales adicionales (es decir, si accede a la variable especial varargs).

  • caller
    Es true si la macro accede a la variable especial caller y puede llamarse desde una etiqueta call .

Si el nombre de una macro comienza con un guion bajo, no se exporta y no se puede importar.

Call

En algunos casos, puede ser útil pasar una macro a otra macro. Para ello, puedes usar el bloque especial call.

También es posible pasar argumentos de vuelta al bloque call. Esto lo hace útil como sustituto de los bucles. En términos generales, un bloque call funciona exactamente como una macro sin nombre.

Was this article helpful?

On this page
  • Acceso a atributos
  • Asignaciones
  • Expresiones
  • Filtros
  • Filtros integrados
  • Filtros personalizados
  • Pruebas
  • Métodos nativos de Python
  • Delimitadores
  • Asignaciones
  • Lista de estructuras de control
  • Lista de funciones globales
  • Macros (funciones)
  • Call

Made from France 💙

Categories

  • ANALÍTICA
  • CONSTRUIR
  • LOUIS AI
  • INTEGRAR

🔗 Useful Links

  • Sign In
  • Website
  • Terms & Conditions

© 2026

MindsayPowered by Mindsay

Search the help center…

Search help center articles