1
0
mirror of https://github.com/django/django.git synced 2025-01-03 06:55:47 +00:00

Fixed #34883 -- Allowed template tags to set extra data on templates.

By setting a value in the `parser.extra_data` mapping, template tags
pass additional data out of the parsing context.

Any extra data set is exposed on the template via the matching
`.extra_data` attribute.

Library authors should use a key to namespace extra data. The 'django'
namespace is reserved for internal use.
This commit is contained in:
Carlton Gibson 2023-09-29 19:02:19 +02:00 committed by Mariusz Felisiak
parent f4e72e6523
commit 35bbb2c9c0
4 changed files with 28 additions and 2 deletions

View File

@ -193,7 +193,9 @@ class Template:
)
try:
return parser.parse()
nodelist = parser.parse()
self.extra_data = parser.extra_data
return nodelist
except Exception as e:
if self.engine.debug:
e.template_debug = self.get_exception_info(e, e.token)
@ -439,6 +441,12 @@ class Parser:
self.filters = {}
self.command_stack = []
# Custom template tags may store additional data on the parser that
# will be made available on the template instance. Library authors
# should use a key to namespace any added data. The 'django' namespace
# is reserved for internal use.
self.extra_data = {}
if libraries is None:
libraries = {}
if builtins is None:

View File

@ -194,7 +194,9 @@ Signals
Templates
~~~~~~~~~
* ...
* Custom tags may now set extra data on the ``Parser`` object that will later
be made available on the ``Template`` instance. Such data may be used, for
example, by the template loader, or other template clients.
Tests
~~~~~

View File

@ -1,4 +1,5 @@
from django import template
from django.template.base import TextNode
from django.template.defaultfilters import stringfilter
from django.utils.html import escape, format_html
from django.utils.safestring import mark_safe
@ -216,3 +217,9 @@ class CounterNode(template.Node):
count = self.count
self.count = count + 1
return str(count)
@register.tag("extra_data")
def do_extra_data(parser, token):
parser.extra_data["extra_data"] = "CUSTOM_DATA"
return TextNode("")

View File

@ -140,6 +140,15 @@ class TemplateTestMixin:
if self.debug_engine:
self.assertEqual(e.exception.template_debug["during"], "{% badtag %}")
def test_compile_tag_extra_data(self):
"""Custom tags can pass extra data back to template."""
engine = self._engine(
app_dirs=True,
libraries={"custom": "template_tests.templatetags.custom"},
)
t = engine.from_string("{% load custom %}{% extra_data %}")
self.assertEqual(t.extra_data["extra_data"], "CUSTOM_DATA")
def test_render_tag_error_in_extended_block(self):
"""Errors in extended block are displayed correctly."""
e = self._engine(app_dirs=True)