Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

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
Owner

Fixes #14502.

django/template/defaulttags.py
... ...
@@ -1273,6 +1280,21 @@ def url(parser, token):
1273 1280
     return URLNode(viewname, args, kwargs, asvar)
1274 1281
 
1275 1282
 @register.tag
  1283
+def verbatim(parser, token):
  1284
+    """
  1285
+    Output the content of this tag (usually template source) content of this
2
Ramiro Morales Owner
ramiro added a note May 08, 2012

Docstring is a bit confusing.

Chris Beaven Owner
SmileyChris added a note May 08, 2012

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
Owner
alex commented May 08, 2012

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

Alex Ogier
ogier commented May 08, 2012

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

Chris Beaven
Owner

Yup, that's why.

Florian Apolloner
Owner

Fixed in 4464bbb

Claude Paroz
Owner

Committed in 4464bbb

Claude Paroz claudep closed this June 09, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

May 14, 2012
Chris Beaven Add a {% verbatim %} template tag.
Fixes #14502.
bc01a91
This page is out of date. Refresh to see the latest.
16  django/template/base.py
@@ -184,6 +184,7 @@ def __init__(self, template_string, origin):
184 184
         self.template_string = template_string
185 185
         self.origin = origin
186 186
         self.lineno = 1
  187
+        self.verbatim = False
187 188
 
188 189
     def tokenize(self):
189 190
         """
@@ -203,15 +204,26 @@ def create_token(self, token_string, in_tag):
203 204
         If in_tag is True, we are processing something that matched a tag,
204 205
         otherwise it should be treated as a literal string.
205 206
         """
206  
-        if in_tag:
  207
+        if in_tag and token_string.startswith(BLOCK_TAG_START):
207 208
             # The [2:-2] ranges below strip off *_TAG_START and *_TAG_END.
208 209
             # We could do len(BLOCK_TAG_START) to be more "correct", but we've
209 210
             # hard-coded the 2s here for performance. And it's not like
210 211
             # the TAG_START values are going to change anytime, anyway.
  212
+            block_content = token_string[2:-2].strip()
  213
+            if self.verbatim and block_content == self.verbatim:
  214
+                self.verbatim = False
  215
+        if in_tag and not self.verbatim:
211 216
             if token_string.startswith(VARIABLE_TAG_START):
212 217
                 token = Token(TOKEN_VAR, token_string[2:-2].strip())
213 218
             elif token_string.startswith(BLOCK_TAG_START):
214  
-                token = Token(TOKEN_BLOCK, token_string[2:-2].strip())
  219
+                if block_content.startswith('verbatim'):
  220
+                    bits = block_content.split(' ', 1)
  221
+                    if bits[0] == 'verbatim':
  222
+                        if len(bits) > 1:
  223
+                            self.verbatim = bits[1]
  224
+                        else:
  225
+                            self.verbatim = 'endverbatim'
  226
+                token = Token(TOKEN_BLOCK, block_content)
215 227
             elif token_string.startswith(COMMENT_TAG_START):
216 228
                 content = ''
217 229
                 if token_string.find(TRANSLATOR_COMMENT_MARK):
35  django/template/defaulttags.py
@@ -6,7 +6,7 @@
6 6
 from itertools import groupby, cycle as itertools_cycle
7 7
 
8 8
 from django.conf import settings
9  
-from django.template.base import (Node, NodeList, Template, Library,
  9
+from django.template.base import (Node, NodeList, Template, Context, Library,
10 10
     TemplateSyntaxError, VariableDoesNotExist, InvalidTemplateLibrary,
11 11
     BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END,
12 12
     SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END,
@@ -425,6 +425,13 @@ def render(self, context):
425 425
         else:
426 426
             return url
427 427
 
  428
+class VerbatimNode(Node):
  429
+    def __init__(self, content):
  430
+        self.content = content
  431
+
  432
+    def render(self, context):
  433
+        return self.content
  434
+
428 435
 class WidthRatioNode(Node):
429 436
     def __init__(self, val_expr, max_expr, max_width):
430 437
         self.val_expr = val_expr
@@ -1273,6 +1280,32 @@ def url(parser, token):
1273 1280
     return URLNode(viewname, args, kwargs, asvar)
1274 1281
 
1275 1282
 @register.tag
  1283
+def verbatim(parser, token):
  1284
+    """
  1285
+    Stops the template engine rendering the contents of this block tag.
  1286
+
  1287
+    Usage::
  1288
+
  1289
+        {% verbatim %}
  1290
