Импортировать модуль 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'
... но мне было интересно, есть ли другой способ достичь этого.
Ответы
Ответ 1
Внутри шаблона нет, вы не можете импортировать код python.
Способ сделать это - зарегистрировать функцию как jinja2 настраиваемый фильтр, например:
В вашем файле 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 %}
Ответ 2
Просто передайте функцию в шаблон, например
from dates.format import timesince
your_template.render(timesince)
и в шаблоне просто назовите его, как любую другую функцию,
{% macro time(mytime) %}
<a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}
Функции являются первоклассными гражданами на python, поэтому вы можете передавать их так же, как и все остальное. Вы даже можете пройти весь модуль, если хотите.
Ответ 3
Вы можете экспортировать все символы, доступные в модуле, предоставив модули __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 %}