Подтвердить что ты не робот

Импортировать модуль 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'

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

4b9b3361

Ответ 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 %}