summaryrefslogtreecommitdiff
path: root/django/template/__init__.py
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2008-01-17 18:12:24 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2008-01-17 18:12:24 +0000
commitdaa467d79ec7b40e376294eabc51222a67690181 (patch)
treea91a72f3c10e95bf5c59a2599c0d370ddc8c78dc /django/template/__init__.py
parentc080e441f347ad252be5e2d4dc56e9f43fce88cc (diff)
newforms-admin: Merged from trunk up to [7021].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7022 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/template/__init__.py')
-rw-r--r--django/template/__init__.py171
1 files changed, 34 insertions, 137 deletions
diff --git a/django/template/__init__.py b/django/template/__init__.py
index 9b1868cfce..750c48988d 100644
--- a/django/template/__init__.py
+++ b/django/template/__init__.py
@@ -154,15 +154,12 @@ class StringOrigin(Origin):
class Template(object):
def __init__(self, template_string, origin=None, name='<Unknown Template>'):
- "Compilation stage"
try:
template_string = smart_unicode(template_string)
except UnicodeDecodeError:
raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.")
- if settings.TEMPLATE_DEBUG and origin == None:
+ if settings.TEMPLATE_DEBUG and origin is None:
origin = StringOrigin(template_string)
- # Could do some crazy stack-frame stuff to record where this string
- # came from...
self.nodelist = compile_string(template_string, origin)
self.name = name
@@ -177,13 +174,18 @@ class Template(object):
def compile_string(template_string, origin):
"Compiles template_string into NodeList ready for rendering"
- lexer = lexer_factory(template_string, origin)
- parser = parser_factory(lexer.tokenize())
+ if settings.TEMPLATE_DEBUG:
+ from debug import DebugLexer, DebugParser
+ lexer_class, parser_class = DebugLexer, DebugParser
+ else:
+ lexer_class, parser_class = Lexer, Parser
+ lexer = lexer_class(template_string, origin)
+ parser = parser_class(lexer.tokenize())
return parser.parse()
class Token(object):
def __init__(self, token_type, contents):
- "The token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT"
+ # token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT.
self.token_type, self.contents = token_type, contents
def __str__(self):
@@ -200,7 +202,7 @@ class Lexer(object):
self.origin = origin
def tokenize(self):
- "Return a list of tokens from a given template_string"
+ "Return a list of tokens from a given template_string."
in_tag = False
result = []
for bit in tag_re.split(self.template_string):
@@ -226,30 +228,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
@@ -319,17 +297,17 @@ class Parser(object):
def exit_command(self):
pass
- def error(self, token, msg ):
+ def error(self, token, msg):
return TemplateSyntaxError(msg)
def empty_variable(self, token):
- raise self.error( token, "Empty variable tag")
+ raise self.error(token, "Empty variable tag")
def empty_block_tag(self, token):
- raise self.error( token, "Empty block tag")
+ raise self.error(token, "Empty block tag")
def invalid_block_tag(self, token, command):
- raise self.error( token, "Invalid block tag: '%s'" % command)
+ raise self.error(token, "Invalid block tag: '%s'" % command)
def unclosed_block_tag(self, parse_until):
raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until))
@@ -358,57 +336,7 @@ class Parser(object):
if filter_name in self.filters:
return self.filters[filter_name]
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:
- return DebugLexer(*args, **kwargs)
- else:
- return Lexer(*args, **kwargs)
-
-def parser_factory(*args, **kwargs):
- if settings.TEMPLATE_DEBUG:
- return DebugParser(*args, **kwargs)
- else:
- return Parser(*args, **kwargs)
+ raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
class TokenParser(object):
"""
@@ -426,7 +354,7 @@ class TokenParser(object):
def top(self):
"Overload this method to do the actual parsing and return the result."
- raise NotImplemented
+ raise NotImplementedError()
def more(self):
"Returns True if there is more stuff in the tag."
@@ -435,7 +363,7 @@ class TokenParser(object):
def back(self):
"Undoes the last microparser. Use this for lookahead and backtracking."
if not len(self.backout):
- raise TemplateSyntaxError, "back called without some previous parsing"
+ raise TemplateSyntaxError("back called without some previous parsing")
self.pointer = self.backout.pop()
def tag(self):
@@ -443,7 +371,7 @@ class TokenParser(object):
subject = self.subject
i = self.pointer
if i >= len(subject):
- raise TemplateSyntaxError, "expected another tag, found end of string: %s" % subject
+ raise TemplateSyntaxError("expected another tag, found end of string: %s" % subject)
p = i
while i < len(subject) and subject[i] not in (' ', '\t'):
i += 1
@@ -459,14 +387,14 @@ class TokenParser(object):
subject = self.subject
i = self.pointer
if i >= len(subject):
- raise TemplateSyntaxError, "Searching for value. Expected another value but found end of string: %s" % subject
+ raise TemplateSyntaxError("Searching for value. Expected another value but found end of string: %s" % subject)
if subject[i] in ('"', "'"):
p = i
i += 1
while i < len(subject) and subject[i] != subject[p]:
i += 1
if i >= len(subject):
- raise TemplateSyntaxError, "Searching for value. Unexpected end of string in column %d: %s" % (i, subject)
+ raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
i += 1
res = subject[p:i]
while i < len(subject) and subject[i] in (' ', '\t'):
@@ -483,7 +411,7 @@ class TokenParser(object):
while i < len(subject) and subject[i] != c:
i += 1
if i >= len(subject):
- raise TemplateSyntaxError, "Searching for value. Unexpected end of string in column %d: %s" % (i, subject)
+ raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
i += 1
s = subject[p:i]
while i < len(subject) and subject[i] in (' ', '\t'):
@@ -542,8 +470,8 @@ class FilterExpression(object):
for match in matches:
start = match.start()
if upto != start:
- raise TemplateSyntaxError, "Could not parse some characters: %s|%s|%s" % \
- (token[:upto], token[upto:start], token[start:])
+ raise TemplateSyntaxError("Could not parse some characters: %s|%s|%s" % \
+ (token[:upto], token[upto:start], token[start:]))
if var == None:
var, constant, i18n_constant = match.group("var", "constant", "i18n_constant")
if i18n_constant:
@@ -552,9 +480,9 @@ class FilterExpression(object):
var = '"%s"' % constant.replace(r'\"', '"')
upto = match.end()
if var == None:
- raise TemplateSyntaxError, "Could not find variable at start of %s" % token
+ raise TemplateSyntaxError("Could not find variable at start of %s" % token)
elif var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or var[0] == '_':
- raise TemplateSyntaxError, "Variables and attributes may not begin with underscores: '%s'" % var
+ raise TemplateSyntaxError("Variables and attributes may not begin with underscores: '%s'" % var)
else:
filter_name = match.group("filter_name")
args = []
@@ -570,7 +498,7 @@ class FilterExpression(object):
filters.append( (filter_func,args))
upto = match.end()
if upto != len(token):
- raise TemplateSyntaxError, "Could not parse the remainder: '%s' from '%s'" % (token[upto:], token)
+ raise TemplateSyntaxError("Could not parse the remainder: '%s' from '%s'" % (token[upto:], token))
self.filters = filters
self.var = Variable(var)
@@ -627,7 +555,7 @@ class FilterExpression(object):
provided.pop(0)
except IndexError:
# Not enough
- raise TemplateSyntaxError, "%s requires %d arguments, %d provided" % (name, len(nondefs), plen)
+ raise TemplateSyntaxError("%s requires %d arguments, %d provided" % (name, len(nondefs), plen))
# Defaults can be overridden.
defaults = defaults and list(defaults) or []
@@ -636,7 +564,7 @@ class FilterExpression(object):
defaults.pop(0)
except IndexError:
# Too many.
- raise TemplateSyntaxError, "%s requires %d arguments, %d provided" % (name, len(nondefs), plen)
+ raise TemplateSyntaxError("%s requires %d arguments, %d provided" % (name, len(nondefs), plen))
return True
args_check = staticmethod(args_check)
@@ -816,22 +744,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 +773,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:]
@@ -887,7 +784,7 @@ def generic_tag_compiler(params, defaults, name, node_class, parser, token):
message = "%s takes %s arguments" % (name, bmin)
else:
message = "%s takes between %s and %s arguments" % (name, bmin, bmax)
- raise TemplateSyntaxError, message
+ raise TemplateSyntaxError(message)
return node_class(bits)
class Library(object):
@@ -913,7 +810,7 @@ class Library(object):
self.tags[name] = compile_function
return compile_function
else:
- raise InvalidTemplateLibrary, "Unsupported arguments to Library.tag: (%r, %r)", (name, compile_function)
+ raise InvalidTemplateLibrary("Unsupported arguments to Library.tag: (%r, %r)", (name, compile_function))
def tag_function(self,func):
self.tags[getattr(func, "_decorated_function", func).__name__] = func
@@ -937,7 +834,7 @@ class Library(object):
self.filters[name] = filter_func
return filter_func
else:
- raise InvalidTemplateLibrary, "Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func)
+ raise InvalidTemplateLibrary("Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func))
def filter_function(self, func):
self.filters[getattr(func, "_decorated_function", func).__name__] = func
@@ -966,7 +863,7 @@ class Library(object):
if params[0] == 'context':
params = params[1:]
else:
- raise TemplateSyntaxError, "Any tag function decorated with takes_context=True must have a first argument of 'context'"
+ raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'")
class InclusionNode(Node):
def __init__(self, vars_to_resolve):
@@ -1003,12 +900,12 @@ def get_library(module_name):
try:
mod = __import__(module_name, {}, {}, [''])
except ImportError, e:
- raise InvalidTemplateLibrary, "Could not load template library from %s, %s" % (module_name, e)
+ raise InvalidTemplateLibrary("Could not load template library from %s, %s" % (module_name, e))
try:
lib = mod.register
libraries[module_name] = lib
except AttributeError:
- raise InvalidTemplateLibrary, "Template library %s does not have a variable named 'register'" % module_name
+ raise InvalidTemplateLibrary("Template library %s does not have a variable named 'register'" % module_name)
return lib
def add_to_builtins(module_name):