在jinja2中调用python函数
我正在使用jinja2,想要像调用宏一样调用一个Python函数作为辅助工具。可是,jinja2似乎不太想让我直接调用函数,反而让我重复自己,把函数复制到模板里当作宏来用。
有没有什么简单的方法可以做到这一点?还有没有办法把一整套Python函数导入到jinja2中,让它们可以直接使用,而不需要经过很多复杂的步骤(比如写扩展)?
15 个回答
97
我觉得jinja故意让在模板中运行“任意”python代码变得困难。它想要传达一个观点,那就是模板中逻辑越少越好。
你可以在一个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
175
注意:这特指Flask!
我知道这篇文章有点旧了,但在Flask的新版本中,有更好的方法可以做到这一点,使用的是上下文处理器。
变量可以很容易地创建:
@app.context_processor
def example():
return dict(myexample='This is an example')
上面的内容可以在Flask的Jinja2模板中这样使用:
{{ myexample }}
(这会输出 这是一个例子
)
还可以创建完整的函数:
@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) }}
(这会输出带有货币符号的输入价格)
另外,你可以使用 jinja过滤器,这是Flask自带的。比如,使用装饰器:
@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 %}
269
对于使用Flask的人来说,把这个放在你的 __init__.py
文件里:
def clever_function():
return u'HELLO'
app.jinja_env.globals.update(clever_function=clever_function)
然后在你的模板中用 {{ clever_function() }}
来调用它。