Here's how to implement a custom template backend in order to use another
template system. A template backend is a class that inherits
django.template.backends.base.BaseEngine
. It must implement
get_template()
and optionally from_string()
. Here's an example for a
fictional foobar
template library:
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 を参照してください。
The Django debug page has hooks to provide detailed information when a template error arises. Custom template engines can use these hooks to enhance the traceback information that appears to users. The following hooks are available:
テンプレートの死体解剖を行うのは、TemplateDoesNotExist
例外が発生した時です。例外には、使用されたテンプレートエンジンとテンプレートローダーのリストが含まれているので、与えられたテンプレートを見つけることができます。たとえば、2つの Django エンジンが設定されている場合、死体解剖の結果は次のように表示されます。
Custom engines can populate the postmortem by passing the backend
and
tried
arguments when raising TemplateDoesNotExist
.
Backends that use the postmortem should specify an origin on the template object.
もしテンプレートをパースもしくはレンダリングしてる最中にエラーが発生したら、Djangoはエラーが発生した行を表示することができます。たとえば:
Custom engines can populate this information by setting a template_debug
attribute on exceptions raised during parsing and rendering. This attribute is
a dict
with the following values:
'name'
: The name of the template in which the exception occurred.'message'
: The exception message.'source_lines'
: The lines before, after, and including the line the
exception occurred on. This is for context, so it shouldn't contain more than
20 lines or so.'line'
: The line number on which the exception occurred.'before'
: The content on the error line before the token that raised the
error.'during'
: The token that raised the error.'after'
: The content on the error line after the token that raised the
error.'total'
: The number of lines in source_lines
.'top'
: The line number where source_lines
starts.'bottom'
: The line number where source_lines
ends.Given the above template error, template_debug
would look like:
{
'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,
}
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.
Custom engines can provide their own template.origin
information by
creating an object that specifies the following attributes:
'name'
: テンプレートへのフルパス。'template_name'
: The relative path to the template as passed into the
template loading methods.'loader_name'
: テンプレートの読み込みに使われる関数またはクラスを識別するためのオプションの文字列。例: django.template.loaders.filesystem.Loader
。2022年6月01日