diff options
| author | Preston Timmons <prestontimmons@gmail.com> | 2015-04-24 14:33:03 -0500 |
|---|---|---|
| committer | Preston Timmons <prestontimmons@gmail.com> | 2015-05-06 17:33:47 -0500 |
| commit | adff499e47d99f6b40307acc1ace95508e3c5910 (patch) | |
| tree | bda2771135ba07ad45b5df1fa0ee92588044bbac /docs | |
| parent | d1df1fd2bb274574fd895f6984892b3aba372f48 (diff) | |
Fixed #24119, #24120 -- Formalized debug integration for template backends.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/releases/1.9.txt | 3 | ||||
| -rw-r--r-- | docs/topics/_images/postmortem.png | bin | 0 -> 37075 bytes | |||
| -rw-r--r-- | docs/topics/_images/template-lines.png | bin | 0 -> 21537 bytes | |||
| -rw-r--r-- | docs/topics/templates.txt | 142 |
4 files changed, 140 insertions, 5 deletions
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index 513177fff2..99daac6a8f 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -249,6 +249,9 @@ Templates * The debug page template postmortem now include output from each engine that is installed. +* :ref:`Debug page integration <template-debug-integration>` for custom + template engines was added. + Requests and Responses ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/topics/_images/postmortem.png b/docs/topics/_images/postmortem.png Binary files differnew file mode 100644 index 0000000000..164125ed9d --- /dev/null +++ b/docs/topics/_images/postmortem.png diff --git a/docs/topics/_images/template-lines.png b/docs/topics/_images/template-lines.png Binary files differnew file mode 100644 index 0000000000..c4934049f1 --- /dev/null +++ b/docs/topics/_images/template-lines.png diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index d3b951a7ac..3810ea7483 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -152,11 +152,32 @@ The ``django.template.loader`` module defines two functions to load templates. If loading a template fails, the following two exceptions, defined in ``django.template``, may be raised: -.. exception:: TemplateDoesNotExist +.. exception:: TemplateDoesNotExist(msg, tried=None, backend=None, chain=None) - This exception is raised when a template cannot be found. + This exception is raised when a template cannot be found. It accepts the + following optional arguments for populating the :ref:`template postmortem + <template-postmortem>` on the debug page: -.. exception:: TemplateSyntaxError + ``backend`` + The template backend instance from which the exception originated. + + ``tried`` + A list of sources that were tried when finding the template. This is + formatted as a list of tuples containing ``(origin, status)``, where + ``origin`` is an :ref:`origin-like <template-origin-api>` object and + ``status`` is a string with the reason the template wasn't found. + + ``chain`` + A list of intermediate :exc:`~django.template.TemplateDoesNotExist` + exceptions raised when trying to load a template. This is used by + functions, such as :func:`~django.template.loader.get_template`, that + try to load a given template from multiple engines. + + .. versionadded:: 1.9 + + The ``backend``, ``tried``, and ``chain`` arguments were added. + +.. exception:: TemplateSyntaxError(msg) This exception is raised when a template was found but contains errors. @@ -478,7 +499,6 @@ fictional ``foobar`` template library:: self.engine = foobar.Engine(**options) - def from_string(self, template_code): try: return Template(self.engine.from_string(template_code)) @@ -489,7 +509,7 @@ fictional ``foobar`` template library:: try: return Template(self.engine.get_template(template_name)) except foobar.TemplateNotFound as exc: - raise TemplateDoesNotExist(exc.args) + raise TemplateDoesNotExist(exc.args, backend=self) except foobar.TemplateCompilationFailed as exc: raise TemplateSyntaxError(exc.args) @@ -510,6 +530,117 @@ fictional ``foobar`` template library:: See `DEP 182`_ for more information. +.. _template-debug-integration: + +Debug integration for custom engines +------------------------------------ + +.. versionadded:: 1.9 + + Debug page integration for non-Django template engines was added. + +The Django debug page has hooks to provide detailed information when a template +error arises. Custom template engines can use these hooks to enhance the +traceback information that appears to users. The following hooks are available: + +.. _template-postmortem: + +Template postmortem +~~~~~~~~~~~~~~~~~~~ + +The postmortem appears when :exc:`~django.template.TemplateDoesNotExist` is +raised. It lists the template engines and loaders that were used when trying +to find a given template. For example, if two Django engines are configured, +the postmortem will appear like: + +.. image:: _images/postmortem.png + +Custom engines can populate the postmortem by passing the ``backend`` and +``tried`` arguments when raising :exc:`~django.template.TemplateDoesNotExist`. +Backends that use the postmortem :ref:`should specify an origin +<template-origin-api>` on the template object. + +Contextual line information +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If an error happens during template parsing or rendering, Django can display +the line the error happened on. For example: + +.. image:: _images/template-lines.png + +Custom engines can populate this information by setting a ``template_debug`` +attribute on exceptions raised during parsing and rendering. This attribute +is a :class:`dict` with the following values: + +* ``'name'``: The name of the template in which the exception occurred. + +* ``'message'``: The exception message. + +* ``'source_lines'``: The lines before, after, and including the line the + exception occurred on. This is for context, so it shouldn't contain more than + 20 lines or so. + +* ``'line'``: The line number on which the exception occurred. + +* ``'before'``: The content on the error line before the token that raised the + error. + +* ``'during'``: The token that raised the error. + +* ``'after'``: The content on the error line after the token that raised the + error. + +* ``'total'``: The number of lines in ``source_lines``. + +* ``'top'``: The line number where ``source_lines`` starts. + +* ``'bottom'``: The line number where ``source_lines`` ends. + +Given the above template error, ``template_debug`` would look like:: + + { + '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, + } + +.. _template-origin-api: + +Origin API and 3rd-party integration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Django templates have an :class:`~django.template.base.Origin` object available +through the ``template.origin`` attribute. This enables debug information to be +displayed in the :ref:`template postmortem <template-postmortem>`, as well as +in 3rd-party libraries, like the `Django Debug Toolbar`_. + +Custom engines can provide their own ``template.origin`` information by +creating an object that specifies the following attributes: + +* ``'name'``: The full path to the template. + +* ``'template_name'``: The relative path to the template as passed into the + the template loading methods. + +* ``'loader_name'``: An optional string identifying the function or class used + to load the template, e.g. ``django.template.loaders.filesystem.Loader``. + .. currentmodule:: django.template .. _template-language-intro: @@ -687,3 +818,4 @@ Implementing a custom context processor is as simple as defining a function. .. _Jinja2: http://jinja.pocoo.org/ .. _DEP 182: https://github.com/django/deps/blob/master/accepted/0182-multiple-template-engines.rst +.. _Django Debug Toolbar: https://github.com/django-debug-toolbar/django-debug-toolbar |
