what template odd even async templates variables scope jinja2

templates - odd - jinja2 template render



¿Puede el alcance de una variable Jinja extenderse más allá en un bloque interno? (6)

Al escribir una función de contextfunction() o algo similar, habrá notado que el contexto intenta evitar que lo modifique.

Si ha logrado modificar el contexto utilizando una API de contexto interno, puede haber notado que los cambios en el contexto no parecen estar visibles en la plantilla. La razón de esto es que Jinja usa el contexto solo como fuente de datos primaria para variables de plantilla por razones de rendimiento.

Si desea modificar el contexto, escriba una función que devuelva una variable que pueda asignarse a una variable utilizando set:

{% set comments = get_latest_comments() %}

Source

Tengo la siguiente plantilla de Jinja:

{% set mybool = False %} {% for thing in things %} <div class=''indent1''> <ul> {% if current_user %} {% if current_user.username == thing[''created_by''][''username''] %} {% set mybool = True %} <li>mybool: {{ mybool }}</li> <!-- prints True --> <li><a href=''#''>Edit</a></li> {% endif %} {% endif %} <li>Flag</li> </ul> </div> <hr /> {% endfor %} {% if not mybool %} <!-- always prints this --> <p>mybool is false!</p> {% else %} <p>mybool is true!</p> {% endif %}

Si la condición se cumple en el ciclo for , me gustaría cambiar mybool a true para que pueda mostrar mybool is true! abajo. Sin embargo, parece que el alcance del mybool interno está limitado a la instrucción if , por lo que nunca se establece el mybool deseado .

¿Cómo puedo configurar el mybool "global" para que pueda usarlo en la última instrucción if ?

EDITAR

He encontrado algunas sugerencias (solo las visitas a la página en caché correctamente), pero parece que no funcionan. Tal vez están en desuso en Jinja2 ...

EDITAR

Solución proporcionada a continuación. Todavía tengo curiosidad de por qué las sugerencias anteriores no funcionan. ¿Alguien sabe con certeza que estaban en desuso?


Puedes resolver tu problema usando este truco (sin extensiones):

import jinja2 env = jinja2.Environment() print env.from_string(""" {% set mybool = [False] %} {% for thing in things %} <div class=''indent1''> <ul> {% if current_user %} {% if current_user.username == thing[''created_by''][''username''] %} {% set _ = mybool.append(not mybool.pop()) %} <li>mybool: {{ mybool[0] }}</li> <!-- prints True --> <li><a href=''#''>Edit</a></li> {% endif %} {% endif %} <li>Flag</li> </ul> </div> <hr /> {% endfor %} {% if not mybool[0] %} <!-- always prints this --> <p>mybool is false!</p> {% else %} <p>mybool is true!</p> {% endif %} """).render(current_user={''username'':''me''},things=[{''created_by'':{''username'':''me''}},{''created_by'':{''username'':''you''}}])


Respuesta a una pregunta relacionada: quería tener un contador global del número de veces que ingresé a un cierto bloque de if en la plantilla, y terminé con el siguiente.

En la parte superior de la plantilla:

{% set counter = [''1''] %}

En el bloque if quiero contar:

{% if counter.append(''1'') %}{% endif %}

Al mostrar el conteo:

{{ counter|length }}

La cadena ''1'' puede reemplazarse con cualquier cadena o dígito, creo. Todavía es un truco, pero no muy grande.


Tuve la necesidad de encontrar el número máximo de entradas en un objeto (objeto) de una lista (objects_from_db),

Esto no funcionó por razones conocidas en jinja2 y alcance variable.

{% set maxlength = 0 %} {% for object in objects_from_db %} {% set ilen = object.entries | length %} {% if maxlength < ilen %} {% set maxlength = ilen %} {% endif %} {% endfor %}

Esto es lo que funciona:

{% set mlength = [0]%} {% for object in objects_from_db %} {% set ilen = object.entries | length %} {% if mlength[0] < ilen %} {% set _ = mlength.pop() %} {% set _ = mlength.append(ilen)%} {% endif %} {% endfor %} {% set maxlength = mlength[0] %}

Espero que esto ayude a alguien más a tratar de descubrir lo mismo.


Una forma de evitar esta limitación es habilitar la extensión de declaración de expresión "do" y usar una matriz en lugar de booleana:

{% set exists = [] %} {% for i in range(5) %} {% if True %} {% do exists.append(1) %} {% endif %} {% endfor %} {% if exists %} <!-- exists is true --> {% endif %}

Para habilitar la extensión de declaración de expresión "do" de Jinja: e = jinja2.Environment(extensions=["jinja2.ext.do",])


Actualización 2018

A partir de Jinja 2.10 (8 de noviembre de 2017), hay un objeto namespace() para resolver este problema en particular. Consulte la documentación oficial de Asignaciones para obtener más detalles y un ejemplo; la documentación de la class ilustra cómo asignar varios valores a un espacio de nombres.