mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
new-admin: Negligible syntax changes in django.core.template in preparation for merge to trunk
git-svn-id: http://code.djangoproject.com/svn/django/branches/new-admin@1372 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
855d9909c6
commit
c18d99735e
@ -74,7 +74,8 @@ VARIABLE_TAG_END = '}}'
|
|||||||
|
|
||||||
ALLOWED_VARIABLE_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.'
|
ALLOWED_VARIABLE_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.'
|
||||||
|
|
||||||
#What to report as the origin of templates that come from non loader sources (ie strings)
|
# what to report as the origin for templates that come from non-loader sources
|
||||||
|
# (e.g. strings)
|
||||||
UNKNOWN_SOURCE="<unknown source>"
|
UNKNOWN_SOURCE="<unknown source>"
|
||||||
|
|
||||||
# match a variable or block tag and capture the entire tag, including start/end delimiters
|
# match a variable or block tag and capture the entire tag, including start/end delimiters
|
||||||
@ -107,7 +108,7 @@ class SilentVariableFailure(Exception):
|
|||||||
class Origin(object):
|
class Origin(object):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
raise NotImplementedException
|
raise NotImplementedException
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ class StringOrigin(Origin):
|
|||||||
def __init__(self, source):
|
def __init__(self, source):
|
||||||
super(StringOrigin, self).__init__(UNKNOWN_SOURCE)
|
super(StringOrigin, self).__init__(UNKNOWN_SOURCE)
|
||||||
self.source = source
|
self.source = source
|
||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
return self.source
|
return self.source
|
||||||
|
|
||||||
@ -127,9 +128,10 @@ class Template:
|
|||||||
"Compilation stage"
|
"Compilation stage"
|
||||||
if TEMPLATE_DEBUG and origin == None:
|
if TEMPLATE_DEBUG and origin == None:
|
||||||
origin = StringOrigin(template_string)
|
origin = StringOrigin(template_string)
|
||||||
#Could do some crazy stack frame stuff to record where this string came from...
|
# Could do some crazy stack-frame stuff to record where this string
|
||||||
|
# came from...
|
||||||
self.nodelist = compile_string(template_string, origin)
|
self.nodelist = compile_string(template_string, origin)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for node in self.nodelist:
|
for node in self.nodelist:
|
||||||
for subnode in node:
|
for subnode in node:
|
||||||
@ -140,7 +142,7 @@ class Template:
|
|||||||
return self.nodelist.render(context)
|
return self.nodelist.render(context)
|
||||||
|
|
||||||
def compile_string(template_string, origin):
|
def compile_string(template_string, origin):
|
||||||
"Compiles template_string into NodeList ready for rendering"
|
"Compiles template_string into NodeList ready for rendering"
|
||||||
lexer = lexer_factory(template_string, origin)
|
lexer = lexer_factory(template_string, origin)
|
||||||
parser = parser_factory(lexer.tokenize())
|
parser = parser_factory(lexer.tokenize())
|
||||||
return parser.parse()
|
return parser.parse()
|
||||||
@ -186,7 +188,7 @@ class Context:
|
|||||||
if dict.has_key(key):
|
if dict.has_key(key):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get(self, key, otherwise):
|
def get(self, key, otherwise):
|
||||||
for dict in self.dicts:
|
for dict in self.dicts:
|
||||||
if dict.has_key(key):
|
if dict.has_key(key):
|
||||||
@ -204,13 +206,13 @@ class Token:
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '<%s token: "%s...">' % (
|
return '<%s token: "%s...">' % (
|
||||||
{TOKEN_TEXT:'Text', TOKEN_VAR:'Var', TOKEN_BLOCK:'Block'}[self.token_type],
|
{TOKEN_TEXT: 'Text', TOKEN_VAR: 'Var', TOKEN_BLOCK: 'Block'}[self.token_type],
|
||||||
self.contents[:20].replace('\n', '')
|
self.contents[:20].replace('\n', '')
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s token: "%s">' % (
|
return '<%s token: "%s">' % (
|
||||||
{TOKEN_TEXT:'Text', TOKEN_VAR:'Var', TOKEN_BLOCK:'Block'}[self.token_type],
|
{TOKEN_TEXT: 'Text', TOKEN_VAR: 'Var', TOKEN_BLOCK: 'Block'}[self.token_type],
|
||||||
self.contents[:].replace('\n', '')
|
self.contents[:].replace('\n', '')
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -218,13 +220,13 @@ class Lexer(object):
|
|||||||
def __init__(self, template_string, origin):
|
def __init__(self, template_string, origin):
|
||||||
self.template_string = template_string
|
self.template_string = template_string
|
||||||
self.origin = origin
|
self.origin = origin
|
||||||
|
|
||||||
def tokenize(self):
|
def tokenize(self):
|
||||||
"Return a list of tokens from a given template_string"
|
"Return a list of tokens from a given template_string"
|
||||||
# remove all empty strings, because the regex has a tendency to add them
|
# remove all empty strings, because the regex has a tendency to add them
|
||||||
bits = filter(None, tag_re.split(self.template_string))
|
bits = filter(None, tag_re.split(self.template_string))
|
||||||
return map(self.create_token, bits)
|
return map(self.create_token, bits)
|
||||||
|
|
||||||
def create_token(self,token_string):
|
def create_token(self,token_string):
|
||||||
"Convert the given token string into a new Token object and return it"
|
"Convert the given token string into a new Token object and return it"
|
||||||
if token_string.startswith(VARIABLE_TAG_START):
|
if token_string.startswith(VARIABLE_TAG_START):
|
||||||
@ -233,26 +235,26 @@ class Lexer(object):
|
|||||||
token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip())
|
token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip())
|
||||||
else:
|
else:
|
||||||
token = Token(TOKEN_TEXT, token_string)
|
token = Token(TOKEN_TEXT, token_string)
|
||||||
return token
|
return token
|
||||||
|
|
||||||
class DebugLexer(Lexer):
|
class DebugLexer(Lexer):
|
||||||
def __init__(self, template_string, origin):
|
def __init__(self, template_string, origin):
|
||||||
super(DebugLexer,self).__init__(template_string, origin)
|
super(DebugLexer, self).__init__(template_string, origin)
|
||||||
|
|
||||||
def tokenize(self):
|
def tokenize(self):
|
||||||
"Return a list of tokens from a given template_string"
|
"Return a list of tokens from a given template_string"
|
||||||
token_tups, upto = [], 0
|
token_tups, upto = [], 0
|
||||||
for match in tag_re.finditer(self.template_string):
|
for match in tag_re.finditer(self.template_string):
|
||||||
start, end = match.span()
|
start, end = match.span()
|
||||||
if start > upto:
|
if start > upto:
|
||||||
token_tups.append( (self.template_string[upto:start], (upto, start) ) )
|
token_tups.append( (self.template_string[upto:start], (upto, start)) )
|
||||||
upto = start
|
upto = start
|
||||||
token_tups.append( (self.template_string[start:end], (start,end) ) )
|
token_tups.append( (self.template_string[start:end], (start,end)) )
|
||||||
upto = end
|
upto = end
|
||||||
last_bit = self.template_string[upto:]
|
last_bit = self.template_string[upto:]
|
||||||
if last_bit:
|
if last_bit:
|
||||||
token_tups.append( (last_bit, (upto, upto + len(last_bit) ) ) )
|
token_tups.append( (last_bit, (upto, upto + len(last_bit))) )
|
||||||
return [ self.create_token(tok, (self.origin, loc)) for tok, loc in token_tups]
|
return [self.create_token(tok, (self.origin, loc)) for tok, loc in token_tups]
|
||||||
|
|
||||||
def create_token(self, token_string, source):
|
def create_token(self, token_string, source):
|
||||||
token = super(DebugLexer, self).create_token(token_string)
|
token = super(DebugLexer, self).create_token(token_string)
|
||||||
@ -288,7 +290,7 @@ class Parser(object):
|
|||||||
try:
|
try:
|
||||||
compile_func = registered_tags[command]
|
compile_func = registered_tags[command]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.invalid_block_tag(token, command)
|
self.invalid_block_tag(token, command)
|
||||||
try:
|
try:
|
||||||
compiled_result = compile_func(self, token)
|
compiled_result = compile_func(self, token)
|
||||||
except TemplateSyntaxError, e:
|
except TemplateSyntaxError, e:
|
||||||
@ -305,13 +307,13 @@ class Parser(object):
|
|||||||
|
|
||||||
def create_nodelist(self):
|
def create_nodelist(self):
|
||||||
return NodeList()
|
return NodeList()
|
||||||
|
|
||||||
def extend_nodelist(self, nodelist, node, token):
|
def extend_nodelist(self, nodelist, node, token):
|
||||||
nodelist.append(node)
|
nodelist.append(node)
|
||||||
|
|
||||||
def enter_command(self, command, token):
|
def enter_command(self, command, token):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def exit_command(self):
|
def exit_command(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -320,19 +322,19 @@ class Parser(object):
|
|||||||
|
|
||||||
def empty_variable(self, token):
|
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):
|
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):
|
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):
|
def unclosed_block_tag(self, parse_until):
|
||||||
raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until))
|
raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until))
|
||||||
|
|
||||||
def compile_function_error(self, token, e):
|
def compile_function_error(self, token, e):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def next_token(self):
|
def next_token(self):
|
||||||
return self.tokens.pop(0)
|
return self.tokens.pop(0)
|
||||||
|
|
||||||
@ -341,7 +343,7 @@ class Parser(object):
|
|||||||
|
|
||||||
def delete_first_token(self):
|
def delete_first_token(self):
|
||||||
del self.tokens[0]
|
del self.tokens[0]
|
||||||
|
|
||||||
class DebugParser(Parser):
|
class DebugParser(Parser):
|
||||||
def __init__(self, lexer):
|
def __init__(self, lexer):
|
||||||
super(DebugParser, self).__init__(lexer)
|
super(DebugParser, self).__init__(lexer)
|
||||||
@ -349,7 +351,7 @@ class DebugParser(Parser):
|
|||||||
|
|
||||||
def enter_command(self, command, token):
|
def enter_command(self, command, token):
|
||||||
self.command_stack.append( (command, token.source) )
|
self.command_stack.append( (command, token.source) )
|
||||||
|
|
||||||
def exit_command(self):
|
def exit_command(self):
|
||||||
self.command_stack.pop()
|
self.command_stack.pop()
|
||||||
|
|
||||||
@ -370,11 +372,10 @@ class DebugParser(Parser):
|
|||||||
def extend_nodelist(self, nodelist, node, token):
|
def extend_nodelist(self, nodelist, node, token):
|
||||||
node.source = token.source
|
node.source = token.source
|
||||||
super(DebugParser, self).extend_nodelist(nodelist, node, token)
|
super(DebugParser, self).extend_nodelist(nodelist, node, token)
|
||||||
|
|
||||||
def unclosed_block_tag(self, parse_until):
|
def unclosed_block_tag(self, parse_until):
|
||||||
(command, source) = self.command_stack.pop()
|
(command, source) = self.command_stack.pop()
|
||||||
msg = "Unclosed tag '%s'. Looking for one of: %s " % \
|
msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
|
||||||
(command, ', '.join(parse_until) )
|
|
||||||
raise self.source_error( source, msg)
|
raise self.source_error( source, msg)
|
||||||
|
|
||||||
def compile_function_error(self, token, e):
|
def compile_function_error(self, token, e):
|
||||||
@ -661,15 +662,14 @@ filter_raw_string = r"""
|
|||||||
'filter_sep': re.escape(FILTER_SEPARATOR),
|
'filter_sep': re.escape(FILTER_SEPARATOR),
|
||||||
'arg_sep': re.escape(FILTER_ARGUMENT_SEPARATOR),
|
'arg_sep': re.escape(FILTER_ARGUMENT_SEPARATOR),
|
||||||
'i18n_open' : re.escape("_("),
|
'i18n_open' : re.escape("_("),
|
||||||
'i18n_close' : re.escape(")"),
|
'i18n_close' : re.escape(")"),
|
||||||
}
|
}
|
||||||
|
|
||||||
filter_raw_string = filter_raw_string.replace("\n", "").replace(" ", "")
|
filter_raw_string = filter_raw_string.replace("\n", "").replace(" ", "")
|
||||||
filter_re = re.compile(filter_raw_string)
|
filter_re = re.compile(filter_raw_string)
|
||||||
|
|
||||||
class RegexFilterParser(object):
|
class RegexFilterParser(object):
|
||||||
""" Not used yet because of i18n"""
|
"Not used yet because of i18n"
|
||||||
|
|
||||||
def __init__(self, token):
|
def __init__(self, token):
|
||||||
matches = filter_re.finditer(token)
|
matches = filter_re.finditer(token)
|
||||||
var = None
|
var = None
|
||||||
@ -827,7 +827,7 @@ class DebugNodeList(NodeList):
|
|||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
from sys import exc_info
|
from sys import exc_info
|
||||||
wrapped = TemplateSyntaxError( 'Caught exception whilst rendering' )
|
wrapped = TemplateSyntaxError('Caught an exception while rendering.')
|
||||||
wrapped.source = node.source
|
wrapped.source = node.source
|
||||||
wrapped.exc_info = exc_info()
|
wrapped.exc_info = exc_info()
|
||||||
raise wrapped
|
raise wrapped
|
||||||
@ -858,7 +858,7 @@ class VariableNode(Node):
|
|||||||
return output.encode(DEFAULT_CHARSET)
|
return output.encode(DEFAULT_CHARSET)
|
||||||
else:
|
else:
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
output = resolve_variable_with_filters(self.var_string, context)
|
output = resolve_variable_with_filters(self.var_string, context)
|
||||||
return self.encode_output(output)
|
return self.encode_output(output)
|
||||||
|
@ -192,7 +192,7 @@ class RegroupNode(Node):
|
|||||||
for obj in obj_list:
|
for obj in obj_list:
|
||||||
grouper = resolve_variable_with_filters('var.%s' % self.expression, \
|
grouper = resolve_variable_with_filters('var.%s' % self.expression, \
|
||||||
Context({'var': obj}))
|
Context({'var': obj}))
|
||||||
#TODO: Is this a sensible way to determine equality?
|
# TODO: Is this a sensible way to determine equality?
|
||||||
if output and repr(output[-1]['grouper']) == repr(grouper):
|
if output and repr(output[-1]['grouper']) == repr(grouper):
|
||||||
output[-1]['list'].append(obj)
|
output[-1]['list'].append(obj)
|
||||||
else:
|
else:
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
#
|
#
|
||||||
# name is the template name.
|
# name is the template name.
|
||||||
# dirs is an optional list of directories to search instead of TEMPLATE_DIRS.
|
# dirs is an optional list of directories to search instead of TEMPLATE_DIRS.
|
||||||
|
#
|
||||||
# The loader should return a tuple of (template_source, path). The path returned
|
# The loader should return a tuple of (template_source, path). The path returned
|
||||||
# will be shown to the user for debugging purposes, so it should identify where the template
|
# might be shown to the user for debugging purposes, so it should identify where
|
||||||
# was loaded from.
|
# the template was loaded from.
|
||||||
#
|
#
|
||||||
# Each loader should have an "is_usable" attribute set. This is a boolean that
|
# Each loader should have an "is_usable" attribute set. This is a boolean that
|
||||||
# specifies whether the loader can be used in this Python installation. Each
|
# specifies whether the loader can be used in this Python installation. Each
|
||||||
@ -45,7 +46,7 @@ class LoaderOrigin(Origin):
|
|||||||
def __init__(self, display_name, loader, name, dirs):
|
def __init__(self, display_name, loader, name, dirs):
|
||||||
super(LoaderOrigin, self).__init__(display_name)
|
super(LoaderOrigin, self).__init__(display_name)
|
||||||
self.loader, self.loadname, self.dirs = loader, name, dirs
|
self.loader, self.loadname, self.dirs = loader, name, dirs
|
||||||
|
|
||||||
def reload(self):
|
def reload(self):
|
||||||
return self.loader(self.loadname, self.dirs)[0]
|
return self.loader(self.loadname, self.dirs)[0]
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ def render_to_string(template_name, dictionary=None, context_instance=None):
|
|||||||
Loads the given template_name and renders it with the given dictionary as
|
Loads the given template_name and renders it with the given dictionary as
|
||||||
context. The template_name may be a string to load a single template using
|
context. The template_name may be a string to load a single template using
|
||||||
get_template, or it may be a tuple to use select_template to find one of
|
get_template, or it may be a tuple to use select_template to find one of
|
||||||
the templates in the list. Returns a string.
|
the templates in the list. Returns a string.
|
||||||
"""
|
"""
|
||||||
dictionary = dictionary or {}
|
dictionary = dictionary or {}
|
||||||
if isinstance(template_name, (list, tuple)):
|
if isinstance(template_name, (list, tuple)):
|
||||||
@ -99,7 +100,7 @@ def render_to_string(template_name, dictionary=None, context_instance=None):
|
|||||||
if context_instance:
|
if context_instance:
|
||||||
context_instance.update(dictionary)
|
context_instance.update(dictionary)
|
||||||
else:
|
else:
|
||||||
context_instance = Context(dictionary)
|
context_instance = Context(dictionary)
|
||||||
return t.render(context_instance)
|
return t.render(context_instance)
|
||||||
|
|
||||||
def select_template(template_name_list):
|
def select_template(template_name_list):
|
||||||
@ -185,26 +186,26 @@ class ConstantIncludeNode(Node):
|
|||||||
def __init__(self, template_path):
|
def __init__(self, template_path):
|
||||||
try:
|
try:
|
||||||
t = get_template(template_path)
|
t = get_template(template_path)
|
||||||
self.nodelist = t.nodelist
|
self.template = t
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
if TEMPLATE_DEBUG:
|
if TEMPLATE_DEBUG:
|
||||||
raise
|
raise
|
||||||
self.nodelist = None
|
self.template = None
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
if self.nodelist:
|
if self.template:
|
||||||
return self.nodelist.render(context)
|
return self.template.render(context)
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
class IncludeNode(Node):
|
class IncludeNode(Node):
|
||||||
def __init__(self, template_path_var):
|
def __init__(self, template_name):
|
||||||
self.template_path_var = template_path_var
|
self.template_name = template_name
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
try:
|
try:
|
||||||
template_path = resolve_variable(self.template_path_var, context)
|
template_name = resolve_variable(self.template_name, context)
|
||||||
t = get_template(template_path)
|
t = get_template(template_name)
|
||||||
return t.render(context)
|
return t.render(context)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
if TEMPLATE_DEBUG:
|
if TEMPLATE_DEBUG:
|
||||||
|
@ -23,7 +23,7 @@ for app in INSTALLED_APPS:
|
|||||||
template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
|
template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
|
||||||
if os.path.isdir(template_dir):
|
if os.path.isdir(template_dir):
|
||||||
app_template_dirs.append(template_dir)
|
app_template_dirs.append(template_dir)
|
||||||
|
|
||||||
# It won't change, so convert it to a tuple to save memory.
|
# It won't change, so convert it to a tuple to save memory.
|
||||||
app_template_dirs = tuple(app_template_dirs)
|
app_template_dirs = tuple(app_template_dirs)
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ def load_template_source(template_name, template_dirs=None):
|
|||||||
pkg_name = 'templates/' + template_name + TEMPLATE_FILE_EXTENSION
|
pkg_name = 'templates/' + template_name + TEMPLATE_FILE_EXTENSION
|
||||||
for app in INSTALLED_APPS:
|
for app in INSTALLED_APPS:
|
||||||
try:
|
try:
|
||||||
return (resource_string(app, pkg_name), 'egg:%s:%s ' % (app, pkg_name))
|
return (resource_string(app, pkg_name), 'egg:%s:%s ' % (app, pkg_name))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
raise TemplateDoesNotExist, template_name
|
raise TemplateDoesNotExist, template_name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user