# Documentazione Django 5.2.8

# 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 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,
    }

### 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`.