Implémentation d’un moteur de gabarits personnalisé¶
Moteurs personnalisés¶
Voici comment implémenter un moteur de gabarit personnalisé afin d’utiliser un autre système de gabarits. Un moteur de gabarit est une classe qui hérite de django.template.backends.base.BaseEngine
. Elle doit implémenter get_template()` et, facultativement, from_string()
. Voici un exemple d’une bibliothèque de gabarit fictive 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)
Voir DEP 182 pour plus d’informations.
Intégration du débogage pour les moteurs personnalisés¶
La page de débogage de Django présente des points d’entrée pour fournir des informations détaillées lorsqu’une erreur de gabarit se produit. Les moteurs de gabarit personnalisés peuvent utiliser ces points d’entrée pour améliorer les informations d’erreur qui sont présentées aux utilisateurs. Les points d’entrée suivants sont disponibles :
Gabarit postmortem¶
Le gabarit postmortem apparaît lorsque TemplateDoesNotExist
est générée. Il présente la liste des moteurs et chargeurs de gabarit utilisés lors de la recherche du gabarit concerné. Par exemple, si deux moteurs Django sont configurés, le gabarit postmortem ressemble à ceci :
Les moteurs personnalisés peuvent remplir le gabarit postmortem en passant les paramètres backend
et tried
lors de la génération de TemplateDoesNotExist
. Les moteurs qui utilisent le gabarit postmortem doivent indiquer une origine sur l’objet de gabarit.
Information de ligne contextuelle¶
Si une erreur se produit pendant l’analyse et le rendu d’un gabarit, Django peut afficher la ligne à laquelle s’est produite l’erreur. Par exemple :
Les moteurs personnalisés peuvent fournir cette information en définissant un attribut template_debug
sur les exceptions générées pendant l’analyse et le rendu. Cet attribut est un dict
possédant les valeurs suivantes :
'name'
: le nom du gabarit dans lequel l’exception s’est produite.'message'
: le message de l’exception.'source_lines'
: les lignes précédentes, suivantes ainsi que la ligne elle-même où s’est produite l’exception. C’est pour fournir du contexte, il ne faut donc pas inclure plus d’une vingtaine de lignes.'line'
: le numéro de ligne à laquelle s’est produite l’exception.'before'
: le contenu de la ligne ayant provoqué l’erreur, avant le symbole qui a produit l’erreur.'during'
: le symbole qui a généré l’erreur.'after'
: le contenu de la ligne ayant provoqué l’erreur, après le symbole qui a produit l’erreur.'total'
: le nombre de lignes danssource_lines
.'top'
: le numéro de ligne oùsource_lines
commence.'bottom'
: le numéro de ligne oùsource_lines
se termine.
Étant donné l’erreur de gabarit ci-dessus, template_debug
ressemblerait à ceci :
{
'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,
}
API d’origine et intégration tierce¶
Les gabarits Django possèdent un objet Origin
accessible par leur attribut template.origin
. Ceci permet aux informations de débogage d’apparaître dans le gabarit postmortem, de même que dans des bibliothèques tierces, telle que Django Debug Toolbar.
Les moteurs personnalisés peuvent fournir leurs propres informations template.origin
en créant un objet qui définit les attributs suivants :
'name'
: le chemin complet vers le gabarit.'template_name'
: le chemin relatif vers le gabarit tel que transmis aux méthodes de chargement de gabarits.'loader_name'
: une chaîne facultative identifiant la fonction ou la classe utilisée pour charger le gabarit, par exempledjango.template.loaders.filesystem.Loader
.