diff options
| author | Robin Munn <robin.munn@gmail.com> | 2006-11-08 04:50:01 +0000 |
|---|---|---|
| committer | Robin Munn <robin.munn@gmail.com> | 2006-11-08 04:50:01 +0000 |
| commit | dadfca08c0db567ce33284aaa8eb388cf667a836 (patch) | |
| tree | ab7255eeee1bbe03d95652cc74a3843fa052d8ac /django/template | |
| parent | 0b059aa4eadc1d95ceca3a32821b65a9fb2a53e8 (diff) | |
sqlalchemy: Merged revisions 3918 to 4053 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/sqlalchemy@4054 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/template')
| -rw-r--r-- | django/template/__init__.py | 23 | ||||
| -rw-r--r-- | django/template/context.py | 2 | ||||
| -rw-r--r-- | django/template/defaultfilters.py | 6 | ||||
| -rw-r--r-- | django/template/defaulttags.py | 57 | ||||
| -rw-r--r-- | django/template/loaders/app_directories.py | 4 |
5 files changed, 65 insertions, 27 deletions
diff --git a/django/template/__init__.py b/django/template/__init__.py index af8f37a474..5affafeba9 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -66,6 +66,7 @@ __all__ = ('Template', 'Context', 'RequestContext', 'compile_string') TOKEN_TEXT = 0 TOKEN_VAR = 1 TOKEN_BLOCK = 2 +TOKEN_COMMENT = 3 # template syntax constants FILTER_SEPARATOR = '|' @@ -75,6 +76,8 @@ BLOCK_TAG_START = '{%' BLOCK_TAG_END = '%}' VARIABLE_TAG_START = '{{' VARIABLE_TAG_END = '}}' +COMMENT_TAG_START = '{#' +COMMENT_TAG_END = '#}' SINGLE_BRACE_START = '{' SINGLE_BRACE_END = '}' @@ -85,8 +88,9 @@ ALLOWED_VARIABLE_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01 UNKNOWN_SOURCE="<unknown source>" # match a variable or block tag and capture the entire tag, including start/end delimiters -tag_re = re.compile('(%s.*?%s|%s.*?%s)' % (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END), - re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END))) +tag_re = re.compile('(%s.*?%s|%s.*?%s|%s.*?%s)' % (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END), + re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END), + re.escape(COMMENT_TAG_START), re.escape(COMMENT_TAG_END))) # global dictionary of libraries that have been loaded using get_library libraries = {} @@ -163,12 +167,12 @@ def compile_string(template_string, origin): class Token(object): def __init__(self, token_type, contents): - "The token_type must be TOKEN_TEXT, TOKEN_VAR or TOKEN_BLOCK" + "The token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT" self.token_type, self.contents = token_type, contents def __str__(self): 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', TOKEN_COMMENT: 'Comment'}[self.token_type], self.contents[:20].replace('\n', '')) def split_contents(self): @@ -191,6 +195,8 @@ class Lexer(object): token = Token(TOKEN_VAR, token_string[len(VARIABLE_TAG_START):-len(VARIABLE_TAG_END)].strip()) elif token_string.startswith(BLOCK_TAG_START): token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip()) + elif token_string.startswith(COMMENT_TAG_START): + token = Token(TOKEN_COMMENT, '') else: token = Token(TOKEN_TEXT, token_string) return token @@ -862,8 +868,11 @@ class Library(object): dict = func(*args) if not getattr(self, 'nodelist', False): - from django.template.loader import get_template - t = get_template(file_name) + from django.template.loader import get_template, select_template + if hasattr(file_name, '__iter__'): + t = select_template(file_name) + else: + t = get_template(file_name) self.nodelist = t.nodelist return self.nodelist.render(context_class(dict)) @@ -877,7 +886,7 @@ def get_library(module_name): lib = libraries.get(module_name, None) if not lib: try: - mod = __import__(module_name, '', '', ['']) + mod = __import__(module_name, {}, {}, ['']) except ImportError, e: raise InvalidTemplateLibrary, "Could not load template library from %s, %s" % (module_name, e) try: diff --git a/django/template/context.py b/django/template/context.py index 6d9efdc7ec..ba23e95ab7 100644 --- a/django/template/context.py +++ b/django/template/context.py @@ -69,7 +69,7 @@ def get_standard_processors(): i = path.rfind('.') module, attr = path[:i], path[i+1:] try: - mod = __import__(module, '', '', [attr]) + mod = __import__(module, {}, {}, [attr]) except ImportError, e: raise ImproperlyConfigured, 'Error importing request processor module %s: "%s"' % (module, e) try: diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index cf1d3d5f6d..969ef7b28b 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -421,7 +421,11 @@ def filesizeformat(bytes): Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102 bytes, etc). """ - bytes = float(bytes) + try: + bytes = float(bytes) + except TypeError: + return "0 bytes" + if bytes < 1024: return "%d byte%s" % (bytes, bytes != 1 and 's' or '') if bytes < 1024 * 1024: diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 07e579bf9d..3f3f4bda56 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -1,7 +1,7 @@ "Default tags used by the template system, available to all templates." from django.template import Node, NodeList, Template, Context, resolve_variable -from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END +from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END from django.template import get_library, Library, InvalidTemplateLibrary from django.conf import settings import sys @@ -124,17 +124,27 @@ class ForNode(Node): return nodelist.render(context) class IfChangedNode(Node): - def __init__(self, nodelist): + def __init__(self, nodelist, *varlist): self.nodelist = nodelist self._last_seen = None + self._varlist = varlist def render(self, context): if context.has_key('forloop') and context['forloop']['first']: self._last_seen = None - content = self.nodelist.render(context) - if content != self._last_seen: + try: + if self._varlist: + # Consider multiple parameters. + # This automatically behaves like a OR evaluation of the multiple variables. + compare_to = [resolve_variable(var, context) for var in self._varlist] + else: + compare_to = self.nodelist.render(context) + except VariableDoesNotExist: + compare_to = None + + if compare_to != self._last_seen: firstloop = (self._last_seen == None) - self._last_seen = content + self._last_seen = compare_to context.push() context['ifchanged'] = {'firstloop': firstloop} content = self.nodelist.render(context) @@ -295,6 +305,8 @@ class TemplateTagNode(Node): 'closevariable': VARIABLE_TAG_END, 'openbrace': SINGLE_BRACE_START, 'closebrace': SINGLE_BRACE_END, + 'opencomment': COMMENT_TAG_START, + 'closecomment': COMMENT_TAG_END, } def __init__(self, tagtype): @@ -632,23 +644,34 @@ def ifchanged(parser, token): """ Check if a value has changed from the last iteration of a loop. - The 'ifchanged' block tag is used within a loop. It checks its own rendered - contents against its previous state and only displays its content if the - value has changed:: + The 'ifchanged' block tag is used within a loop. It has two possible uses. - <h1>Archive for {{ year }}</h1> + 1. Checks its own rendered contents against its previous state and only + displays the content if it has changed. For example, this displays a list of + days, only displaying the month if it changes:: - {% for date in days %} - {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} - <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> - {% endfor %} + <h1>Archive for {{ year }}</h1> + + {% for date in days %} + {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} + <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> + {% endfor %} + + 2. If given a variable, check whether that variable has changed. For example, the + following shows the date every time it changes, but only shows the hour if both + the hour and the date have changed:: + + {% for date in days %} + {% ifchanged date.date %} {{ date.date }} {% endifchanged %} + {% ifchanged date.hour date.date %} + {{ date.hour }} + {% endifchanged %} + {% endfor %} """ bits = token.contents.split() - if len(bits) != 1: - raise TemplateSyntaxError, "'ifchanged' tag takes no arguments" nodelist = parser.parse(('endifchanged',)) parser.delete_first_token() - return IfChangedNode(nodelist) + return IfChangedNode(nodelist, *bits[1:]) ifchanged = register.tag(ifchanged) #@register.tag @@ -831,6 +854,8 @@ def templatetag(parser, token): ``closevariable`` ``}}`` ``openbrace`` ``{`` ``closebrace`` ``}`` + ``opencomment`` ``{#`` + ``closecomment`` ``#}`` ================== ======= """ bits = token.contents.split() diff --git a/django/template/loaders/app_directories.py b/django/template/loaders/app_directories.py index 8a9bfef4b6..c4e91df929 100644 --- a/django/template/loaders/app_directories.py +++ b/django/template/loaders/app_directories.py @@ -15,9 +15,9 @@ for app in settings.INSTALLED_APPS: m, a = app[:i], app[i+1:] try: if a is None: - mod = __import__(m, '', '', []) + mod = __import__(m, {}, {}, []) else: - mod = getattr(__import__(m, '', '', [a]), a) + mod = getattr(__import__(m, {}, {}, [a]), a) except ImportError, e: raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0]) template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates') |
