Поддерживает ли Jinja2 относительные пути шаблонов, например. %(here)s/other/template.html
, чтобы включить другие шаблоны относительно текущего места шаблона в файловой системе?
Есть ли у языка программирования Jinja2 понятие "здесь" (текущий каталог)?
Ответ 1
Я так не верю. Обычно вы включаете или расширяете другие шаблоны, указав их пути относительно корня любого загрузчика шаблонов и среды, которую вы используете.
Итак, пусть ваши шаблоны находятся в /path/to/templates
, и вы настроили Jinja так:
import jinja2
template_dir = '/path/to/templates'
loader = jinja2.FileSystemLoader(template_dir)
environment = jinja2.Environment(loader=loader)
Теперь, если вы хотите включить /path/to/templates/includes/sidebar.html
в шаблон /path/to/templates/index.html
, вы должны записать следующее в index.html
:
{% include 'includes/sidebar.html' %}
и Jinja выяснит, как его найти.
Ответ 2
Просто добавьте к Уилу Маккатчену ответ,
В вашем загрузчике может быть несколько каталогов. Затем он ищет в каждой из каталогов (по порядку), пока не найдет шаблон.
например, если вы хотите иметь "sidebar.html" вместо "/includes/sidebar.html", то есть:
loader=jinja2.FileSystemLoader(
[os.path.join(os.path.dirname(__file__),"templates/includes"),
os.path.join(os.path.dirname(__file__),"templates")])
вместо
loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__),"templates"))
Ответ 3
В соответствии с документацией для jinja2.Environment.join_path() поддержка относительных путей шаблонов возможна путем переопределения join_path() для реализации "соединение шаблона".
class RelEnvironment(jinja2.Environment):
"""Override join_path() to enable relative template paths."""
def join_path(self, template, parent):
return os.path.join(os.path.dirname(parent), template)
Ответ 4
Самый чистый способ преодоления этого ограничения будет связан с расширением jinja2, которое позволит импортировать относительные имена шаблонов
Что-то вроде:
from jinja2.ext import Extension
import re
class RelativeInclude(Extension):
"""Allows to import relative template names"""
tags = set(['include2'])
def __init__(self, environment):
super(RelativeInclude, self).__init__(environment)
self.matcher = re.compile("\.*")
def parse(self, parser):
node = parser.parse_include()
template = node.template.as_const()
if template.startswith("."):
# determine the number of go ups
up = len(self.matcher.match(template).group())
# split the current template name into path elements
# take elements minus the number of go ups
seq = parser.name.split("/")[:-up]
# extend elements with the relative path elements
seq.extend(template.split("/")[1:])
template = "/".join(seq)
node.template.value = template
return node