我正在使用jinja2,我想调用一个python函数作为帮助器,使用类似的语法,就好像我调用一个宏 . jinja2似乎打算阻止我进行函数调用,并坚持通过将函数作为宏复制到模板中来重复自己 .
有没有直接的方法来做到这一点?并且,有没有办法导入一整套python函数并让它们可以从jinja2访问,而不需要经历大量的繁琐(例如编写扩展)?
对于使用Flask的人,请将其放在 __init__.py 中:
__init__.py
def clever_function(): return u'HELLO' app.jinja_env.globals.update(clever_function=clever_function)
并在您的模板中使用 {{ clever_function() }} 调用它
{{ clever_function() }}
Note: This is Flask specific!
我知道这篇文章很老了,但是在使用上下文处理器的Flask的新版本中有更好的方法 .
Variables can easily be created:
@app.context_processor def example(): return dict(myexample='This is an example')
以上可以在带有Flask的Jinja2模板中使用,如下所示:
{{ myexample }}
(哪个输出 This is an example )
This is an example
As well as full fledged functions:
@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)
以上使用时如下:
{{ format_price(0.33) }}
(使用货币符号输出输入价格)
Alternatively, you can use jinja filters, baked into Flask. E.g. using decorators:
@app.template_filter('reverse') def reverse_filter(s): return s[::-1]
或者,没有装饰器,并手动注册该功能:
def reverse_filter(s): return s[::-1] app.jinja_env.filters['reverse'] = reverse_filter
使用上述两种方法应用的过滤器可以像这样使用:
{% for x in mylist | reverse %} {% endfor %}
我认为jinja故意难以在模板中运行'任意'python . 它试图强化这样的观点,即模板中较少的逻辑是一件好事 .
您可以在 Environment 实例中操作全局命名空间以添加对函数的引用 . 必须在加载任何模板之前完成 . 例如:
Environment
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
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)
将输出:
Hey, my name is Jay
适用于Jinja2版本2.7.3
使用lambda将模板连接到主代码
return render_template("clever_template", clever_function=lambda x: clever_function x)
然后,您可以在模板中无缝调用该函数
{{clever_function(value)}}
我喜欢@AJP's answer . 我逐字地使用它,直到我结束了很多功能 . 然后我切换到Python function decorator .
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))
好东西有 __name__ !
__name__
从来没有在官方文档或堆栈溢出时看到这么简单的方式,但是当发现这个时我很惊讶:
# 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})
要从Jinja2调用python函数,您可以使用与globals类似的自定义过滤器:http://jinja.pocoo.org/docs/dev/api/#writing-filters
它非常简单实用 . 在myTemplate.txt文件中,我写道:
{{ data|pythonFct }}
并在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)
如果你正在使用Django,你可以通过上下文传递函数:
context = { 'title':'My title', 'str': str, } ... return render(request, 'index.html', context)
现在,您将能够在jinja2模板中使用 str 函数
str
有没有办法导入一整套python函数,并可以从jinja2访问它们?
是的,除了上面的其他答案,这对我有用 .
创建一个类并使用相关方法填充它,例如
class Test_jinja_object: def __init__(self): self.myvar = 'sample_var' def clever_function (self): return 'hello'
然后在视图函数中创建类的实例,并将结果对象作为render_template函数的参数传递给模板
my_obj = Test_jinja_object()
现在在您的模板中,您可以像这样调用jinja中的类方法
{{ my_obj.clever_function () }}
要导入所有内置函数,您可以使用:
app.jinja_env.globals.update(__builtins__)
如果这不起作用,请在 __builtins__ 之后添加 .__dict__ .
__builtins__
.__dict__
基于John32323's answer .
11 回答
对于使用Flask的人,请将其放在
__init__.py
中:并在您的模板中使用
{{ clever_function() }}
调用它Note: This is Flask specific!
我知道这篇文章很老了,但是在使用上下文处理器的Flask的新版本中有更好的方法 .
Variables can easily be created:
以上可以在带有Flask的Jinja2模板中使用,如下所示:
(哪个输出
This is an example
)As well as full fledged functions:
以上使用时如下:
(使用货币符号输出输入价格)
Alternatively, you can use jinja filters, baked into Flask. E.g. using decorators:
或者,没有装饰器,并手动注册该功能:
使用上述两种方法应用的过滤器可以像这样使用:
我认为jinja故意难以在模板中运行'任意'python . 它试图强化这样的观点,即模板中较少的逻辑是一件好事 .
您可以在
Environment
实例中操作全局命名空间以添加对函数的引用 . 必须在加载任何模板之前完成 . 例如:将输出:
适用于Jinja2版本2.7.3
使用lambda将模板连接到主代码
然后,您可以在模板中无缝调用该函数
我喜欢@AJP's answer . 我逐字地使用它,直到我结束了很多功能 . 然后我切换到Python function decorator .
好东西有
__name__
!从来没有在官方文档或堆栈溢出时看到这么简单的方式,但是当发现这个时我很惊讶:
要从Jinja2调用python函数,您可以使用与globals类似的自定义过滤器:http://jinja.pocoo.org/docs/dev/api/#writing-filters
它非常简单实用 . 在myTemplate.txt文件中,我写道:
并在python脚本中:
如果你正在使用Django,你可以通过上下文传递函数:
现在,您将能够在jinja2模板中使用
str
函数有没有办法导入一整套python函数,并可以从jinja2访问它们?
是的,除了上面的其他答案,这对我有用 .
创建一个类并使用相关方法填充它,例如
然后在视图函数中创建类的实例,并将结果对象作为render_template函数的参数传递给模板
现在在您的模板中,您可以像这样调用jinja中的类方法
要导入所有内置函数,您可以使用:
如果这不起作用,请在
__builtins__
之后添加.__dict__
.基于John32323's answer .