Commits

Anonymous committed ae887bb

adds Literal argument type allowing for literal unparsed values that include template tags to be handled as strings.

  • Participants
  • Parent commits 4aae6d0

Comments (0)

Files changed (2)

File customtags/arguments.py

             container.tag_kwargs[str(self.name)] = nodelist
 
 
+class Literal(NodeList):
+
+    def get_default(self):
+        return StaticValue("")
+
+    def parse(self, parser, tokens, container, nextargs=None):
+        self.clean_token(parser, tokens)
+
+        literal = ''.join({
+            template.TOKEN_BLOCK: '{%% %s %%}',
+            template.TOKEN_VAR: '{{ %s }}',
+            template.TOKEN_COMMENT: '{# %s #}',
+            template.TOKEN_TEXT: '%s',
+        }[token.token_type] % token.contents for token in self._do_parse(parser))
+
+        if self.name is None:
+            container.tag_args.append(StaticValue(literal))
+        else:
+            container.tag_kwargs[str(self.name)] = StaticValue(literal)
+
+    def _do_parse(self, parser):
+        """
+        Parse to the end of a literal block. This is different than Parser.parse()
+        in that it does not generate Node objects; it simply yields tokens.
+        """
+        depth = 0
+        while parser.tokens:
+            token = parser.tokens[0]
+            if token.token_type == template.TOKEN_BLOCK:
+                if token.contents == self.name:
+                    depth += 1
+                elif token.contents in self.endtags or \
+                     token.contents == self.endtags:
+                    depth -= 1
+            if depth < 0:
+                break
+            yield parser.next_token()
+        if not parser.tokens and depth >= 0:
+            parser.unclosed_block_tag(self.endtags)
+
+
 class MultiArgument(BaseArgument):
     def __init__(self, name=None, *args, **kwargs):
         if len(args) == 1 and isinstance(args[0], (list, tuple)):

File customtags_tests/tests.py

         settings.INSTALLED_APPS = old_apps 
         settings.MIDDLEWARE_CLASSES = old_middleware 
 
+    def test_20_literal(self):
 
+        class CodeBlock(core.Tag):
+            options = core.Options(
+                arguments.Literal('literal'),
+                arguments.EndTag()
+            )
+
+            def render_tag(self, context, literal):
+                return literal
+
+        tpls = [
+            ('{% code_block %}{# comment #}{% endcode_block %}', '{# comment #}', {}),
+            ('{% code_block %}{{ variable }}{% endcode_block %}', '{{ variable }}', {}),
+            ('{% code_block %}{% tag %}{% endcode_block %}', '{% tag %}', {}),
+            ('{% code_block %}Text{% endcode_block %}', 'Text', {}),
+            ('{% code_block %}{# comment #}{{ var }}{% tag %}Text{% endcode_block %}', 
+             '{# comment #}{{ var }}{% tag %}Text', {}),
+        ]
+        self._tag_tester(CodeBlock, tpls)
+
+