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.
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:
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.
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 in source_lines
.'top'
: Il numero di riga dove inizia source_lines
.'bottom'
: Il numero di riga dove termina source_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,
}
I template Django hanno un oggetto Origin
disponibile attraverso l’attributo template.origin
. Questo abilita informazioni di debug da mostrare nel template postmortem, così come nelle librerie di terze parti, come 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
.mag 03, 2024