• 3.1
  • 5.0
  • 6.1
  • Версия документации: 3.2

Custom template backend

Пользовательские бэкэнды

Вот как реализовать пользовательский бэкенд шаблонов для использования другой системы шаблонов. Бэкенд шаблонов — это класс, который наследует 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 для исключений, возникающих во время анализа и рендеринга. Это атрибут типа:class: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,
}

Origin API и интеграция со сторонними продуктами

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.

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

  • 'name': Полный путь к шаблону.

  • 'template_name': Относительный путь к шаблону, переданный в методы загрузки шаблона.

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

Back to Top