mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Fixed #14502 -- Added a verbatim template tag.
Thanks SmileyChris for the patch.
This commit is contained in:
		| @@ -184,6 +184,7 @@ class Lexer(object): | |||||||
|         self.template_string = template_string |         self.template_string = template_string | ||||||
|         self.origin = origin |         self.origin = origin | ||||||
|         self.lineno = 1 |         self.lineno = 1 | ||||||
|  |         self.verbatim = False | ||||||
|  |  | ||||||
|     def tokenize(self): |     def tokenize(self): | ||||||
|         """ |         """ | ||||||
| @@ -203,15 +204,26 @@ class Lexer(object): | |||||||
|         If in_tag is True, we are processing something that matched a tag, |         If in_tag is True, we are processing something that matched a tag, | ||||||
|         otherwise it should be treated as a literal string. |         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. |             # 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 |             # 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 |             # hard-coded the 2s here for performance. And it's not like | ||||||
|             # the TAG_START values are going to change anytime, anyway. |             # 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): |             if token_string.startswith(VARIABLE_TAG_START): | ||||||
|                 token = Token(TOKEN_VAR, token_string[2:-2].strip()) |                 token = Token(TOKEN_VAR, token_string[2:-2].strip()) | ||||||
|             elif token_string.startswith(BLOCK_TAG_START): |             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): |             elif token_string.startswith(COMMENT_TAG_START): | ||||||
|                 content = '' |                 content = '' | ||||||
|                 if token_string.find(TRANSLATOR_COMMENT_MARK): |                 if token_string.find(TRANSLATOR_COMMENT_MARK): | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ from datetime import datetime | |||||||
| from itertools import groupby, cycle as itertools_cycle | from itertools import groupby, cycle as itertools_cycle | ||||||
|  |  | ||||||
| from django.conf import settings | 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, |     TemplateSyntaxError, VariableDoesNotExist, InvalidTemplateLibrary, | ||||||
|     BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, |     BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, | ||||||
|     SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END, |     SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END, | ||||||
| @@ -425,6 +425,13 @@ class URLNode(Node): | |||||||
|         else: |         else: | ||||||
|             return url |             return url | ||||||
|  |  | ||||||
|  | class VerbatimNode(Node): | ||||||
|  |     def __init__(self, content): | ||||||
|  |         self.content = content | ||||||
|  |  | ||||||
|  |     def render(self, context): | ||||||
|  |         return self.content | ||||||
|  |  | ||||||
| class WidthRatioNode(Node): | class WidthRatioNode(Node): | ||||||
|     def __init__(self, val_expr, max_expr, max_width): |     def __init__(self, val_expr, max_expr, max_width): | ||||||
|         self.val_expr = val_expr |         self.val_expr = val_expr | ||||||
| @@ -1272,6 +1279,32 @@ def url(parser, token): | |||||||
|  |  | ||||||
|     return URLNode(viewname, args, kwargs, asvar) |     return URLNode(viewname, args, kwargs, asvar) | ||||||
|  |  | ||||||
|  | @register.tag | ||||||
|  | def verbatim(parser, token): | ||||||
|  |     """ | ||||||
|  |     Stops the template engine from 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 | @register.tag | ||||||
| def widthratio(parser, token): | def widthratio(parser, token): | ||||||
|     """ |     """ | ||||||
|   | |||||||
| @@ -1040,6 +1040,29 @@ This will follow the normal :ref:`namespaced URL resolution strategy | |||||||
| <topics-http-reversing-url-namespaces>`, including using any hints provided | <topics-http-reversing-url-namespaces>`, including using any hints provided | ||||||
| by the context as to the current application. | by the context as to the current application. | ||||||
|  |  | ||||||
|  | .. templatetag:: verbatim | ||||||
|  |  | ||||||
|  | verbatim | ||||||
|  | ^^^^^^^^ | ||||||
|  |  | ||||||
|  | .. versionadded:: 1.5 | ||||||
|  |  | ||||||
|  | Stops the template engine from 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 | .. templatetag:: widthratio | ||||||
|  |  | ||||||
| widthratio | widthratio | ||||||
|   | |||||||
| @@ -62,6 +62,13 @@ For one-to-one relationships, both sides can be cached. For many-to-one | |||||||
| relationships, only the single side of the relationship can be cached. This | relationships, only the single side of the relationship can be cached. This | ||||||
| is particularly helpful in combination with ``prefetch_related``. | is particularly helpful in combination with ``prefetch_related``. | ||||||
|  |  | ||||||
|  | ``{% 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 | Minor features | ||||||
| ~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1616,6 +1616,14 @@ class Templates(unittest.TestCase): | |||||||
|             'static-prefixtag04': ('{% load static %}{% get_media_prefix as media_prefix %}{{ media_prefix }}', {}, settings.MEDIA_URL), |             '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-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')), |             '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 |         return tests | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user