2011-01-28 2 views
31

Можно ли импортировать модуль Python в шаблон Jinja, чтобы я мог использовать его функции?Импортировать модуль 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' 

... но мне было интересно, если есть другой способ для достижения этой цели.

ответ

42

Внутри шаблона нет, вы не можете импортировать код python.

Способ сделать это, чтобы зарегистрировать функцию как Jinja2 custom filter, как это:

В файле питона:

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

Just передать функцию в шаблон, например

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 

(вы также можете назвать его "import", передав аргумент dict)

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

затем в джинджа-шаблоне, вы можете импортировать любой модуль:

{% set time = imp0rt('time') %} 
{{ time.time() }} 
Смежные вопросы