如何实现自定义模板后台

定制后端

下面介绍如何实现自定义模板后端以使用其他模板系统。模板后端是继承 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

自定义引擎可以通过传递 backendtried 提出时的论点 TemplateDoesNotExist . 使用尸检的后端 should specify an origin 在模板对象上。

上下文行信息

如果在模板分析或呈现过程中发生错误,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 属性。这使调试信息能够显示在 template postmortem 以及第三方类库,如 Django Debug Toolbar .

自定义引擎可以提供自己的 template.origin 通过创建指定以下属性的对象获得的信息:

  • 'name' :模板的完整路径。

  • 'template_name' :传递到模板加载方法中的模板的相对路径。

  • 'loader_name' :标识用于加载模板的函数或类的可选字符串,例如 django.template.loaders.filesystem.Loader .