Spec-Zone.ru › Django 6.0

Как реализовать собственный бэкенд шаблонов

Собственные бэкенды

Вот как реализовать собственный бэкенд шаблонов, чтобы использовать другую систему шаблонов. Бэкенд шаблонов — это класс, наследующий django.template.backends.base.BaseEngine. Он должен реализовать get_template() и может также реализовать from_string(). Вот пример для вымышленной библиотеки шаблонов 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)

Дополнительные сведения см. в документе DEP 182.

Интеграция отладки для собственных движков

Страница отладки Django содержит хуки для предоставления подробной информации при возникновении ошибки в шаблоне. Собственные движки шаблонов могут использовать эти хуки, чтобы дополнить сведения в трассировке стека, отображаемые пользователям. Доступны следующие хуки:

Анализ шаблона после сбоя

Анализ после сбоя отображается при возникновении исключения TemplateDoesNotExist. В нём перечислены движки шаблонов и загрузчики, использовавшиеся при поиске заданного шаблона. Например, если настроены два движка Django, анализ после сбоя будет выглядеть так:

../_images/postmortem.png

Собственные движки могут заполнить сведения для анализа после сбоя, передав аргументы backend и tried при возникновении исключения TemplateDoesNotExist. Бэкендам, использующим анализ после сбоя, следует указывать источник в объекте шаблона.

Контекстная информация о строке

Если ошибка возникает при разборе или рендеринге шаблона, Django может показать строку, в которой произошла ошибка. Например:

../_images/template-lines.png

Собственные движки могут заполнить эту информацию, задав атрибут template_debug для исключений, возникающих при разборе и рендеринге. Этот атрибут представляет собой dict со следующими значениями:

  • 'name': имя шаблона, в котором произошло исключение.
  • 'message': сообщение исключения.
  • 'source_lines': строки до строки, в которой произошло исключение, после неё и сама эта строка. Эта информация нужна для контекста, поэтому она не должна содержать более 20 строк.
  • 'line': номер строки, в которой произошло исключение.
  • 'before': содержимое строки с ошибкой до токена, вызвавшего ошибку.
  • 'during': токен, вызвавший ошибку.
  • 'after': содержимое строки с ошибкой после токена, вызвавшего ошибку.
  • 'total': количество строк в source_lines.
  • 'top': номер строки, в которой начинается source_lines.
  • 'bottom': номер строки, в которой заканчивается source_lines.

Для приведённой выше ошибки шаблона значение template_debug выглядело бы так:

{
    "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 источника и интеграция со сторонними библиотеками

В шаблонах Django объект Origin доступен через атрибут template.origin. Это позволяет отображать отладочную информацию в анализе шаблона после сбоя, а также в сторонних библиотеках, таких как Django Debug Toolbar.

Собственные движки могут предоставлять собственную информацию template.origin, создавая объект со следующими атрибутами:

  • 'name': полный путь к шаблону.
  • 'template_name': относительный путь к шаблону, передаваемый методам загрузки шаблонов.
  • 'loader_name': необязательная строка, указывающая функцию или класс, использованные для загрузки шаблона, например django.template.loaders.filesystem.Loader.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/howto/custom-template-backend/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API