Jinja2はテンプレート相対パスをサポートしていますか? %(here)s/other/template.html
、ファイルシステム内の現在のテンプレートの場所に関連する他のテンプレートを含めるには?
私はそうは思わない。通常、使用しているテンプレートローダーと環境のルートを基準にしてパスを指定することにより、他のテンプレートを含めたり拡張したりします。
したがって、テンプレートがすべて/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' %}
そしてジンジャはそれを見つける方法を理解するでしょう。
Will McCutchenの答えに追加するだけで、
ローダーには複数のディレクトリを含めることができます。次に、テンプレートが見つかるまで、各ディレクトリを(順番に)検索します。
たとえば、「/ contains/sidebar.html」ではなく「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"))
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)
この制限を克服する最もクリーンな方法は、次のことを可能にする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