~canonical-django/canonical-django/project-template

« back to all changes in this revision

Viewing changes to trunk/python-packages/django/template/debug.py

  • Committer: Matthew Nuzum
  • Date: 2008-11-13 05:46:03 UTC
  • Revision ID: matthew.nuzum@canonical.com-20081113054603-v0kvr6z6xyexvqt3
adding to version control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError
 
2
from django.utils.encoding import force_unicode
 
3
from django.utils.html import escape
 
4
from django.utils.safestring import SafeData, EscapeData
 
5
 
 
6
class DebugLexer(Lexer):
 
7
    def __init__(self, template_string, origin):
 
8
        super(DebugLexer, self).__init__(template_string, origin)
 
9
 
 
10
    def tokenize(self):
 
11
        "Return a list of tokens from a given template_string"
 
12
        result, upto = [], 0
 
13
        for match in tag_re.finditer(self.template_string):
 
14
            start, end = match.span()
 
15
            if start > upto:
 
16
                result.append(self.create_token(self.template_string[upto:start], (upto, start), False))
 
17
                upto = start
 
18
            result.append(self.create_token(self.template_string[start:end], (start, end), True))
 
19
            upto = end
 
20
        last_bit = self.template_string[upto:]
 
21
        if last_bit:
 
22
            result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False))
 
23
        return result
 
24
 
 
25
    def create_token(self, token_string, source, in_tag):
 
26
        token = super(DebugLexer, self).create_token(token_string, in_tag)
 
27
        token.source = self.origin, source
 
28
        return token
 
29
 
 
30
class DebugParser(Parser):
 
31
    def __init__(self, lexer):
 
32
        super(DebugParser, self).__init__(lexer)
 
33
        self.command_stack = []
 
34
 
 
35
    def enter_command(self, command, token):
 
36
        self.command_stack.append( (command, token.source) )
 
37
 
 
38
    def exit_command(self):
 
39
        self.command_stack.pop()
 
40
 
 
41
    def error(self, token, msg):
 
42
        return self.source_error(token.source, msg)
 
43
 
 
44
    def source_error(self, source,msg):
 
45
        e = TemplateSyntaxError(msg)
 
46
        e.source = source
 
47
        return e
 
48
 
 
49
    def create_nodelist(self):
 
50
        return DebugNodeList()
 
51
 
 
52
    def create_variable_node(self, contents):
 
53
        return DebugVariableNode(contents)
 
54
 
 
55
    def extend_nodelist(self, nodelist, node, token):
 
56
        node.source = token.source
 
57
        super(DebugParser, self).extend_nodelist(nodelist, node, token)
 
58
 
 
59
    def unclosed_block_tag(self, parse_until):
 
60
        command, source = self.command_stack.pop()
 
61
        msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
 
62
        raise self.source_error(source, msg)
 
63
 
 
64
    def compile_function_error(self, token, e):
 
65
        if not hasattr(e, 'source'):
 
66
            e.source = token.source
 
67
 
 
68
class DebugNodeList(NodeList):
 
69
    def render_node(self, node, context):
 
70
        try:
 
71
            result = node.render(context)
 
72
        except TemplateSyntaxError, e:
 
73
            if not hasattr(e, 'source'):
 
74
                e.source = node.source
 
75
            raise
 
76
        except Exception, e:
 
77
            from sys import exc_info
 
78
            wrapped = TemplateSyntaxError(u'Caught an exception while rendering: %s' % force_unicode(e, errors='replace'))
 
79
            wrapped.source = node.source
 
80
            wrapped.exc_info = exc_info()
 
81
            raise wrapped
 
82
        return result
 
83
 
 
84
class DebugVariableNode(VariableNode):
 
85
    def render(self, context):
 
86
        try:
 
87
            output = force_unicode(self.filter_expression.resolve(context))
 
88
        except TemplateSyntaxError, e:
 
89
            if not hasattr(e, 'source'):
 
90
                e.source = self.source
 
91
            raise
 
92
        except UnicodeDecodeError:
 
93
            return ''
 
94
        if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData):
 
95
            return escape(output)
 
96
        else:
 
97
            return output