Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add a {% verbatim %} template tag. #51

Closed
wants to merge 1 commit into from

6 participants

Chris Beaven Alex Gaynor Alex Ogier Florian Apolloner Claude Paroz Ramiro Morales
Chris Beaven
Collaborator

Fixes #14502.

django/template/defaulttags.py
@@ -1273,6 +1280,21 @@ def url(parser, token):
return URLNode(viewname, args, kwargs, asvar)
@register.tag
+def verbatim(parser, token):
+ """
+ Output the content of this tag (usually template source) content of this
Ramiro Morales Collaborator
ramiro added a note

Docstring is a bit confusing.

Chris Beaven Collaborator

Thanks, I always end up half-writing my docstrings :P (fixed now)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Alex Gaynor
Collaborator

Is there a reason that this was done by modifying the core parser, rather than as a tag which reinterprets the tokens?

Alex Ogier

@alex Template tag tokens strip whitespace, so you need support all the way up to the tokenizer to do verbatim properly.

Chris Beaven
Collaborator

Yup, that's why.

Florian Apolloner
Owner

Fixed in 4464bbb

Claude Paroz
Collaborator

Committed in 4464bbb

Claude Paroz claudep closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 14, 2012
  1. Chris Beaven

    Add a {% verbatim %} template tag.

    SmileyChris authored
    Fixes #14502.
This page is out of date. Refresh to see the latest.
16 django/template/base.py
View
@@ -184,6 +184,7 @@ def __init__(self, template_string, origin):
self.template_string = template_string
self.origin = origin
self.lineno = 1
+ self.verbatim = False
def tokenize(self):
"""
@@ -203,15 +204,26 @@ def create_token(self, token_string, in_tag):
If in_tag is True, we are processing something that matched a tag,
otherwise it should be treated as a literal string.
"""
- if in_tag:
+ if in_tag and token_string.startswith(BLOCK_TAG_START):
# The [2:-2] ranges below strip off *_TAG_START and *_TAG_END.
# We could do len(BLOCK_TAG_START) to be more "correct", but we've
# hard-coded the 2s here for performance. And it's not like
# the TAG_START values are going to change anytime, anyway.
+ block_content = token_string[2:-2].strip()
+ if self.verbatim and block_content == self.verbatim:
+ self.verbatim = False
+ if in_tag and not self.verbatim:
if token_string.startswith(VARIABLE_TAG_START):
token = Token(TOKEN_VAR, token_string[2:-2].strip())
elif token_string.startswith(BLOCK_TAG_START):
- token = Token(TOKEN_BLOCK, token_string[2:-2].strip())
+ if block_content.startswith('verbatim'):
+ bits = block_content.split(' ', 1)
+ if bits[0] == 'verbatim':
+ if len(bits) > 1:
+ self.verbatim = bits[1]
+ else:
+ self.verbatim = 'endverbatim'
+ token = Token(TOKEN_BLOCK, block_content)
elif token_string.startswith(COMMENT_TAG_START):
content = ''
if token_string.find(TRANSLATOR_COMMENT_MARK):
35 django/template/defaulttags.py
View
@@ -6,7 +6,7 @@
from itertools import groupby, cycle as itertools_cycle
from django.conf import settings
-from django.template.base import (Node, NodeList, Template, Library,
+from django.template.base import (Node, NodeList, Template, Context, Library,
TemplateSyntaxError, VariableDoesNotExist, InvalidTemplateLibrary,
BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END,
SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END,
@@ -425,6 +425,13 @@ def render(self, context):
else:
return url
+class VerbatimNode(Node):
+ def __init__(self, content):
+ self.content = content
+
+ def render(self, context):
+ return self.content
+
class WidthRatioNode(Node):
def __init__(self, val_expr, max_expr, max_width):
self.val_expr = val_expr
@@ -1273,6 +1280,32 @@ def url(parser, token):
return URLNode(viewname, args, kwargs, asvar)
@register.tag
+def verbatim(parser, token):
+ """
+ Stops the template engine rendering the contents of this block tag.
+
+ Usage::
+
+ {% verbatim %}
+ {% don't process this %}
+ {% endverbatim %}
+
+ You can also specify an alternate closing tag::
+
+ {% verbatim -- %}
+ ...
+ {% -- %}
+ """
+ bits = token.contents.split(' ', 1)
+ if len(bits) > 1:
+ closing_tag = bits[1]
+ else:
+ closing_tag = 'endverbatim'
+ nodelist = parser.parse((closing_tag,))
+ parser.delete_first_token()
+ return VerbatimNode(nodelist.render(Context()))
+
+@register.tag
def widthratio(parser, token):
"""
For creating bar charts and such, this tag calculates the ratio of a given
23 docs/ref/templates/builtins.txt
View
@@ -1059,6 +1059,29 @@ This will follow the normal :ref:`namespaced URL resolution strategy
<topics-http-reversing-url-namespaces>`, including using any hints provided
by the context as to the current application.
+.. templatetag:: verbatim
+
+verbatim
+^^^^^^^^
+
+.. versionadded:: 1.5
+
+Stops the template engine rendering the contents of this block tag.
+
+A common use is to allow a Javascript template layer that collides with
+Django's syntax. For example::
+
+ {% verbatim %}
+ {{if dying}}Still alive.{{/if}}
+ {% endverbatim %}
+
+You can also specify an alternate closing tag::
+
+ {% verbatim finished %}
+ The verbatim tag looks like this:
+ {% verbatim %}{% endverbatim %}
+ {% finished %}
+
.. templatetag:: widthratio
widthratio
7 docs/releases/1.5.txt
View
@@ -44,6 +44,13 @@ reasons or when trying to avoid overwriting concurrent changes.
See the :meth:`Model.save() <django.db.models.Model.save()>` documentation for
more details.
+``{% verbatim %}`` template tag
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To make it easier to deal with javascript templates which collide with Django's
+syntax, you can now use the :ttag:`verbatim` block tag to avoid parsing the
+tag's content.
+
Minor features
~~~~~~~~~~~~~~
8 tests/regressiontests/templates/tests.py
View
@@ -1616,6 +1616,14 @@ def get_template_tests(self):
'static-prefixtag04': ('{% load static %}{% get_media_prefix as media_prefix %}{{ media_prefix }}', {}, settings.MEDIA_URL),
'static-statictag01': ('{% load static %}{% static "admin/base.css" %}', {}, urljoin(settings.STATIC_URL, 'admin/base.css')),
'static-statictag02': ('{% load static %}{% static base_css %}', {'base_css': 'admin/base.css'}, urljoin(settings.STATIC_URL, 'admin/base.css')),
+
+ # Verbatim template tag outputs contents without rendering.
+ 'verbatim-tag01': ('{% verbatim %}{{bare }}{% endverbatim %}', {}, '{{bare }}'),
+ 'verbatim-tag02': ('{% verbatim %}{% endif %}{% endverbatim %}', {}, '{% endif %}'),
+ 'verbatim-tag03': ("{% verbatim %}It's the {% verbatim %} tag{% endverbatim %}", {}, "It's the {% verbatim %} tag"),
+ 'verbatim-tag04': ('{% verbatim %}{% verbatim %}{% endverbatim %}{% endverbatim %}', {}, template.TemplateSyntaxError),
+ 'verbatim-tag05': ('{% verbatim %}{% endverbatim %}{% verbatim %}{% endverbatim %}', {}, ''),
+ 'verbatim-tag06': ("{% verbatim -- %}Don't {% endverbatim %} just yet{% -- %}", {}, "Don't {% endverbatim %} just yet"),
}
return tests
Something went wrong with that request. Please try again.