last jinja for async africa python jinja2

python - for - jinja2 dump



Llamar a una función de pitón desde jinja2 (11)

Estoy usando jinja2, y quiero llamar a una función de python como ayudante, usando una sintaxis similar, como si estuviera llamando a una macro. jinja2 parece decidido a evitar que haga una llamada a función e insiste en que me repita copiando la función en una plantilla como una macro.

¿Hay alguna manera directa de hacer esto? Y, ¿hay alguna manera de importar un conjunto completo de funciones de python y tenerlas accesibles desde jinja2, sin pasar por un montón de rigamarole (como escribir una extensión)?


¿Hay alguna forma de importar un conjunto completo de funciones de Python y tenerlas accesibles desde jinja2?

Sí, hay, además de las otras respuestas anteriores, esto funciona para mí.

Crear una clase y llenarla con los métodos asociados, por ejemplo

class Test_jinja_object: def __init__(self): self.myvar = ''sample_var'' def clever_function (self): return ''hello''

Luego, cree una instancia de su clase en su función de vista y pase el objeto resultante a su plantilla como un parámetro para la función render_template

my_obj = Test_jinja_object()

Ahora en tu plantilla, puedes llamar a los métodos de clase en jinja como tal

{{ my_obj.clever_function () }}


Creo que jinja deliberadamente hace que sea difícil ejecutar python ''arbitrario'' dentro de una plantilla. Intenta forzar la opinión de que menos lógica en las plantillas es algo bueno.

Puede manipular el espacio de nombres global dentro de una instancia de Environment para agregar referencias a sus funciones. Debe hacerse antes de cargar cualquier plantilla. Por ejemplo:

from jinja2 import Environment, FileSystemLoader def clever_function(a, b): return u''''.join([b, a]) env = Environment(loader=FileSystemLoader(''/path/to/templates'')) env.globals[''clever_function''] = clever_function


Me gusta la respuesta de @ AJP . Lo usé textualmente hasta que terminé con muchas funciones. Luego cambié a un decorador de funciones de Python .

from jinja2 import Template template = '''''' Hi, my name is {{ custom_function1(first_name) }} My name is {{ custom_function2(first_name) }} My name is {{ custom_function3(first_name) }} '''''' jinga_html_template = Template(template) def template_function(func): jinga_html_template.globals[func.__name__] = func return func @template_function def custom_function1(a): return a.replace(''o'', ''ay'') @template_function def custom_function2(a): return a.replace(''o'', ''ill'') @template_function def custom_function3(a): return ''Slim Shady'' fields = {''first_name'': ''Jo''} print(jinga_html_template.render(**fields))

¡Las funciones buenas tienen un __name__ !


Nunca vi una forma tan simple en los documentos oficiales o en el desbordamiento de la pila, pero me sorprendió cuando encontré esto:

# jinja2.__version__ == 2.8 from jinja2 import Template def calcName(n, i): return '' ''.join([n] * i) template = Template("Hello {{ calcName(''Gandalf'', 2) }}") template.render(calcName=calcName) # or template.render({''calcName'': calcName})


Para importar todas las funciones integradas, puede usar:

app.jinja_env.globals.update(__builtins__)

Agregue .__dict__ después de __builtins__ si esto no funciona.

Basado en la respuesta de John32323 .


Para llamar a una función python desde Jinja2, puede usar filtros personalizados que funcionan de forma similar a los globales: http://jinja.pocoo.org/docs/dev/api/#writing-filters

Es bastante simple y útil. En un archivo myTemplate.txt, escribí:

{{ data|pythonFct }}

Y en una secuencia de comandos python:

import jinja2 def pythonFct(data): return "This is my data: {0}".format(data) input="my custom filter works!" loader = jinja2.FileSystemLoader(path or ''./'') env = jinja2.Environment(loader=loader) env.filters[''pythonFct''] = pythonFct result = env.get_template("myTemplate.txt").render(data=input) print(result)


Si lo está haciendo con Django, puede pasar la función con el contexto:

context = { ''title'':''My title'', ''str'': str, } ... return render(request, ''index.html'', context)

Ahora podrá usar la función str en la plantilla jinja2


Usa una lambda para conectar la plantilla a tu código principal

return render_template("clever_template", clever_function=lambda x: clever_function x)

Entonces puede llamar sin problemas a la función en la plantilla

{{clever_function(value)}}


Nota: ¡Esto es específico de Flask!

Sé que esta publicación es bastante antigua, pero hay mejores métodos para hacerlo en las versiones más nuevas de Flask utilizando procesadores de contexto.

Las variables se pueden crear fácilmente:

@app.context_processor def example(): return dict(myexample=''This is an example'')

Lo anterior se puede usar en una plantilla Jinja2 con Flask así:

{{ myexample }}

(Qué salidas This is an example )

Además de las funciones completas:

@app.context_processor def utility_processor(): def format_price(amount, currency=u''€''): return u''{0:.2f}{1}''.format(amount, currency) return dict(format_price=format_price)

Lo anterior cuando se usa así:

{{ format_price(0.33) }}

(Que genera el precio de entrada con el símbolo de moneda)

Alternativamente, puedes usar filtros jinja , horneados en Flask. Ej. Usando decoradores:

@app.template_filter(''reverse'') def reverse_filter(s): return s[::-1]

O bien, sin decoradores, y registrando manualmente la función:

def reverse_filter(s): return s[::-1] app.jinja_env.filters[''reverse''] = reverse_filter

Los filtros aplicados con los dos métodos anteriores se pueden usar así:

{% for x in mylist | reverse %} {% endfor %}


Para aquellos que usan Flask, pon esto en tu __init__.py :

def clever_function(): return u''HELLO'' app.jinja_env.globals.update(clever_function=clever_function)

y en su plantilla, {{ clever_function() }} con {{ clever_function() }}


from jinja2 import Template def custom_function(a): return a.replace(''o'', ''ay'') template = ''Hey, my name is {{ custom_function(first_name) }}'' jinga_html_template = Template(template) jinga_html_template.globals[''custom_function''] = custom_function fields = {''first_name'': ''Jo''} print jinga_html_template.render(**fields)

Se producirá:

Hey, my name is Jay

Funciona con Jinja2 versión 2.7.3