是否可以将Python模块导入Jinja模板,以便我可以使用它的功能?
例如,我有一个 format.py 文件,其中包含格式化日期和时间的方法。在Jinja宏中,我可以做之类的以下内容吗?
{% from 'dates/format.py' import timesince %}
{% macro time(mytime) %}
<a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}
因为 format.py 不是模板,上面的代码会给我这个错误:
UndefinedError: the template 'dates/format.py' (imported on line 2 in 'dates/macros.html') does not export the requested name 'timesince'
......但我想知道是否有另一种方法来实现这一目标。
答案 0 :(得分:52)
在模板中,不,你不能导入python代码。
这样做的方法是将函数注册为jinja2 custom filter,如下所示:
在你的python文件中:
from dates.format import timesince
environment = jinja2.Environment(whatever)
environment.filters['timesince'] = timesince
# render template here
在你的模板中:
{% macro time(mytime) %}
<a title="{{ mytime }}">{{ mytime|timesince }}</a>
{% endmacro %}
答案 1 :(得分:21)
将函数传递给模板,就像这样
from dates.format import timesince
your_template.render(timesince)
并在模板中,只需像任何其他函数一样调用它,
{% macro time(mytime) %}
<a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}
函数是python中的一等公民,所以你可以像其他任何东西一样传递它们。如果你愿意,你甚至可以传入一个完整的模块。
答案 2 :(得分:6)
模板不知道import
,但您可以使用importlib
进行教学:
import importlib
my_template.render( imp0rt = importlib.import_module ) # can't use 'import', because it's reserved
(您也可以通过将参数传递给"import"
来命名为dict
kwargs = { 'import' : importlib.import_module }
my_template.render( **kwargs )
然后在jinja模板中,您可以导入任何模块:
{% set time = imp0rt( 'time' ) %}
{{ time.time() }}
答案 3 :(得分:2)
您可以通过将模块__dict__作为参数提供给jinja模板渲染方法来导出模块中的所有可用符号。以下内容将为模板提供__builtin__,inspect和types模块的函数和类型。
import __builtin__
import inspect
import types
env=RelEnvironment()
template = env.get_template(templatefile)
export_dict={}
export_dict.update(__builtin__.__dict__)
export_dict.update(types.__dict__)
export_dict.update(inspect.__dict__)
result=template.render(**export_dict)
在模板中,使用类似于以下内容的导出模块的功能:
{%- for element in getmembers(object) -%}
{# Use the getmembers function from inspect module on an object #}
{% endfor %}
答案 4 :(得分:1)
您可以像这样将模块传递给 render
函数:
from src.constants import proto
wls = {"workloads": [{"name": "test1", "p": "UDP"}, {"name": "test2", "p": "TCP_NONTLS"}]}
env = Environment(
loader=PackageLoader("src", "templates")
)
template = env.get_template("lds.yaml.j2")
print(template.render(wls,proto=proto))
在 jinja 模板中,您现在可以使用 proto
:
{% if workload.p == proto.udp -%}