diff --git a/django/template/__init__.py b/django/template/__init__.py index 9b1868cfcef..dafa0696f74 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -226,30 +226,6 @@ class Lexer(object): token = Token(TOKEN_TEXT, token_string) return token -class DebugLexer(Lexer): - def __init__(self, template_string, origin): - super(DebugLexer, self).__init__(template_string, origin) - - def tokenize(self): - "Return a list of tokens from a given template_string" - result, upto = [], 0 - for match in tag_re.finditer(self.template_string): - start, end = match.span() - if start > upto: - result.append(self.create_token(self.template_string[upto:start], (upto, start), False)) - upto = start - result.append(self.create_token(self.template_string[start:end], (start, end), True)) - upto = end - last_bit = self.template_string[upto:] - if last_bit: - result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False)) - return result - - def create_token(self, token_string, source, in_tag): - token = super(DebugLexer, self).create_token(token_string, in_tag) - token.source = self.origin, source - return token - class Parser(object): def __init__(self, tokens): self.tokens = tokens @@ -360,52 +336,16 @@ class Parser(object): else: raise TemplateSyntaxError, "Invalid filter: '%s'" % filter_name -class DebugParser(Parser): - def __init__(self, lexer): - super(DebugParser, self).__init__(lexer) - self.command_stack = [] - - def enter_command(self, command, token): - self.command_stack.append( (command, token.source) ) - - def exit_command(self): - self.command_stack.pop() - - def error(self, token, msg): - return self.source_error(token.source, msg) - - def source_error(self, source,msg): - e = TemplateSyntaxError(msg) - e.source = source - return e - - def create_nodelist(self): - return DebugNodeList() - - def create_variable_node(self, contents): - return DebugVariableNode(contents) - - def extend_nodelist(self, nodelist, node, token): - node.source = token.source - super(DebugParser, self).extend_nodelist(nodelist, node, token) - - def unclosed_block_tag(self, parse_until): - command, source = self.command_stack.pop() - msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until)) - raise self.source_error( source, msg) - - def compile_function_error(self, token, e): - if not hasattr(e, 'source'): - e.source = token.source - def lexer_factory(*args, **kwargs): if settings.TEMPLATE_DEBUG: + from debug import DebugLexer return DebugLexer(*args, **kwargs) else: return Lexer(*args, **kwargs) def parser_factory(*args, **kwargs): if settings.TEMPLATE_DEBUG: + from debug import DebugParser return DebugParser(*args, **kwargs) else: return Parser(*args, **kwargs) @@ -816,22 +756,6 @@ class NodeList(list): def render_node(self, node, context): return node.render(context) -class DebugNodeList(NodeList): - def render_node(self, node, context): - try: - result = node.render(context) - except TemplateSyntaxError, e: - if not hasattr(e, 'source'): - e.source = node.source - raise - except Exception, e: - from sys import exc_info - wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e) - wrapped.source = node.source - wrapped.exc_info = exc_info() - raise wrapped - return result - class TextNode(Node): def __init__(self, s): self.s = s @@ -861,21 +785,6 @@ class VariableNode(Node): else: return force_unicode(output) -class DebugVariableNode(VariableNode): - def render(self, context): - try: - output = force_unicode(self.filter_expression.resolve(context)) - except TemplateSyntaxError, e: - if not hasattr(e, 'source'): - e.source = self.source - raise - except UnicodeDecodeError: - return '' - if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData): - return escape(output) - else: - return output - def generic_tag_compiler(params, defaults, name, node_class, parser, token): "Returns a template.Node subclass." bits = token.split_contents()[1:] diff --git a/django/template/debug.py b/django/template/debug.py new file mode 100644 index 00000000000..008059c28fb --- /dev/null +++ b/django/template/debug.py @@ -0,0 +1,97 @@ +from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError +from django.utils.encoding import force_unicode +from django.utils.html import escape +from django.utils.safestring import SafeData, EscapeData + +class DebugLexer(Lexer): + def __init__(self, template_string, origin): + super(DebugLexer, self).__init__(template_string, origin) + + def tokenize(self): + "Return a list of tokens from a given template_string" + result, upto = [], 0 + for match in tag_re.finditer(self.template_string): + start, end = match.span() + if start > upto: + result.append(self.create_token(self.template_string[upto:start], (upto, start), False)) + upto = start + result.append(self.create_token(self.template_string[start:end], (start, end), True)) + upto = end + last_bit = self.template_string[upto:] + if last_bit: + result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False)) + return result + + def create_token(self, token_string, source, in_tag): + token = super(DebugLexer, self).create_token(token_string, in_tag) + token.source = self.origin, source + return token + +class DebugParser(Parser): + def __init__(self, lexer): + super(DebugParser, self).__init__(lexer) + self.command_stack = [] + + def enter_command(self, command, token): + self.command_stack.append( (command, token.source) ) + + def exit_command(self): + self.command_stack.pop() + + def error(self, token, msg): + return self.source_error(token.source, msg) + + def source_error(self, source,msg): + e = TemplateSyntaxError(msg) + e.source = source + return e + + def create_nodelist(self): + return DebugNodeList() + + def create_variable_node(self, contents): + return DebugVariableNode(contents) + + def extend_nodelist(self, nodelist, node, token): + node.source = token.source + super(DebugParser, self).extend_nodelist(nodelist, node, token) + + def unclosed_block_tag(self, parse_until): + command, source = self.command_stack.pop() + msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until)) + raise self.source_error(source, msg) + + def compile_function_error(self, token, e): + if not hasattr(e, 'source'): + e.source = token.source + +class DebugNodeList(NodeList): + def render_node(self, node, context): + try: + result = node.render(context) + except TemplateSyntaxError, e: + if not hasattr(e, 'source'): + e.source = node.source + raise + except Exception, e: + from sys import exc_info + wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e) + wrapped.source = node.source + wrapped.exc_info = exc_info() + raise wrapped + return result + +class DebugVariableNode(VariableNode): + def render(self, context): + try: + output = force_unicode(self.filter_expression.resolve(context)) + except TemplateSyntaxError, e: + if not hasattr(e, 'source'): + e.source = self.source + raise + except UnicodeDecodeError: + return '' + if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData): + return escape(output) + else: + return output