如何将自定义过滤器嵌入jinja2模板?
我正在写一些Jinja2模板,希望能在相关项目中尽量方便地重复使用。 我有一套自定义的便利过滤器,希望这些模板能“携带”它们。 有没有什么Jinja2的语法可以把过滤器的定义直接放到模板里? 或者有没有什么方法可以把纯Python函数嵌入到Jinja2模板中,这样它就能对传入模板的变量进行操作? 我以前用过mako,在那里做这个非常简单,但在mako中处理LaTeX模板很麻烦,因为缺少自定义语法,所以我不得不换用Jinja2。
2 个回答
20
在jinja2
模板中,有一种简单的方法可以添加自定义过滤器。FILTERS
是一个字典,里面包含了我们可以用来渲染模板的所有过滤器。不过,我们还可以往里面添加更多的过滤器。
下面是一个快速的例子,教你如何添加新的过滤器。
from jinja2 import Template
from jinja2.filters import FILTERS, environmentfilter
// Remove the decorator in the next line if using version 3.1.0 or higher, read below
@environmentfilter
def do_reverse_by_word(environment, value, attribute=None):
"""
custom max calculation logic
"""
if attribute:
return [list(reversed(i.get(attribute).split())) for i in value]
return list(reversed(value.split()))
FILTERS["reverse_by_word"] = do_reverse_by_word
print(Template("{{ name | reverse_by_word }}").render({"name": "Stack Overflow"}))
print(Template("{{ names | reverse_by_word(attribute='name') }}").render({"names": [{"name": "Stack Overflow"}, {"name": "Stack Exchange"}]}))
输出结果
['Overflow', 'Stack']
[['Overflow', 'Stack'], ['Exchange', 'Stack']]
如果你有更复杂的使用场景,请在下面留言。我会很高兴回答你的所有问题。
更新(经过3.1.2
版本测试):现在不再需要使用environmentfilter
这个装饰器(而且它已经不存在了)。来源
41
你不能直接把Python代码嵌入到Jinja2模板里。根据我所知道的,正确的方法是在你的应用程序中定义这些代码,然后把它们添加到你的Jinja2环境实例中。下面是一个例子,来自于https://jinja.palletsprojects.com/en/2.11.x/api/#writing-filters。
import jinja2
loader = jinja2.FileSystemLoader('/tmp')
env = jinja2.Environment(autoescape=True, loader=loader)
def upperstring(input):
"""Custom filter"""
return input.upper()
env.filters['upperstring'] = upperstring
temp = env.get_template('template.html')
temp.render(name="testing")
这是我使用的模板
{{ name | upperstring }}
结果是这样的
TESTING