Aqui está como implementar um backend de template personalizado para utilizar um sistema de template. Um backend de template precisa herdar de django.template.backends.base.BaseEngine
. Precisa implementar get_template()
e opcionalmente from_string()
. Aqui está um exemplo para a biblioteca de template fícticia 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)
Veja a DEP 182 para mais informações.
A página de debug do Django tem hooks para prover informações detalhadas quando um erro de template é levantado. Motores de template customizados podem utilizar estes hooks para melhoras as informações de traceback que aparecem aos usuários. Os seguintes hooks estão disponíveis:
O postmortem aparece quando TemplateDoesNotExist
é levantado. Ele lista os motores de template e loaders que foram utilizados ao tentar encontrar o template informado. Por exemplo, se dois motores Django estão configurados, o postmortem será parecido com:
Motores personalizados podem popular o postmortem por passar o backend
e os argumentos tried
ao levantar TemplateDoesNotExist
. Backends que utilizam o postmortem devem especificar uma origem 1 ao objeto template.
Se um erro acontece durante o tratamento ou renderização do template, o Django pode mostrar a linha em que o erro ocorreu. Por exemplo:
Motores personalizados podem popular esta informação por definir um atributo template_debug
nas exceções levantadas durante o tratamento e renderização. Esse atributo é um dict
com os seguintes valores:
'name'
: O nome do template onde a exceção ocorreu.
'message'
: A mensagem de exceção.
'source_lines'
: As linhas antes, depois, e incluindo a linha que exceção aconteceu. Isso é para contexto, por isso não teve mais do que cerca de 20 linhas.
'line'
: O número da linha em que a exceção aconteceu.
'before'
: O conteúdo na linha de erro anterior ao token que levantou o erro.
'during'
: O token que levantou o erro.
'after'
: O conteúdo da linha de erro posterior ao token que levantou o erro.
'total'
: O número de linhas em source_lines
.
'top'
: O número da linha onde source_lines
começa.
'bottom'
: O número da linha onde source_lines
termina.
Dado o seguinte erro de template, template_debug
se parecerá com:
{
"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.
Motores personalizados podem prover suas próprias informações de template.origin
por criar um objeto que especifique os seguintes atributos:
'name'
: O caminho completo do template.
'template_name'
: O caminho relativo do template como foi passado aos mecanismos de carregamento de template.
'loader_name'
: Uma string opcional identificando a função ou classe utilizada para carregar o template, por exemplo django.template.loaders.filesystem.Loader
.
abr. 23, 2025