从jinja2调用python函数

我正在使用jinja2,我想调用一个python函数作为助手,使用类似的语法,如果我正在调用一个macros。 jinja2似乎意图阻止我进行一个函数调用,并坚持我通过将函数复制到模板中作为一个macros来重复自己。

有没有简单的方法来做到这一点? 而且,还有什么办法可以导入一整套python函数,并且可以通过jinja2访问它们,而不需要经过大量的细节(如编写扩展名)?

对于那些使用Flask的人,把它放在你的__init__.py

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

并在你的模板中调用{{ clever_function() }}

注意:这是特定的瓶子!

我知道这个post是相当古老的,但有更好的方法在使用上下文处理器的更新版本的Flask中执行此操作。

variables可以很容易地创build:

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

以上可以在Flask中使用Jinja2模板,如下所示:

 {{ myexample }} 

(哪个输出This is an example

以及完整的function:

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

(输出货币符号的input价格)

或者,你可以使用忍者filter ,烧成烧瓶。 比如使用装饰器:

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

或者,没有装饰器,并手动注册function:

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

以上两种方法应用的filter可以这样使用:

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

我认为jinja故意让模板内运行“任意”python变得困难。 它试图强化模板中较less的逻辑是好事的观点。

您可以在一个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) 

然后,您可以无缝地调用模板中的function

 {{clever_function(value)}} 

从来没有在官方文档或堆栈溢出看到这样简单的方式,但是当我发现这一点时,我感到惊讶:

 # 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函数,你可以使用自定义filter,这些filter和全局variables一样: 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函数

有没有办法导入一整套python函数,并让他们从jinja2访问?

是的,除了上面的其他答案,这对我有用。

创build一个类并使用关联的方法填充它,例如

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

然后在你的视图函数中创build你的类的一个实例,并将结果对象作为render_template函数的parameter passing给你的模板

 my_obj = Test_jinja_object() 

现在在你的模板中,你可以像这样调用jinja中的类方法

 {{ my_obj.clever_function () }} 

我喜欢@ AJP的回答 。 我逐字地使用它,直到我结束了很多function。 然后我切换到一个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 def func_wrapper(*args, **kwargs): return func(*args, **kwargs) return func_wrapper @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__