+            {% don't process this %}
  1291
+        {% endverbatim %}
  1292
+
  1293
+    You can also specify an alternate closing tag::
  1294
+
  1295
+        {% verbatim -- %}
  1296
+            ...
  1297
+        {% -- %}
  1298
+    """
  1299
+    bits = token.contents.split(' ', 1)
  1300
+    if len(bits) > 1:
  1301
+        closing_tag = bits[1]
  1302
+    else:
  1303
+        closing_tag = 'endverbatim'
  1304
+    nodelist = parser.parse((closing_tag,))
  1305
+    parser.delete_first_token()
  1306
+    return VerbatimNode(nodelist.render(Context()))
  1307
+
  1308
+@register.tag
1276 1309
 def widthratio(parser, token):
1277 1310
     """
1278 1311
     For creating bar charts and such, this tag calculates the ratio of a given
23  docs/ref/templates/builtins.txt
@@ -1059,6 +1059,29 @@ This will follow the normal :ref:`namespaced URL resolution strategy
1059 1059
 <topics-http-reversing-url-namespaces>`, including using any hints provided
1060 1060
 by the context as to the current application.
1061 1061
 
  1062
+.. templatetag:: verbatim
  1063
+
  1064
+verbatim
  1065
+^^^^^^^^
  1066
+
  1067
+.. versionadded:: 1.5
  1068
+
  1069
+Stops the template engine rendering the contents of this block tag.
  1070
+
  1071
+A common use is to allow a Javascript template layer that collides with
  1072
+Django's syntax. For example::
  1073
+
  1074
+    {% verbatim %}
  1075
+        {{if dying}}Still alive.{{/if}}
  1076
+    {% endverbatim %}
  1077
+
  1078
+You can also specify an alternate closing tag::
  1079
+
  1080
+    {% verbatim finished %}
  1081
+        The verbatim tag looks like this:
  1082
+        {% verbatim %}{% endverbatim %}
  1083
+    {% finished %}
  1084
+
1062 1085
 .. templatetag:: widthratio
1063 1086
 
1064 1087
 widthratio
7  docs/releases/1.5.txt
@@ -44,6 +44,13 @@ reasons or when trying to avoid overwriting concurrent changes.
44 44
 See the :meth:`Model.save() <django.db.models.Model.save()>` documentation for
45 45
 more details.
46 46
 
  47
+``{% verbatim %}`` template tag
  48
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  49
+
  50
+To make it easier to deal with javascript templates which collide with Django's
  51
+syntax, you can now use the :ttag:`verbatim` block tag to avoid parsing the
  52
+tag's content.
  53
+
47 54
 Minor features
48 55
 ~~~~~~~~~~~~~~
49 56
 
8  tests/regressiontests/templates/tests.py
@@ -1616,6 +1616,14 @@ def get_template_tests(self):
1616 1616
             'static-prefixtag04': ('{% load static %}{% get_media_prefix as media_prefix %}{{ media_prefix }}', {}, settings.MEDIA_URL),
1617 1617
             'static-statictag01': ('{% load static %}{% static "admin/base.css" %}', {}, urljoin(settings.STATIC_URL, 'admin/base.css')),
1618 1618
             'static-statictag02': ('{% load static %}{% static base_css %}', {'base_css': 'admin/base.css'}, urljoin(settings.STATIC_URL, 'admin/base.css')),
  1619
+
  1620
+            # Verbatim template tag outputs contents without rendering.
  1621
+            'verbatim-tag01': ('{% verbatim %}{{bare   }}{% endverbatim %}', {}, '{{bare   }}'),
  1622
+            'verbatim-tag02': ('{% verbatim %}{% endif %}{% endverbatim %}', {}, '{% endif %}'),
  1623
+            'verbatim-tag03': ("{% verbatim %}It's the {% verbatim %} tag{% endverbatim %}", {}, "It's the {% verbatim %} tag"),
  1624
+            'verbatim-tag04': ('{% verbatim %}{% verbatim %}{% endverbatim %}{% endverbatim %}', {}, template.TemplateSyntaxError),
  1625
+            'verbatim-tag05': ('{% verbatim %}{% endverbatim %}{% verbatim %}{% endverbatim %}', {}, ''),
  1626
+            'verbatim-tag06': ("{% verbatim -- %}Don't {% endverbatim %} just yet{% -- %}", {}, "Don't {% endverbatim %} just yet"),
1619 1627
         }
1620 1628
         return tests
1621 1629
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.