mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Style and import fixes.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6641 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -1,11 +1,12 @@ | |||||||
| "Default variable filters" | """Default variable filters.""" | ||||||
|  |  | ||||||
|  | import re | ||||||
|  | import random as random_module | ||||||
|  |  | ||||||
| from django.template import Variable, Library | from django.template import Variable, Library | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.utils.translation import ugettext, ungettext | from django.utils.translation import ugettext, ungettext | ||||||
| from django.utils.encoding import force_unicode, smart_str, iri_to_uri | from django.utils.encoding import force_unicode, iri_to_uri | ||||||
| import re |  | ||||||
| import random as random_module |  | ||||||
|  |  | ||||||
| register = Library() | register = Library() | ||||||
|  |  | ||||||
| @@ -36,17 +37,17 @@ def stringfilter(func): | |||||||
|  |  | ||||||
|  |  | ||||||
| def addslashes(value): | def addslashes(value): | ||||||
|     "Adds slashes - useful for passing strings to JavaScript, for example." |     """Adds slashes - useful for passing strings to JavaScript, for example.""" | ||||||
|     return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") |     return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") | ||||||
| addslashes = stringfilter(addslashes) | addslashes = stringfilter(addslashes) | ||||||
|  |  | ||||||
| def capfirst(value): | def capfirst(value): | ||||||
|     "Capitalizes the first character of the value" |     """Capitalizes the first character of the value.""" | ||||||
|     return value and value[0].upper() + value[1:] |     return value and value[0].upper() + value[1:] | ||||||
| capfirst = stringfilter(capfirst) | capfirst = stringfilter(capfirst) | ||||||
|  |  | ||||||
| def fix_ampersands(value): | def fix_ampersands(value): | ||||||
|     "Replaces ampersands with ``&`` entities" |     """Replaces ampersands with ``&`` entities.""" | ||||||
|     from django.utils.html import fix_ampersands |     from django.utils.html import fix_ampersands | ||||||
|     return fix_ampersands(value) |     return fix_ampersands(value) | ||||||
| fix_ampersands = stringfilter(fix_ampersands) | fix_ampersands = stringfilter(fix_ampersands) | ||||||
| @@ -86,15 +87,16 @@ def floatformat(text, arg=-1): | |||||||
|         return formatstr % f |         return formatstr % f | ||||||
|  |  | ||||||
| def iriencode(value): | def iriencode(value): | ||||||
|     "Escapes an IRI value for use in a URL" |     """Escapes an IRI value for use in a URL.""" | ||||||
|     return force_unicode(iri_to_uri(value)) |     return force_unicode(iri_to_uri(value)) | ||||||
| iriencode = stringfilter(iriencode) | iriencode = stringfilter(iriencode) | ||||||
|  |  | ||||||
| def linenumbers(value): | def linenumbers(value): | ||||||
|     "Displays text with line numbers" |     """Displays text with line numbers.""" | ||||||
|     from django.utils.html import escape |     from django.utils.html import escape | ||||||
|     lines = value.split(u'\n') |     lines = value.split(u'\n') | ||||||
|     # Find the maximum width of the line count, for use with zero padding string format command |     # Find the maximum width of the line count, for use with zero padding | ||||||
|  |     # string format command. | ||||||
|     width = unicode(len(unicode(len(lines)))) |     width = unicode(len(unicode(len(lines)))) | ||||||
|     for i, line in enumerate(lines): |     for i, line in enumerate(lines): | ||||||
|         lines[i] = (u"%0" + width  + u"d. %s") % (i + 1, escape(line)) |         lines[i] = (u"%0" + width  + u"d. %s") % (i + 1, escape(line)) | ||||||
| @@ -102,22 +104,24 @@ def linenumbers(value): | |||||||
| linenumbers = stringfilter(linenumbers) | linenumbers = stringfilter(linenumbers) | ||||||
|  |  | ||||||
| def lower(value): | def lower(value): | ||||||
|     "Converts a string into all lowercase" |     """Converts a string into all lowercase.""" | ||||||
|     return value.lower() |     return value.lower() | ||||||
| lower = stringfilter(lower) | lower = stringfilter(lower) | ||||||
|  |  | ||||||
| def make_list(value): | def make_list(value): | ||||||
|     """ |     """ | ||||||
|     Returns the value turned into a list. For an integer, it's a list of |     Returns the value turned into a list. | ||||||
|     digits. For a string, it's a list of characters. |  | ||||||
|  |     For an integer, it's a list of digits. | ||||||
|  |     For a string, it's a list of characters. | ||||||
|     """ |     """ | ||||||
|     return list(value) |     return list(value) | ||||||
| make_list = stringfilter(make_list) | make_list = stringfilter(make_list) | ||||||
|  |  | ||||||
| def slugify(value): | def slugify(value): | ||||||
|     """ |     """ | ||||||
|     Normalizes string, converts to lowercase, removes non-alpha chars and |     Normalizes string, converts to lowercase, removes non-alpha characters, | ||||||
|     converts spaces to hyphens. |     and converts spaces to hyphens. | ||||||
|     """ |     """ | ||||||
|     import unicodedata |     import unicodedata | ||||||
|     value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') |     value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') | ||||||
| @@ -127,7 +131,8 @@ slugify = stringfilter(slugify) | |||||||
|  |  | ||||||
| def stringformat(value, arg): | def stringformat(value, arg): | ||||||
|     """ |     """ | ||||||
|     Formats the variable according to the argument, a string formatting specifier. |     Formats the variable according to the arg, a string formatting specifier. | ||||||
|  |  | ||||||
|     This specifier uses Python string formating syntax, with the exception that |     This specifier uses Python string formating syntax, with the exception that | ||||||
|     the leading "%" is dropped. |     the leading "%" is dropped. | ||||||
|  |  | ||||||
| @@ -140,29 +145,29 @@ def stringformat(value, arg): | |||||||
|         return u"" |         return u"" | ||||||
|  |  | ||||||
| def title(value): | def title(value): | ||||||
|     "Converts a string into titlecase" |     """Converts a string into titlecase.""" | ||||||
|     return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title()) |     return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title()) | ||||||
| title = stringfilter(title) | title = stringfilter(title) | ||||||
|  |  | ||||||
| def truncatewords(value, arg): | def truncatewords(value, arg): | ||||||
|     """ |     """ | ||||||
|     Truncates a string after a certain number of words |     Truncates a string after a certain number of words. | ||||||
|  |  | ||||||
|     Argument: Number of words to truncate after |     Argument: Number of words to truncate after. | ||||||
|     """ |     """ | ||||||
|     from django.utils.text import truncate_words |     from django.utils.text import truncate_words | ||||||
|     try: |     try: | ||||||
|         length = int(arg) |         length = int(arg) | ||||||
|     except ValueError: # invalid literal for int() |     except ValueError: # Invalid literal for int(). | ||||||
|         return value # Fail silently. |         return value # Fail silently. | ||||||
|     return truncate_words(value, length) |     return truncate_words(value, length) | ||||||
| truncatewords = stringfilter(truncatewords) | truncatewords = stringfilter(truncatewords) | ||||||
|  |  | ||||||
| def truncatewords_html(value, arg): | def truncatewords_html(value, arg): | ||||||
|     """ |     """ | ||||||
|     Truncates HTML after a certain number of words |     Truncates HTML after a certain number of words. | ||||||
|  |  | ||||||
|     Argument: Number of words to truncate after |     Argument: Number of words to truncate after. | ||||||
|     """ |     """ | ||||||
|     from django.utils.text import truncate_html_words |     from django.utils.text import truncate_html_words | ||||||
|     try: |     try: | ||||||
| @@ -173,26 +178,26 @@ def truncatewords_html(value, arg): | |||||||
| truncatewords_html = stringfilter(truncatewords_html) | truncatewords_html = stringfilter(truncatewords_html) | ||||||
|  |  | ||||||
| def upper(value): | def upper(value): | ||||||
|     "Converts a string into all uppercase" |     """Converts a string into all uppercase.""" | ||||||
|     return value.upper() |     return value.upper() | ||||||
| upper = stringfilter(upper) | upper = stringfilter(upper) | ||||||
|  |  | ||||||
| def urlencode(value): | def urlencode(value): | ||||||
|     "Escapes a value for use in a URL" |     """Escapes a value for use in a URL.""" | ||||||
|     from django.utils.http import urlquote |     from django.utils.http import urlquote | ||||||
|     return urlquote(value) |     return urlquote(value) | ||||||
| urlencode = stringfilter(urlencode) | urlencode = stringfilter(urlencode) | ||||||
|  |  | ||||||
| def urlize(value): | def urlize(value): | ||||||
|     "Converts URLs in plain text into clickable links" |     """Converts URLs in plain text into clickable links.""" | ||||||
|     from django.utils.html import urlize |     from django.utils.html import urlize | ||||||
|     return urlize(value, nofollow=True) |     return urlize(value, nofollow=True) | ||||||
| urlize = stringfilter(urlize) | urlize = stringfilter(urlize) | ||||||
|  |  | ||||||
| def urlizetrunc(value, limit): | def urlizetrunc(value, limit): | ||||||
|     """ |     """ | ||||||
|     Converts URLs into clickable links, truncating URLs to the given character limit, |     Converts URLs into clickable links, truncating URLs to the given character | ||||||
|     and adding 'rel=nofollow' attribute to discourage spamming. |     limit, and adding 'rel=nofollow' attribute to discourage spamming. | ||||||
|  |  | ||||||
|     Argument: Length to truncate URLs to. |     Argument: Length to truncate URLs to. | ||||||
|     """ |     """ | ||||||
| @@ -201,13 +206,13 @@ def urlizetrunc(value, limit): | |||||||
| urlizetrunc = stringfilter(urlizetrunc) | urlizetrunc = stringfilter(urlizetrunc) | ||||||
|  |  | ||||||
| def wordcount(value): | def wordcount(value): | ||||||
|     "Returns the number of words" |     """Returns the number of words.""" | ||||||
|     return len(value.split()) |     return len(value.split()) | ||||||
| wordcount = stringfilter(wordcount) | wordcount = stringfilter(wordcount) | ||||||
|  |  | ||||||
| def wordwrap(value, arg): | def wordwrap(value, arg): | ||||||
|     """ |     """ | ||||||
|     Wraps words at specified line length |     Wraps words at specified line length. | ||||||
|  |  | ||||||
|     Argument: number of characters to wrap the text at. |     Argument: number of characters to wrap the text at. | ||||||
|     """ |     """ | ||||||
| @@ -217,29 +222,29 @@ wordwrap = stringfilter(wordwrap) | |||||||
|  |  | ||||||
| def ljust(value, arg): | def ljust(value, arg): | ||||||
|     """ |     """ | ||||||
|     Left-aligns the value in a field of a given width |     Left-aligns the value in a field of a given width. | ||||||
|  |  | ||||||
|     Argument: field size |     Argument: field size. | ||||||
|     """ |     """ | ||||||
|     return value.ljust(int(arg)) |     return value.ljust(int(arg)) | ||||||
| ljust = stringfilter(ljust) | ljust = stringfilter(ljust) | ||||||
|  |  | ||||||
| def rjust(value, arg): | def rjust(value, arg): | ||||||
|     """ |     """ | ||||||
|     Right-aligns the value in a field of a given width |     Right-aligns the value in a field of a given width. | ||||||
|  |  | ||||||
|     Argument: field size |     Argument: field size. | ||||||
|     """ |     """ | ||||||
|     return value.rjust(int(arg)) |     return value.rjust(int(arg)) | ||||||
| rjust = stringfilter(rjust) | rjust = stringfilter(rjust) | ||||||
|  |  | ||||||
| def center(value, arg): | def center(value, arg): | ||||||
|     "Centers the value in a field of a given width" |     """Centers the value in a field of a given width.""" | ||||||
|     return value.center(int(arg)) |     return value.center(int(arg)) | ||||||
| center = stringfilter(center) | center = stringfilter(center) | ||||||
|  |  | ||||||
| def cut(value, arg): | def cut(value, arg): | ||||||
|     "Removes all values of arg from the given string" |     """Removes all values of arg from the given string.""" | ||||||
|     return value.replace(arg, u'') |     return value.replace(arg, u'') | ||||||
| cut = stringfilter(cut) | cut = stringfilter(cut) | ||||||
|  |  | ||||||
| @@ -272,7 +277,7 @@ def linebreaksbr(value): | |||||||
| linebreaksbr = stringfilter(linebreaksbr) | linebreaksbr = stringfilter(linebreaksbr) | ||||||
|  |  | ||||||
| def removetags(value, tags): | def removetags(value, tags): | ||||||
|     "Removes a space separated list of [X]HTML tags from the output" |     """Removes a space separated list of [X]HTML tags from the output.""" | ||||||
|     tags = [re.escape(tag) for tag in tags.split()] |     tags = [re.escape(tag) for tag in tags.split()] | ||||||
|     tags_re = u'(%s)' % u'|'.join(tags) |     tags_re = u'(%s)' % u'|'.join(tags) | ||||||
|     starttag_re = re.compile(ur'<%s(/?>|(\s+[^>]*>))' % tags_re, re.U) |     starttag_re = re.compile(ur'<%s(/?>|(\s+[^>]*>))' % tags_re, re.U) | ||||||
| @@ -283,7 +288,7 @@ def removetags(value, tags): | |||||||
| removetags = stringfilter(removetags) | removetags = stringfilter(removetags) | ||||||
|  |  | ||||||
| def striptags(value): | def striptags(value): | ||||||
|     "Strips all [X]HTML tags" |     """Strips all [X]HTML tags.""" | ||||||
|     from django.utils.html import strip_tags |     from django.utils.html import strip_tags | ||||||
|     return strip_tags(value) |     return strip_tags(value) | ||||||
| striptags = stringfilter(striptags) | striptags = stringfilter(striptags) | ||||||
| @@ -314,29 +319,29 @@ def dictsortreversed(value, arg): | |||||||
|     return [item[1] for item in decorated] |     return [item[1] for item in decorated] | ||||||
|  |  | ||||||
| def first(value): | def first(value): | ||||||
|     "Returns the first item in a list" |     """Returns the first item in a list.""" | ||||||
|     try: |     try: | ||||||
|         return value[0] |         return value[0] | ||||||
|     except IndexError: |     except IndexError: | ||||||
|         return u'' |         return u'' | ||||||
|  |  | ||||||
| def join(value, arg): | def join(value, arg): | ||||||
|     "Joins a list with a string, like Python's ``str.join(list)``" |     """Joins a list with a string, like Python's ``str.join(list)``.""" | ||||||
|     try: |     try: | ||||||
|         return arg.join(map(force_unicode, value)) |         return arg.join(map(force_unicode, value)) | ||||||
|     except AttributeError: # fail silently but nicely |     except AttributeError: # fail silently but nicely | ||||||
|         return value |         return value | ||||||
|  |  | ||||||
| def length(value): | def length(value): | ||||||
|     "Returns the length of the value - useful for lists" |     """Returns the length of the value - useful for lists.""" | ||||||
|     return len(value) |     return len(value) | ||||||
|  |  | ||||||
| def length_is(value, arg): | def length_is(value, arg): | ||||||
|     "Returns a boolean of whether the value's length is the argument" |     """Returns a boolean of whether the value's length is the argument.""" | ||||||
|     return len(value) == int(arg) |     return len(value) == int(arg) | ||||||
|  |  | ||||||
| def random(value): | def random(value): | ||||||
|     "Returns a random item from the list" |     """Returns a random item from the list.""" | ||||||
|     return random_module.choice(value) |     return random_module.choice(value) | ||||||
|  |  | ||||||
| def slice_(value, arg): | def slice_(value, arg): | ||||||
| @@ -416,7 +421,7 @@ def unordered_list(value): | |||||||
|             sublist = '' |             sublist = '' | ||||||
|             sublist_item = None |             sublist_item = None | ||||||
|             if isinstance(title, (list, tuple)): |             if isinstance(title, (list, tuple)): | ||||||
|                 sublist_item = title  |                 sublist_item = title | ||||||
|                 title = '' |                 title = '' | ||||||
|             elif i < list_length - 1: |             elif i < list_length - 1: | ||||||
|                 next_item = list_[i+1] |                 next_item = list_[i+1] | ||||||
| @@ -424,7 +429,7 @@ def unordered_list(value): | |||||||
|                     # The next item is a sub-list. |                     # The next item is a sub-list. | ||||||
|                     sublist_item = next_item |                     sublist_item = next_item | ||||||
|                     # We've processed the next item now too. |                     # We've processed the next item now too. | ||||||
|                     i += 1  |                     i += 1 | ||||||
|             if sublist_item: |             if sublist_item: | ||||||
|                 sublist = _helper(sublist_item, tabs+1) |                 sublist = _helper(sublist_item, tabs+1) | ||||||
|                 sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist, |                 sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist, | ||||||
| @@ -433,7 +438,7 @@ def unordered_list(value): | |||||||
|                                                sublist)) |                                                sublist)) | ||||||
|             i += 1 |             i += 1 | ||||||
|         return '\n'.join(output) |         return '\n'.join(output) | ||||||
|     value, converted = convert_old_style_list(value)  |     value, converted = convert_old_style_list(value) | ||||||
|     return _helper(value) |     return _helper(value) | ||||||
|  |  | ||||||
| ################### | ################### | ||||||
| @@ -441,7 +446,7 @@ def unordered_list(value): | |||||||
| ################### | ################### | ||||||
|  |  | ||||||
| def add(value, arg): | def add(value, arg): | ||||||
|     "Adds the arg to the value" |     """Adds the arg to the value.""" | ||||||
|     return int(value) + int(arg) |     return int(value) + int(arg) | ||||||
|  |  | ||||||
| def get_digit(value, arg): | def get_digit(value, arg): | ||||||
| @@ -468,7 +473,7 @@ def get_digit(value, arg): | |||||||
| ################### | ################### | ||||||
|  |  | ||||||
| def date(value, arg=None): | def date(value, arg=None): | ||||||
|     "Formats a date according to the given format" |     """Formats a date according to the given format.""" | ||||||
|     from django.utils.dateformat import format |     from django.utils.dateformat import format | ||||||
|     if not value: |     if not value: | ||||||
|         return u'' |         return u'' | ||||||
| @@ -477,7 +482,7 @@ def date(value, arg=None): | |||||||
|     return format(value, arg) |     return format(value, arg) | ||||||
|  |  | ||||||
| def time(value, arg=None): | def time(value, arg=None): | ||||||
|     "Formats a time according to the given format" |     """Formats a time according to the given format.""" | ||||||
|     from django.utils.dateformat import time_format |     from django.utils.dateformat import time_format | ||||||
|     if value in (None, u''): |     if value in (None, u''): | ||||||
|         return u'' |         return u'' | ||||||
| @@ -486,7 +491,7 @@ def time(value, arg=None): | |||||||
|     return time_format(value, arg) |     return time_format(value, arg) | ||||||
|  |  | ||||||
| def timesince(value, arg=None): | def timesince(value, arg=None): | ||||||
|     'Formats a date as the time since that date (i.e. "4 days, 6 hours")' |     """Formats a date as the time since that date (i.e. "4 days, 6 hours").""" | ||||||
|     from django.utils.timesince import timesince |     from django.utils.timesince import timesince | ||||||
|     if not value: |     if not value: | ||||||
|         return u'' |         return u'' | ||||||
| @@ -495,7 +500,7 @@ def timesince(value, arg=None): | |||||||
|     return timesince(value) |     return timesince(value) | ||||||
|  |  | ||||||
| def timeuntil(value, arg=None): | def timeuntil(value, arg=None): | ||||||
|     'Formats a date as the time until that date (i.e. "4 days, 6 hours")' |     """Formats a date as the time until that date (i.e. "4 days, 6 hours").""" | ||||||
|     from django.utils.timesince import timesince |     from django.utils.timesince import timesince | ||||||
|     from datetime import datetime |     from datetime import datetime | ||||||
|     if not value: |     if not value: | ||||||
| @@ -509,17 +514,17 @@ def timeuntil(value, arg=None): | |||||||
| ################### | ################### | ||||||
|  |  | ||||||
| def default(value, arg): | def default(value, arg): | ||||||
|     "If value is unavailable, use given default" |     """If value is unavailable, use given default.""" | ||||||
|     return value or arg |     return value or arg | ||||||
|  |  | ||||||
| def default_if_none(value, arg): | def default_if_none(value, arg): | ||||||
|     "If value is None, use given default" |     """If value is None, use given default.""" | ||||||
|     if value is None: |     if value is None: | ||||||
|         return arg |         return arg | ||||||
|     return value |     return value | ||||||
|  |  | ||||||
| def divisibleby(value, arg): | def divisibleby(value, arg): | ||||||
|     "Returns true if the value is devisible by the argument" |     """Returns True if the value is devisible by the argument.""" | ||||||
|     return int(value) % int(arg) == 0 |     return int(value) % int(arg) == 0 | ||||||
|  |  | ||||||
| def yesno(value, arg=None): | def yesno(value, arg=None): | ||||||
| @@ -544,7 +549,8 @@ def yesno(value, arg=None): | |||||||
|         return value # Invalid arg. |         return value # Invalid arg. | ||||||
|     try: |     try: | ||||||
|         yes, no, maybe = bits |         yes, no, maybe = bits | ||||||
|     except ValueError: # unpack list of wrong size (no "maybe" value provided) |     except ValueError: | ||||||
|  |         # Unpack list of wrong size (no "maybe" value provided). | ||||||
|         yes, no, maybe = bits[0], bits[1], bits[1] |         yes, no, maybe = bits[0], bits[1], bits[1] | ||||||
|     if value is None: |     if value is None: | ||||||
|         return maybe |         return maybe | ||||||
| @@ -558,8 +564,8 @@ def yesno(value, arg=None): | |||||||
|  |  | ||||||
| def filesizeformat(bytes): | def filesizeformat(bytes): | ||||||
|     """ |     """ | ||||||
|     Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102 |     Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, | ||||||
|     bytes, etc). |     102 bytes, etc). | ||||||
|     """ |     """ | ||||||
|     try: |     try: | ||||||
|         bytes = float(bytes) |         bytes = float(bytes) | ||||||
| @@ -591,23 +597,23 @@ def pluralize(value, arg=u's'): | |||||||
|     try: |     try: | ||||||
|         if int(value) != 1: |         if int(value) != 1: | ||||||
|             return plural_suffix |             return plural_suffix | ||||||
|     except ValueError: # invalid string that's not a number |     except ValueError: # Invalid string that's not a number. | ||||||
|         pass |         pass | ||||||
|     except TypeError: # value isn't a string or a number; maybe it's a list? |     except TypeError: # Value isn't a string or a number; maybe it's a list? | ||||||
|         try: |         try: | ||||||
|             if len(value) != 1: |             if len(value) != 1: | ||||||
|                 return plural_suffix |                 return plural_suffix | ||||||
|         except TypeError: # len() of unsized object |         except TypeError: # len() of unsized object. | ||||||
|             pass |             pass | ||||||
|     return singular_suffix |     return singular_suffix | ||||||
|  |  | ||||||
| def phone2numeric(value): | def phone2numeric(value): | ||||||
|     "Takes a phone number and converts it in to its numerical equivalent" |     """Takes a phone number and converts it in to its numerical equivalent.""" | ||||||
|     from django.utils.text import phone2numeric |     from django.utils.text import phone2numeric | ||||||
|     return phone2numeric(value) |     return phone2numeric(value) | ||||||
|  |  | ||||||
| def pprint(value): | def pprint(value): | ||||||
|     "A wrapper around pprint.pprint -- for debugging, really" |     """A wrapper around pprint.pprint -- for debugging, really.""" | ||||||
|     from pprint import pformat |     from pprint import pformat | ||||||
|     try: |     try: | ||||||
|         return pformat(value) |         return pformat(value) | ||||||
|   | |||||||
| @@ -1,6 +1,12 @@ | |||||||
| "Default tags used by the template system, available to all templates." | """Default tags used by the template system, available to all templates.""" | ||||||
|  |  | ||||||
|  | import sys | ||||||
|  | import re | ||||||
| from itertools import cycle as itertools_cycle | from itertools import cycle as itertools_cycle | ||||||
|  | try: | ||||||
|  |     reversed | ||||||
|  | except NameError: | ||||||
|  |     from django.utils.itercompat import reversed     # Python 2.3 fallback | ||||||
|  |  | ||||||
| from django.template import Node, NodeList, Template, Context, Variable | from django.template import Node, NodeList, Template, Context, 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, COMMENT_TAG_START, COMMENT_TAG_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 | ||||||
| @@ -8,13 +14,6 @@ from django.template import get_library, Library, InvalidTemplateLibrary | |||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.utils.encoding import smart_str, smart_unicode | from django.utils.encoding import smart_str, smart_unicode | ||||||
| from django.utils.itercompat import groupby | from django.utils.itercompat import groupby | ||||||
| import sys |  | ||||||
| import re |  | ||||||
|  |  | ||||||
| try: |  | ||||||
|     reversed |  | ||||||
| except NameError: |  | ||||||
|     from django.utils.itercompat import reversed     # Python 2.3 fallback |  | ||||||
|  |  | ||||||
| register = Library() | register = Library() | ||||||
|  |  | ||||||
| @@ -48,7 +47,7 @@ class FilterNode(Node): | |||||||
|  |  | ||||||
|     def render(self, context): |     def render(self, context): | ||||||
|         output = self.nodelist.render(context) |         output = self.nodelist.render(context) | ||||||
|         # apply filters |         # Apply filters. | ||||||
|         context.update({'var': output}) |         context.update({'var': output}) | ||||||
|         filtered = self.filter_expr.resolve(context) |         filtered = self.filter_expr.resolve(context) | ||||||
|         context.pop() |         context.pop() | ||||||
| @@ -80,7 +79,8 @@ class ForNode(Node): | |||||||
|         else: |         else: | ||||||
|             reversed = '' |             reversed = '' | ||||||
|         return "<For Node: for %s in %s, tail_len: %d%s>" % \ |         return "<For Node: for %s in %s, tail_len: %d%s>" % \ | ||||||
|             (', '.join( self.loopvars ), self.sequence, len(self.nodelist_loop), reversed) |             (', '.join(self.loopvars), self.sequence, len(self.nodelist_loop), | ||||||
|  |              reversed) | ||||||
|  |  | ||||||
|     def __iter__(self): |     def __iter__(self): | ||||||
|         for node in self.nodelist_loop: |         for node in self.nodelist_loop: | ||||||
| @@ -114,19 +114,20 @@ class ForNode(Node): | |||||||
|         unpack = len(self.loopvars) > 1 |         unpack = len(self.loopvars) > 1 | ||||||
|         for i, item in enumerate(values): |         for i, item in enumerate(values): | ||||||
|             context['forloop'] = { |             context['forloop'] = { | ||||||
|                 # shortcuts for current loop iteration number |                 # Shortcuts for current loop iteration number. | ||||||
|                 'counter0': i, |                 'counter0': i, | ||||||
|                 'counter': i+1, |                 'counter': i+1, | ||||||
|                 # reverse counter iteration numbers |                 # Reverse counter iteration numbers. | ||||||
|                 'revcounter': len_values - i, |                 'revcounter': len_values - i, | ||||||
|                 'revcounter0': len_values - i - 1, |                 'revcounter0': len_values - i - 1, | ||||||
|                 # boolean values designating first and last times through loop |                 # Boolean values designating first and last times through loop. | ||||||
|                 'first': (i == 0), |                 'first': (i == 0), | ||||||
|                 'last': (i == len_values - 1), |                 'last': (i == len_values - 1), | ||||||
|                 'parentloop': parentloop, |                 'parentloop': parentloop, | ||||||
|             } |             } | ||||||
|             if unpack: |             if unpack: | ||||||
|                 # If there are multiple loop variables, unpack the item into them. |                 # If there are multiple loop variables, unpack the item into | ||||||
|  |                 # them. | ||||||
|                 context.update(dict(zip(self.loopvars, item))) |                 context.update(dict(zip(self.loopvars, item))) | ||||||
|             else: |             else: | ||||||
|                 context[self.loopvars[0]] = item |                 context[self.loopvars[0]] = item | ||||||
| @@ -153,8 +154,8 @@ class IfChangedNode(Node): | |||||||
|             self._last_seen = None |             self._last_seen = None | ||||||
|         try: |         try: | ||||||
|             if self._varlist: |             if self._varlist: | ||||||
|                 # Consider multiple parameters. |                 # Consider multiple parameters.  This automatically behaves | ||||||
|                 # This automatically behaves like a OR evaluation of the multiple variables. |                 # like an OR evaluation of the multiple variables. | ||||||
|                 compare_to = [var.resolve(context) for var in self._varlist] |                 compare_to = [var.resolve(context) for var in self._varlist] | ||||||
|             else: |             else: | ||||||
|                 compare_to = self.nodelist.render(context) |                 compare_to = self.nodelist.render(context) | ||||||
| @@ -248,13 +249,17 @@ class RegroupNode(Node): | |||||||
|  |  | ||||||
|     def render(self, context): |     def render(self, context): | ||||||
|         obj_list = self.target.resolve(context, True) |         obj_list = self.target.resolve(context, True) | ||||||
|         if obj_list == None: # target_var wasn't found in context; fail silently |         if obj_list == None: | ||||||
|  |             # target variable wasn't found in context; fail silently. | ||||||
|             context[self.var_name] = [] |             context[self.var_name] = [] | ||||||
|             return '' |             return '' | ||||||
|         # List of dictionaries in the format |         # List of dictionaries in the format: | ||||||
|         # {'grouper': 'key', 'list': [list of contents]}. |         # {'grouper': 'key', 'list': [list of contents]}. | ||||||
|         context[self.var_name] = [{'grouper':key, 'list':list(val)} for key, val in |         context[self.var_name] = [ | ||||||
|             groupby(obj_list, lambda v, f=self.expression.resolve: f(v, True))] |             {'grouper': key, 'list': list(val)} | ||||||
|  |             for key, val in | ||||||
|  |             groupby(obj_list, lambda v, f=self.expression.resolve: f(v, True)) | ||||||
|  |         ] | ||||||
|         return '' |         return '' | ||||||
|  |  | ||||||
| def include_is_allowed(filepath): | def include_is_allowed(filepath): | ||||||
| @@ -338,13 +343,15 @@ class URLNode(Node): | |||||||
|     def render(self, context): |     def render(self, context): | ||||||
|         from django.core.urlresolvers import reverse, NoReverseMatch |         from django.core.urlresolvers import reverse, NoReverseMatch | ||||||
|         args = [arg.resolve(context) for arg in self.args] |         args = [arg.resolve(context) for arg in self.args] | ||||||
|         kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) for k, v in self.kwargs.items()]) |         kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) | ||||||
|  |                        for k, v in self.kwargs.items()]) | ||||||
|         try: |         try: | ||||||
|             return reverse(self.view_name, args=args, kwargs=kwargs) |             return reverse(self.view_name, args=args, kwargs=kwargs) | ||||||
|         except NoReverseMatch: |         except NoReverseMatch: | ||||||
|             try: |             try: | ||||||
|                 project_name = settings.SETTINGS_MODULE.split('.')[0] |                 project_name = settings.SETTINGS_MODULE.split('.')[0] | ||||||
|                 return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs) |                 return reverse(project_name + '.' + self.view_name, | ||||||
|  |                                args=args, kwargs=kwargs) | ||||||
|             except NoReverseMatch: |             except NoReverseMatch: | ||||||
|                 return '' |                 return '' | ||||||
|  |  | ||||||
| @@ -388,7 +395,7 @@ class WithNode(Node): | |||||||
| #@register.tag | #@register.tag | ||||||
| def comment(parser, token): | def comment(parser, token): | ||||||
|     """ |     """ | ||||||
|     Ignore everything between ``{% comment %}`` and ``{% endcomment %}`` |     Ignores everything between ``{% comment %}`` and ``{% endcomment %}``. | ||||||
|     """ |     """ | ||||||
|     parser.skip_past('endcomment') |     parser.skip_past('endcomment') | ||||||
|     return CommentNode() |     return CommentNode() | ||||||
| @@ -397,7 +404,7 @@ comment = register.tag(comment) | |||||||
| #@register.tag | #@register.tag | ||||||
| def cycle(parser, token): | def cycle(parser, token): | ||||||
|     """ |     """ | ||||||
|     Cycle among the given strings each time this tag is encountered |     Cycles among the given strings each time this tag is encountered. | ||||||
|  |  | ||||||
|     Within a loop, cycles among the given strings each time through |     Within a loop, cycles among the given strings each time through | ||||||
|     the loop:: |     the loop:: | ||||||
| @@ -416,14 +423,14 @@ def cycle(parser, token): | |||||||
|             <tr class="{% cycle rowcolors %}">...</tr> |             <tr class="{% cycle rowcolors %}">...</tr> | ||||||
|  |  | ||||||
|     You can use any number of values, seperated by spaces. Commas can also |     You can use any number of values, seperated by spaces. Commas can also | ||||||
|     be used to separate values; if a comma is used, the cycle values are  |     be used to separate values; if a comma is used, the cycle values are | ||||||
|     interpreted as literal strings. |     interpreted as literal strings. | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
|     # Note: This returns the exact same node on each {% cycle name %} call; that |     # Note: This returns the exact same node on each {% cycle name %} call; | ||||||
|     # is, the node object returned from {% cycle a b c as name %} and the one |     # that is, the node object returned from {% cycle a b c as name %} and the | ||||||
|     # returned from {% cycle name %} are the exact same object.  This shouldn't |     # one returned from {% cycle name %} are the exact same object.  This | ||||||
|     # cause problems (heh), but if it does, now you know. |     # shouldn't cause problems (heh), but if it does, now you know. | ||||||
|     # |     # | ||||||
|     # Ugly hack warning: this stuffs the named template dict into parser so |     # Ugly hack warning: this stuffs the named template dict into parser so | ||||||
|     # that names are only unique within each template (as opposed to using |     # that names are only unique within each template (as opposed to using | ||||||
| @@ -441,10 +448,11 @@ def cycle(parser, token): | |||||||
|         args[1:2] = ['"%s"' % arg for arg in args[1].split(",")] |         args[1:2] = ['"%s"' % arg for arg in args[1].split(",")] | ||||||
|  |  | ||||||
|     if len(args) == 2: |     if len(args) == 2: | ||||||
|         # {% cycle foo %} case |         # {% cycle foo %} case. | ||||||
|         name = args[1] |         name = args[1] | ||||||
|         if not hasattr(parser, '_namedCycleNodes'): |         if not hasattr(parser, '_namedCycleNodes'): | ||||||
|             raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name) |             raise TemplateSyntaxError("No named cycles in template." | ||||||
|  |                                       " '%s' is not defined" % name) | ||||||
|         if not name in parser._namedCycleNodes: |         if not name in parser._namedCycleNodes: | ||||||
|             raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) |             raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) | ||||||
|         return parser._namedCycleNodes[name] |         return parser._namedCycleNodes[name] | ||||||
| @@ -462,7 +470,8 @@ cycle = register.tag(cycle) | |||||||
|  |  | ||||||
| def debug(parser, token): | def debug(parser, token): | ||||||
|     """ |     """ | ||||||
|     Output a whole load of debugging information, including the current context and imported modules. |     Outputs a whole load of debugging information, including the current | ||||||
|  |     context and imported modules. | ||||||
|  |  | ||||||
|     Sample usage:: |     Sample usage:: | ||||||
|  |  | ||||||
| @@ -476,7 +485,7 @@ debug = register.tag(debug) | |||||||
| #@register.tag(name="filter") | #@register.tag(name="filter") | ||||||
| def do_filter(parser, token): | def do_filter(parser, token): | ||||||
|     """ |     """ | ||||||
|     Filter the contents of the blog through variable filters. |     Filters the contents of the blog through variable filters. | ||||||
|  |  | ||||||
|     Filters can also be piped through each other, and they can have |     Filters can also be piped through each other, and they can have | ||||||
|     arguments -- just like in variable syntax. |     arguments -- just like in variable syntax. | ||||||
| @@ -525,14 +534,15 @@ def firstof(parser, token): | |||||||
|     """ |     """ | ||||||
|     bits = token.split_contents()[1:] |     bits = token.split_contents()[1:] | ||||||
|     if len(bits) < 1: |     if len(bits) < 1: | ||||||
|         raise TemplateSyntaxError, "'firstof' statement requires at least one argument" |         raise TemplateSyntaxError("'firstof' statement requires at least one" | ||||||
|  |                                   " argument") | ||||||
|     return FirstOfNode(bits) |     return FirstOfNode(bits) | ||||||
| firstof = register.tag(firstof) | firstof = register.tag(firstof) | ||||||
|  |  | ||||||
| #@register.tag(name="for") | #@register.tag(name="for") | ||||||
| def do_for(parser, token): | def do_for(parser, token): | ||||||
|     """ |     """ | ||||||
|     Loop over each item in an array. |     Loops over each item in an array. | ||||||
|  |  | ||||||
|     For example, to display a list of athletes given ``athlete_list``:: |     For example, to display a list of athletes given ``athlete_list``:: | ||||||
|  |  | ||||||
| @@ -544,9 +554,9 @@ def do_for(parser, token): | |||||||
|  |  | ||||||
|     You can loop over a list in reverse by using |     You can loop over a list in reverse by using | ||||||
|     ``{% for obj in list reversed %}``. |     ``{% for obj in list reversed %}``. | ||||||
|      |  | ||||||
|     You can also unpack multiple values from a two-dimensional array:: |     You can also unpack multiple values from a two-dimensional array:: | ||||||
|      |  | ||||||
|         {% for key,value in dict.items %} |         {% for key,value in dict.items %} | ||||||
|             {{ key }}: {{ value }} |             {{ key }}: {{ value }} | ||||||
|         {% endfor %} |         {% endfor %} | ||||||
| @@ -571,17 +581,20 @@ def do_for(parser, token): | |||||||
|     """ |     """ | ||||||
|     bits = token.contents.split() |     bits = token.contents.split() | ||||||
|     if len(bits) < 4: |     if len(bits) < 4: | ||||||
|         raise TemplateSyntaxError, "'for' statements should have at least four words: %s" % token.contents |         raise TemplateSyntaxError("'for' statements should have at least four" | ||||||
|  |                                   " words: %s" % token.contents) | ||||||
|  |  | ||||||
|     reversed = bits[-1] == 'reversed' |     reversed = bits[-1] == 'reversed' | ||||||
|     in_index = reversed and -3 or -2 |     in_index = reversed and -3 or -2 | ||||||
|     if bits[in_index] != 'in': |     if bits[in_index] != 'in': | ||||||
|         raise TemplateSyntaxError, "'for' statements should use the format 'for x in y': %s" % token.contents |         raise TemplateSyntaxError("'for' statements should use the format" | ||||||
|  |                                   " 'for x in y': %s" % token.contents) | ||||||
|  |  | ||||||
|     loopvars = re.sub(r' *, *', ',', ' '.join(bits[1:in_index])).split(',') |     loopvars = re.sub(r' *, *', ',', ' '.join(bits[1:in_index])).split(',') | ||||||
|     for var in loopvars: |     for var in loopvars: | ||||||
|         if not var or ' ' in var: |         if not var or ' ' in var: | ||||||
|             raise TemplateSyntaxError, "'for' tag received an invalid argument: %s" % token.contents |             raise TemplateSyntaxError("'for' tag received an invalid argument:" | ||||||
|  |                                       " %s" % token.contents) | ||||||
|  |  | ||||||
|     sequence = parser.compile_filter(bits[in_index+1]) |     sequence = parser.compile_filter(bits[in_index+1]) | ||||||
|     nodelist_loop = parser.parse(('endfor',)) |     nodelist_loop = parser.parse(('endfor',)) | ||||||
| @@ -606,7 +619,7 @@ def do_ifequal(parser, token, negate): | |||||||
| #@register.tag | #@register.tag | ||||||
| def ifequal(parser, token): | def ifequal(parser, token): | ||||||
|     """ |     """ | ||||||
|     Output the contents of the block if the two arguments equal each other. |     Outputs the contents of the block if the two arguments equal each other. | ||||||
|  |  | ||||||
|     Examples:: |     Examples:: | ||||||
|  |  | ||||||
| @@ -625,7 +638,10 @@ ifequal = register.tag(ifequal) | |||||||
|  |  | ||||||
| #@register.tag | #@register.tag | ||||||
| def ifnotequal(parser, token): | def ifnotequal(parser, token): | ||||||
|     """Output the contents of the block if the two arguments are not equal. See ifequal.""" |     """ | ||||||
|  |     Outputs the contents of the block if the two arguments are not equal. | ||||||
|  |     See ifequal. | ||||||
|  |     """ | ||||||
|     return do_ifequal(parser, token, True) |     return do_ifequal(parser, token, True) | ||||||
| ifnotequal = register.tag(ifnotequal) | ifnotequal = register.tag(ifnotequal) | ||||||
|  |  | ||||||
| @@ -634,9 +650,7 @@ def do_if(parser, token): | |||||||
|     """ |     """ | ||||||
|     The ``{% if %}`` tag evaluates a variable, and if that variable is "true" |     The ``{% if %}`` tag evaluates a variable, and if that variable is "true" | ||||||
|     (i.e. exists, is not empty, and is not a false boolean value) the contents |     (i.e. exists, is not empty, and is not a false boolean value) the contents | ||||||
|     of the block are output: |     of the block are output:: | ||||||
|  |  | ||||||
|     :: |  | ||||||
|  |  | ||||||
|         {% if athlete_list %} |         {% if athlete_list %} | ||||||
|             Number of athletes: {{ athlete_list|count }} |             Number of athletes: {{ athlete_list|count }} | ||||||
| @@ -647,8 +661,8 @@ def do_if(parser, token): | |||||||
|     In the above, if ``athlete_list`` is not empty, the number of athletes will |     In the above, if ``athlete_list`` is not empty, the number of athletes will | ||||||
|     be displayed by the ``{{ athlete_list|count }}`` variable. |     be displayed by the ``{{ athlete_list|count }}`` variable. | ||||||
|  |  | ||||||
|     As you can see, the ``if`` tag can take an option ``{% else %}`` clause that |     As you can see, the ``if`` tag can take an option ``{% else %}`` clause | ||||||
|     will be displayed if the test fails. |     that will be displayed if the test fails. | ||||||
|  |  | ||||||
|     ``if`` tags may use ``or``, ``and`` or ``not`` to test a number of |     ``if`` tags may use ``or``, ``and`` or ``not`` to test a number of | ||||||
|     variables or to negate a given variable:: |     variables or to negate a given variable:: | ||||||
| @@ -673,9 +687,9 @@ def do_if(parser, token): | |||||||
|             There are some athletes and absolutely no coaches. |             There are some athletes and absolutely no coaches. | ||||||
|         {% endif %} |         {% endif %} | ||||||
|  |  | ||||||
|     ``if`` tags do not allow ``and`` and ``or`` clauses with the same |     ``if`` tags do not allow ``and`` and ``or`` clauses with the same tag, | ||||||
|     tag, because the order of logic would be ambigous. For example, |     because the order of logic would be ambigous. For example, this is | ||||||
|     this is invalid:: |     invalid:: | ||||||
|  |  | ||||||
|         {% if athlete_list and coach_list or cheerleader_list %} |         {% if athlete_list and coach_list or cheerleader_list %} | ||||||
|  |  | ||||||
| @@ -691,8 +705,8 @@ def do_if(parser, token): | |||||||
|     bits = token.contents.split() |     bits = token.contents.split() | ||||||
|     del bits[0] |     del bits[0] | ||||||
|     if not bits: |     if not bits: | ||||||
|         raise TemplateSyntaxError, "'if' statement requires at least one argument" |         raise TemplateSyntaxError("'if' statement requires at least one argument") | ||||||
|     # bits now looks something like this: ['a', 'or', 'not', 'b', 'or', 'c.d'] |     # Bits now looks something like this: ['a', 'or', 'not', 'b', 'or', 'c.d'] | ||||||
|     bitstr = ' '.join(bits) |     bitstr = ' '.join(bits) | ||||||
|     boolpairs = bitstr.split(' and ') |     boolpairs = bitstr.split(' and ') | ||||||
|     boolvars = [] |     boolvars = [] | ||||||
| @@ -727,13 +741,13 @@ do_if = register.tag("if", do_if) | |||||||
| #@register.tag | #@register.tag | ||||||
| def ifchanged(parser, token): | def ifchanged(parser, token): | ||||||
|     """ |     """ | ||||||
|     Check if a value has changed from the last iteration of a loop. |     Checks if a value has changed from the last iteration of a loop. | ||||||
|  |  | ||||||
|     The 'ifchanged' block tag is used within a loop. It has two possible uses. |     The 'ifchanged' block tag is used within a loop. It has two possible uses. | ||||||
|  |  | ||||||
|     1. Checks its own rendered contents against its previous state and only |     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 |        displays the content if it has changed. For example, this displays a | ||||||
|        days, only displaying the month if it changes:: |        list of days, only displaying the month if it changes:: | ||||||
|  |  | ||||||
|             <h1>Archive for {{ year }}</h1> |             <h1>Archive for {{ year }}</h1> | ||||||
|  |  | ||||||
| @@ -742,9 +756,9 @@ def ifchanged(parser, token): | |||||||
|                 <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> |                 <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> | ||||||
|             {% endfor %} |             {% endfor %} | ||||||
|  |  | ||||||
|     2. If given a variable, check whether that variable has changed. For example, the |     2. If given a variable, check whether that variable has changed. | ||||||
|        following shows the date every time it changes, but only shows the hour if both |        For example, the following shows the date every time it changes, but | ||||||
|        the hour and the date have changed:: |        only shows the hour if both the hour and the date have changed:: | ||||||
|  |  | ||||||
|             {% for date in days %} |             {% for date in days %} | ||||||
|                 {% ifchanged date.date %} {{ date.date }} {% endifchanged %} |                 {% ifchanged date.date %} {{ date.date }} {% endifchanged %} | ||||||
| @@ -762,7 +776,7 @@ ifchanged = register.tag(ifchanged) | |||||||
| #@register.tag | #@register.tag | ||||||
| def ssi(parser, token): | def ssi(parser, token): | ||||||
|     """ |     """ | ||||||
|     Output the contents of a given file into the page. |     Outputs the contents of a given file into the page. | ||||||
|  |  | ||||||
|     Like a simple "include" tag, the ``ssi`` tag includes the contents |     Like a simple "include" tag, the ``ssi`` tag includes the contents | ||||||
|     of another file -- which must be specified using an absolute page -- |     of another file -- which must be specified using an absolute page -- | ||||||
| @@ -778,21 +792,24 @@ def ssi(parser, token): | |||||||
|     bits = token.contents.split() |     bits = token.contents.split() | ||||||
|     parsed = False |     parsed = False | ||||||
|     if len(bits) not in (2, 3): |     if len(bits) not in (2, 3): | ||||||
|         raise TemplateSyntaxError, "'ssi' tag takes one argument: the path to the file to be included" |         raise TemplateSyntaxError("'ssi' tag takes one argument: the path to" | ||||||
|  |                                   " the file to be included") | ||||||
|     if len(bits) == 3: |     if len(bits) == 3: | ||||||
|         if bits[2] == 'parsed': |         if bits[2] == 'parsed': | ||||||
|             parsed = True |             parsed = True | ||||||
|         else: |         else: | ||||||
|             raise TemplateSyntaxError, "Second (optional) argument to %s tag must be 'parsed'" % bits[0] |             raise TemplateSyntaxError("Second (optional) argument to %s tag" | ||||||
|  |                                       " must be 'parsed'" % bits[0]) | ||||||
|     return SsiNode(bits[1], parsed) |     return SsiNode(bits[1], parsed) | ||||||
| ssi = register.tag(ssi) | ssi = register.tag(ssi) | ||||||
|  |  | ||||||
| #@register.tag | #@register.tag | ||||||
| def load(parser, token): | def load(parser, token): | ||||||
|     """ |     """ | ||||||
|     Load a custom template tag set. |     Loads a custom template tag set. | ||||||
|  |  | ||||||
|     For example, to load the template tags in ``django/templatetags/news/photos.py``:: |     For example, to load the template tags in | ||||||
|  |     ``django/templatetags/news/photos.py``:: | ||||||
|  |  | ||||||
|         {% load news.photos %} |         {% load news.photos %} | ||||||
|     """ |     """ | ||||||
| @@ -803,14 +820,15 @@ def load(parser, token): | |||||||
|             lib = get_library("django.templatetags.%s" % taglib) |             lib = get_library("django.templatetags.%s" % taglib) | ||||||
|             parser.add_library(lib) |             parser.add_library(lib) | ||||||
|         except InvalidTemplateLibrary, e: |         except InvalidTemplateLibrary, e: | ||||||
|             raise TemplateSyntaxError, "'%s' is not a valid tag library: %s" % (taglib, e) |             raise TemplateSyntaxError("'%s' is not a valid tag library: %s" % | ||||||
|  |                                       (taglib, e)) | ||||||
|     return LoadNode() |     return LoadNode() | ||||||
| load = register.tag(load) | load = register.tag(load) | ||||||
|  |  | ||||||
| #@register.tag | #@register.tag | ||||||
| def now(parser, token): | def now(parser, token): | ||||||
|     """ |     """ | ||||||
|     Display the date, formatted according to the given string. |     Displays the date, formatted according to the given string. | ||||||
|  |  | ||||||
|     Uses the same format as PHP's ``date()`` function; see http://php.net/date |     Uses the same format as PHP's ``date()`` function; see http://php.net/date | ||||||
|     for all the possible values. |     for all the possible values. | ||||||
| @@ -829,7 +847,7 @@ now = register.tag(now) | |||||||
| #@register.tag | #@register.tag | ||||||
| def regroup(parser, token): | def regroup(parser, token): | ||||||
|     """ |     """ | ||||||
|     Regroup a list of alike objects by a common attribute. |     Regroups a list of alike objects by a common attribute. | ||||||
|  |  | ||||||
|     This complex tag is best illustrated by use of an example:  say that |     This complex tag is best illustrated by use of an example:  say that | ||||||
|     ``people`` is a list of ``Person`` objects that have ``first_name``, |     ``people`` is a list of ``Person`` objects that have ``first_name``, | ||||||
| @@ -867,8 +885,8 @@ def regroup(parser, token): | |||||||
|  |  | ||||||
|     Note that `{% regroup %}`` does not work when the list to be grouped is not |     Note that `{% regroup %}`` does not work when the list to be grouped is not | ||||||
|     sorted by the key you are grouping by!  This means that if your list of |     sorted by the key you are grouping by!  This means that if your list of | ||||||
|     people was not sorted by gender, you'd need to make sure it is sorted before |     people was not sorted by gender, you'd need to make sure it is sorted | ||||||
|     using it, i.e.:: |     before using it, i.e.:: | ||||||
|  |  | ||||||
|         {% regroup people|dictsort:"gender" by gender as grouped %} |         {% regroup people|dictsort:"gender" by gender as grouped %} | ||||||
|  |  | ||||||
| @@ -878,10 +896,11 @@ def regroup(parser, token): | |||||||
|         raise TemplateSyntaxError, "'regroup' tag takes five arguments" |         raise TemplateSyntaxError, "'regroup' tag takes five arguments" | ||||||
|     target = parser.compile_filter(firstbits[1]) |     target = parser.compile_filter(firstbits[1]) | ||||||
|     if firstbits[2] != 'by': |     if firstbits[2] != 'by': | ||||||
|         raise TemplateSyntaxError, "second argument to 'regroup' tag must be 'by'" |         raise TemplateSyntaxError("second argument to 'regroup' tag must be 'by'") | ||||||
|     lastbits_reversed = firstbits[3][::-1].split(None, 2) |     lastbits_reversed = firstbits[3][::-1].split(None, 2) | ||||||
|     if lastbits_reversed[1][::-1] != 'as': |     if lastbits_reversed[1][::-1] != 'as': | ||||||
|         raise TemplateSyntaxError, "next-to-last argument to 'regroup' tag must be 'as'" |         raise TemplateSyntaxError("next-to-last argument to 'regroup' tag must" | ||||||
|  |                                   " be 'as'") | ||||||
|  |  | ||||||
|     expression = parser.compile_filter(lastbits_reversed[2][::-1]) |     expression = parser.compile_filter(lastbits_reversed[2][::-1]) | ||||||
|  |  | ||||||
| @@ -891,8 +910,7 @@ regroup = register.tag(regroup) | |||||||
|  |  | ||||||
| def spaceless(parser, token): | def spaceless(parser, token): | ||||||
|     """ |     """ | ||||||
|     Removes whitespace between HTML tags. This includes tab |     Removes whitespace between HTML tags, including tab and newline characters. | ||||||
|     characters and newlines. |  | ||||||
|  |  | ||||||
|     Example usage:: |     Example usage:: | ||||||
|  |  | ||||||
| @@ -906,8 +924,8 @@ def spaceless(parser, token): | |||||||
|  |  | ||||||
|         <p><a href="foo/">Foo</a></p> |         <p><a href="foo/">Foo</a></p> | ||||||
|  |  | ||||||
|     Only space between *tags* is normalized -- not space between tags and text. In |     Only space between *tags* is normalized -- not space between tags and text. | ||||||
|     this example, the space around ``Hello`` won't be stripped:: |     In this example, the space around ``Hello`` won't be stripped:: | ||||||
|  |  | ||||||
|         {% spaceless %} |         {% spaceless %} | ||||||
|             <strong> |             <strong> | ||||||
| @@ -923,7 +941,7 @@ spaceless = register.tag(spaceless) | |||||||
| #@register.tag | #@register.tag | ||||||
| def templatetag(parser, token): | def templatetag(parser, token): | ||||||
|     """ |     """ | ||||||
|     Output one of the bits used to compose template tags. |     Outputs one of the bits used to compose template tags. | ||||||
|  |  | ||||||
|     Since the template system has no concept of "escaping", to display one of |     Since the template system has no concept of "escaping", to display one of | ||||||
|     the bits used in template tags, you must use the ``{% templatetag %}`` tag. |     the bits used in template tags, you must use the ``{% templatetag %}`` tag. | ||||||
| @@ -948,8 +966,9 @@ def templatetag(parser, token): | |||||||
|         raise TemplateSyntaxError, "'templatetag' statement takes one argument" |         raise TemplateSyntaxError, "'templatetag' statement takes one argument" | ||||||
|     tag = bits[1] |     tag = bits[1] | ||||||
|     if tag not in TemplateTagNode.mapping: |     if tag not in TemplateTagNode.mapping: | ||||||
|         raise TemplateSyntaxError, "Invalid templatetag argument: '%s'. Must be one of: %s" % \ |         raise TemplateSyntaxError("Invalid templatetag argument: '%s'." | ||||||
|             (tag, TemplateTagNode.mapping.keys()) |                                   " Must be one of: %s" % | ||||||
|  |                                   (tag, TemplateTagNode.mapping.keys())) | ||||||
|     return TemplateTagNode(tag) |     return TemplateTagNode(tag) | ||||||
| templatetag = register.tag(templatetag) | templatetag = register.tag(templatetag) | ||||||
|  |  | ||||||
| @@ -957,7 +976,8 @@ def url(parser, token): | |||||||
|     """ |     """ | ||||||
|     Returns an absolute URL matching given view with its parameters. |     Returns an absolute URL matching given view with its parameters. | ||||||
|  |  | ||||||
|     This is a way to define links that aren't tied to a particular URL configuration:: |     This is a way to define links that aren't tied to a particular URL | ||||||
|  |     configuration:: | ||||||
|  |  | ||||||
|         {% url path.to.some_view arg1,arg2,name1=value1 %} |         {% url path.to.some_view arg1,arg2,name1=value1 %} | ||||||
|  |  | ||||||
| @@ -985,7 +1005,8 @@ def url(parser, token): | |||||||
|     """ |     """ | ||||||
|     bits = token.contents.split(' ', 2) |     bits = token.contents.split(' ', 2) | ||||||
|     if len(bits) < 2: |     if len(bits) < 2: | ||||||
|         raise TemplateSyntaxError, "'%s' takes at least one argument (path to a view)" % bits[0] |         raise TemplateSyntaxError("'%s' takes at least one argument" | ||||||
|  |                                   " (path to a view)" % bits[0]) | ||||||
|     args = [] |     args = [] | ||||||
|     kwargs = {} |     kwargs = {} | ||||||
|     if len(bits) > 2: |     if len(bits) > 2: | ||||||
| @@ -1010,8 +1031,8 @@ def widthratio(parser, token): | |||||||
|         <img src='bar.gif' height='10' width='{% widthratio this_value max_value 100 %}' /> |         <img src='bar.gif' height='10' width='{% widthratio this_value max_value 100 %}' /> | ||||||
|  |  | ||||||
|     Above, if ``this_value`` is 175 and ``max_value`` is 200, the the image in |     Above, if ``this_value`` is 175 and ``max_value`` is 200, the the image in | ||||||
|     the above example will be 88 pixels wide (because 175/200 = .875; .875 * |     the above example will be 88 pixels wide (because 175/200 = .875; | ||||||
|     100 = 87.5 which is rounded up to 88). |     .875 * 100 = 87.5 which is rounded up to 88). | ||||||
|     """ |     """ | ||||||
|     bits = token.contents.split() |     bits = token.contents.split() | ||||||
|     if len(bits) != 4: |     if len(bits) != 4: | ||||||
| @@ -1028,7 +1049,7 @@ widthratio = register.tag(widthratio) | |||||||
| #@register.tag | #@register.tag | ||||||
| def do_with(parser, token): | def do_with(parser, token): | ||||||
|     """ |     """ | ||||||
|     Add a value to the context (inside of this block) for caching and easy |     Adds a value to the context (inside of this block) for caching and easy | ||||||
|     access. |     access. | ||||||
|  |  | ||||||
|     For example:: |     For example:: | ||||||
| @@ -1039,7 +1060,8 @@ def do_with(parser, token): | |||||||
|     """ |     """ | ||||||
|     bits = list(token.split_contents()) |     bits = list(token.split_contents()) | ||||||
|     if len(bits) != 4 or bits[2] != "as": |     if len(bits) != 4 or bits[2] != "as": | ||||||
|         raise TemplateSyntaxError, "%r expected format is 'value as name'" % bits[0] |         raise TemplateSyntaxError("%r expected format is 'value as name'" % | ||||||
|  |                                   bits[0]) | ||||||
|     var = parser.compile_filter(bits[1]) |     var = parser.compile_filter(bits[1]) | ||||||
|     name = bits[3] |     name = bits[3] | ||||||
|     nodelist = parser.parse(('endwith',)) |     nodelist = parser.parse(('endwith',)) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user