2011-01-28 82 views
31

是否可以将一个Python模块导入Jinja模板,以便我可以使用它的功能?将Python模块导入Jinja模板?

例如,我有一个format.py文件,其中包含格式化日期和时间的方法。在金佳宏中,我可以做些什么以下?

{% 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' 

...但我不知道是否有另一种方式来实现这一目标。

回答

42

在模板中,不可以导入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 %} 
16

刚将功能传递到模板中,像这样

from dates.format import timesince 
your_template.render(timesince) 

和模板,只是把它像任何其他功能,

{% macro time(mytime) %} 
    <a title="{{ mytime }}">{{ timesince(mytime) }}</a> 
{% endmacro %} 

函数是一等公民在Python中,这样你就可以通过他们周围,就像其他任何东西。如果你愿意,你甚至可以传入一个完整的模块。

2

通过提供模块__dict__作为jinja模板渲染方法的参数,您可以导出模块中可用的所有符号。以下将提供__builtin__的可用函数和类型,检查和输入模块到模板中。

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 %} 
3

模板不知道import,但你可以用importlib教它:

import importlib 
my_template.render(imp0rt = importlib.import_module) # can't use 'import', because it's reserved 

(您也可以通过传递参数dict来将它命名为"import"

kwargs = { 'import' : importlib.import_module } 
my_template.render(**kwargs) 

然后在神社模板,你可以导入任何模块:

{% set time = imp0rt('time') %} 
{{ time.time() }}