テンプレートのバックエンドをカスタマイズする¶
カスタムのバックエンド¶
ここでは、他のテンプレートシステムを使用するために、カスタムテンプレートバックエンドを実装する方法を説明します。テンプレートバックエンドは django.template.backends.base.BaseEngine
を継承したクラスです。このクラスは get_template()
と、オプションで from_string()
を実装する必要があります。以下は架空の foobar
テンプレートライブラリの例です:
from django.template import TemplateDoesNotExist, TemplateSyntaxError
from django.template.backends.base import BaseEngine
from django.template.backends.utils import csrf_input_lazy, csrf_token_lazy
import foobar
class FooBar(BaseEngine):
# Name of the subdirectory containing the templates for this engine
# inside an installed application.
app_dirname = "foobar"
def __init__(self, params):
params = params.copy()
options = params.pop("OPTIONS").copy()
super().__init__(params)
self.engine = foobar.Engine(**options)
def from_string(self, template_code):
try:
return Template(self.engine.from_string(template_code))
except foobar.TemplateCompilationFailed as exc:
raise TemplateSyntaxError(exc.args)
def get_template(self, template_name):
try:
return Template(self.engine.get_template(template_name))
except foobar.TemplateNotFound as exc:
raise TemplateDoesNotExist(exc.args, backend=self)
except foobar.TemplateCompilationFailed as exc:
raise TemplateSyntaxError(exc.args)
class Template:
def __init__(self, template):
self.template = template
def render(self, context=None, request=None):
if context is None:
context = {}
if request is not None:
context["request"] = request
context["csrf_input"] = csrf_input_lazy(request)
context["csrf_token"] = csrf_token_lazy(request)
return self.template.render(context)
詳しい情報は DEP 182 を参照してください。
カスタムエンジンに対するデバッグの統合¶
Django のデバッグページには、テンプレートエラーが発生したときに詳細な情報を提供するフックがあります。カスタムのテンプレートエンジンは、これらのフックを使うことで、ユーザに表示されるトレースバック情報を強化できます。以下のフックが利用できます:
テンプレートの postmortem (事後分析)¶
postmortemは TemplateDoesNotExist
が発生したときに表示されます。これは、指定されたテンプレートを見つけようとしたときに使われたテンプレートエンジンとローダの一覧を表示します。例えば、2つの Django エンジンが設定されている場合、 postmortem は以下のように表示されます:
カスタムエンジンは TemplateDoesNotExist
を発生させるときに backend
と tried
引数を渡すことで postmortem に値を入れることができます。postmortem を使用するバックエンドはテンプレートオブジェクトの origin を指定する 必要があります。
コンテキストの行情報¶
もしテンプレートをパースもしくはレンダリングしてる最中にエラーが発生したら、Djangoはエラーが発生した行を表示することができます。たとえば:
カスタムエンジンはパースやレンダリング中に発生した例外に template_debug
属性を指定することで、この情報を入力できます。この属性は以下の値を持つ dict
です:
'name'
: 例外が発生したテンプレートの名前。'message'
: 例外メッセージ。'source_lines'
: 例外が発生した行の前後の行。これは文脈のためのものなので、20行以上にすべきではありません。'line'
: 例外が発生した行番号。'before'
: エラーを発生させたトークンの前のエラー行の内容。'during'
: エラーを発生させたトークン。'after'
: エラーを発生させたトークンの後のエラー行の内容。'total'
:source_lines
の行数。'top'
:source_lines
が始まる行番号。'bottom'
:source_lines
が終了する行番号。
上記のテンプレートエラーが発生した場合、 template_debug
は次のようになります:
{
"name": "/path/to/template.html",
"message": "Invalid block tag: 'syntax'",
"source_lines": [
(1, "some\n"),
(2, "lines\n"),
(3, "before\n"),
(4, "Hello {% syntax error %} {{ world }}\n"),
(5, "some\n"),
(6, "lines\n"),
(7, "after\n"),
(8, ""),
],
"line": 4,
"before": "Hello ",
"during": "{% syntax error %}",
"after": " {{ world }}\n",
"total": 9,
"bottom": 9,
"top": 1,
}
Origin API と サードパーティとの統合¶
Django templates have an Origin
object available
through the template.origin
attribute. This enables debug information to be
displayed in the template postmortem, as well as
in 3rd-party libraries, like the Django Debug Toolbar.
カスタムエンジンは、以下の属性を指定するオブジェクトを作成することで、独自の template.origin
情報を提供できます:
'name'
: テンプレートへのフルパス。'template_name'
: テンプレート読み込みメソッドに渡される、テンプレートへの相対パス。'loader_name'
: テンプレートの読み込みに使われる関数またはクラスを識別するためのオプションの文字列。例:django.template.loaders.filesystem.Loader
。