Come implementare un backend per template personalizzato¶
Backend personalizzati¶
Ecco come implementare un backend di template custom per utilizzare un altro sistema di template. Un backend di template è una classe che eredita da django.template.backends.base.BaseEngine
. Deve implementare get_template()
ed opzionalmente from_string()
. Ecco un esempio di template library fittizia 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)
Vedi DEP 182 per maggiori informazioni.
Integrazione per il debug di engine custom¶
La pagina di debug di Django ha hook che forniscono informazioni dettagliate quando si verifica un template error. I motori di template personalizzati possono utilizzare questi hook per aumentare le informazioni di traceback visualizzate dagli utenti. Sono disponibili i seguenti hook:
Postmortem sul template¶
il postmortem appare quando viene sollevato TemplateDoesNotExist
. Fa una lista dei motori di template e dei loader che sono stati usati quando si cercava un determinato template. Per esempio, se sono configurati due motori Django, il postmortem apparrà così:
I motori personalizzati possono popolare il postmortem passando gli argomenti backend
e tried
quando sollevano TemplateDoesNotExist
.I backend che usano il postmortem dovrebbero specificare una origine sull’oggetto di template.
Informazione su linea contestuale¶
Se viene generato un errore durante il parsing o il rendering del template, Django è in grado di mostrare la riga in cui è presente l’errore. Ad esempio:
I motori personalizzati possono popolare questa informazione impostando un attributo template_debug
sulle eccezioni sollevate durante il parsing ed il rendering. Questo attributo è un dict
con i seguenti valori:
'name'
: Il nome del template in cui è avvenuta l’eccezione.'message'
: Il messaggio dell’eccezione'source_lines'
: Le righe prima, dopo e che includono la riga dove è avvenuta l’eccezione. Questo è per il contesto, quindi non dovrebbe contenere più di 20 righe o giù di lì.'line'
: Il numero di riga in cui è avvenuta l’eccezione.'before'
: Il contenuto della riga dell’errore prima del token che ha generato l’errore.'during'
: Il token che ha generato l’errore.'after'
: Il contenuto della riga dell’errore dopo il token che ha generato l’errore.'total'
: Il numero di righe insource_lines
.'top'
: Il numero di riga dove iniziasource_lines
.'bottom'
: Il numero di riga dove terminasource_lines
.
Dato il template di errore qui sopra, template_debug
sarà simile a:
{
"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 ed integrazione di terze parti¶
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.
I motori personalizzati possono fornire la propria informazione template.origin
creando un oggetto che specifica i seguenti attributi:
'name'
: il percorso completo verso il template.'template_name'
: il percorso relativo verso il template così come viene passato nei metodi di caricamento del template.'loader_name'
: una stringa opzionale che indentifica la funzione o la classe utilizzata per caricare il template, per es.django.template.loaders.filesystem.Loader
.