| """Default variable filters.""" |
| |
| import re |
| import random as random_module |
| try: |
| from functools import wraps |
| except ImportError: |
| from django.utils.functional import wraps # Python 2.3, 2.4 fallback. |
| |
| from django.template import Variable, Library |
| from django.conf import settings |
| from django.utils.translation import ugettext, ungettext |
| from django.utils.encoding import force_unicode, iri_to_uri |
| from django.utils.safestring import mark_safe, SafeData |
| |
| register = Library() |
| |
| ####################### |
| # STRING DECORATOR # |
| ####################### |
| |
| def stringfilter(func): |
| """ |
| Decorator for filters which should only receive unicode objects. The object |
| passed as the first positional argument will be converted to a unicode |
| object. |
| """ |
| def _dec(*args, **kwargs): |
| if args: |
| args = list(args) |
| args[0] = force_unicode(args[0]) |
| if isinstance(args[0], SafeData) and getattr(func, 'is_safe', False): |
| return mark_safe(func(*args, **kwargs)) |
| return func(*args, **kwargs) |
| |
| # Include a reference to the real function (used to check original |
| # arguments by the template parser). |
| _dec._decorated_function = getattr(func, '_decorated_function', func) |
| for attr in ('is_safe', 'needs_autoescape'): |
| if hasattr(func, attr): |
| setattr(_dec, attr, getattr(func, attr)) |
| return wraps(func)(_dec) |
| |
| ################### |
| # STRINGS # |
| ################### |
| |
| |
| def addslashes(value): |
| """ |
| Adds slashes before quotes. Useful for escaping strings in CSV, for |
| example. Less useful for escaping JavaScript; use the ``escapejs`` |
| filter instead. |
| """ |
| return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") |
| addslashes.is_safe = True |
| addslashes = stringfilter(addslashes) |
| |
| def capfirst(value): |
| """Capitalizes the first character of the value.""" |
| return value and value[0].upper() + value[1:] |
| capfirst.is_safe=True |
| capfirst = stringfilter(capfirst) |
| |
| _js_escapes = ( |
| ('\\', '\\\\'), |
| ('"', '\\"'), |
| ("'", "\\'"), |
| ('\n', '\\n'), |
| ('\r', '\\r'), |
| ('\b', '\\b'), |
| ('\f', '\\f'), |
| ('\t', '\\t'), |
| ('\v', '\\v'), |
| ('</', '<\\/'), |
| ) |
| def escapejs(value): |
| """Backslash-escapes characters for use in JavaScript strings.""" |
| for bad, good in _js_escapes: |
| value = value.replace(bad, good) |
| return value |
| escapejs = stringfilter(escapejs) |
| |
| def fix_ampersands(value): |
| """Replaces ampersands with ``&`` entities.""" |
| from django.utils.html import fix_ampersands |
| return fix_ampersands(value) |
| fix_ampersands.is_safe=True |
| fix_ampersands = stringfilter(fix_ampersands) |
| |
| def floatformat(text, arg=-1): |
| """ |
| Displays a float to a specified number of decimal places. |
| |
| If called without an argument, it displays the floating point number with |
| one decimal place -- but only if there's a decimal place to be displayed: |
| |
| * num1 = 34.23234 |
| * num2 = 34.00000 |
| * num3 = 34.26000 |
| * {{ num1|floatformat }} displays "34.2" |
| * {{ num2|floatformat }} displays "34" |
| * {{ num3|floatformat }} displays "34.3" |
| |
| If arg is positive, it will always display exactly arg number of decimal |
| places: |
| |
| * {{ num1|floatformat:3 }} displays "34.232" |
| * {{ num2|floatformat:3 }} displays "34.000" |
| * {{ num3|floatformat:3 }} displays "34.260" |
| |
| If arg is negative, it will display arg number of decimal places -- but |
| only if there are places to be displayed: |
| |
| * {{ num1|floatformat:"-3" }} displays "34.232" |
| * {{ num2|floatformat:"-3" }} displays "34" |
| * {{ num3|floatformat:"-3" }} displays "34.260" |
| """ |
| try: |
| f = float(text) |
| except (ValueError, TypeError): |
| return u'' |
| try: |
| d = int(arg) |
| except ValueError: |
| return force_unicode(f) |
| try: |
| m = f - int(f) |
| except OverflowError: |
| return force_unicode(f) |
| if not m and d < 0: |
| return mark_safe(u'%d' % int(f)) |
| else: |
| formatstr = u'%%.%df' % abs(d) |
| return mark_safe(formatstr % f) |
| floatformat.is_safe = True |
| |
| def iriencode(value): |
| """Escapes an IRI value for use in a URL.""" |
| return force_unicode(iri_to_uri(value)) |
| iriencode.is_safe = True |
| iriencode = stringfilter(iriencode) |
| |
| def linenumbers(value, autoescape=None): |
| """Displays text with line numbers.""" |
| from django.utils.html import escape |
| lines = value.split(u'\n') |
| # Find the maximum width of the line count, for use with zero padding |
| # string format command |
| width = unicode(len(unicode(len(lines)))) |
| if not autoescape or isinstance(value, SafeData): |
| for i, line in enumerate(lines): |
| lines[i] = (u"%0" + width + u"d. %s") % (i + 1, line) |
| else: |
| for i, line in enumerate(lines): |
| lines[i] = (u"%0" + width + u"d. %s") % (i + 1, escape(line)) |
| return mark_safe(u'\n'.join(lines)) |
| linenumbers.is_safe = True |
| linenumbers.needs_autoescape = True |
| linenumbers = stringfilter(linenumbers) |
| |
| def lower(value): |
| """Converts a string into all lowercase.""" |
| return value.lower() |
| lower.is_safe = True |
| lower = stringfilter(lower) |
| |
| def make_list(value): |
| """ |
| Returns the value turned into a list. |
| |
| For an integer, it's a list of digits. |
| For a string, it's a list of characters. |
| """ |
| return list(value) |
| make_list.is_safe = False |
| make_list = stringfilter(make_list) |
| |
| def slugify(value): |
| """ |
| Normalizes string, converts to lowercase, removes non-alpha characters, |
| and converts spaces to hyphens. |
| """ |
| import unicodedata |
| value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') |
| value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) |
| return mark_safe(re.sub('[-\s]+', '-', value)) |
| slugify.is_safe = True |
| slugify = stringfilter(slugify) |
| |
| def stringformat(value, arg): |
| """ |
| Formats the variable according to the arg, a string formatting specifier. |
| |
| This specifier uses Python string formating syntax, with the exception that |
| the leading "%" is dropped. |
| |
| See http://docs.python.org/lib/typesseq-strings.html for documentation |
| of Python string formatting |
| """ |
| try: |
| return (u"%" + unicode(arg)) % value |
| except (ValueError, TypeError): |
| return u"" |
| stringformat.is_safe = True |
| |
| def title(value): |
| """Converts a string into titlecase.""" |
| return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title()) |
| title.is_safe = True |
| title = stringfilter(title) |
| |
| def truncatewords(value, arg): |
| """ |
| Truncates a string after a certain number of words. |
| |
| Argument: Number of words to truncate after. |
| """ |
| from django.utils.text import truncate_words |
| try: |
| length = int(arg) |
| except ValueError: # Invalid literal for int(). |
| return value # Fail silently. |
| return truncate_words(value, length) |
| truncatewords.is_safe = True |
| truncatewords = stringfilter(truncatewords) |
| |
| def truncatewords_html(value, arg): |
| """ |
| Truncates HTML after a certain number of words. |
| |
| Argument: Number of words to truncate after. |
| """ |
| from django.utils.text import truncate_html_words |
| try: |
| length = int(arg) |
| except ValueError: # invalid literal for int() |
| return value # Fail silently. |
| return truncate_html_words(value, length) |
| truncatewords_html.is_safe = True |
| truncatewords_html = stringfilter(truncatewords_html) |
| |
| def upper(value): |
| """Converts a string into all uppercase.""" |
| return value.upper() |
| upper.is_safe = False |
| upper = stringfilter(upper) |
| |
| def urlencode(value): |
| """Escapes a value for use in a URL.""" |
| from django.utils.http import urlquote |
| return urlquote(value) |
| urlencode.is_safe = False |
| urlencode = stringfilter(urlencode) |
| |
| def urlize(value, autoescape=None): |
| """Converts URLs in plain text into clickable links.""" |
| from django.utils.html import urlize |
| return mark_safe(urlize(value, nofollow=True, autoescape=autoescape)) |
| urlize.is_safe=True |
| urlize.needs_autoescape = True |
| urlize = stringfilter(urlize) |
| |
| def urlizetrunc(value, limit, autoescape=None): |
| """ |
| Converts URLs into clickable links, truncating URLs to the given character |
| limit, and adding 'rel=nofollow' attribute to discourage spamming. |
| |
| Argument: Length to truncate URLs to. |
| """ |
| from django.utils.html import urlize |
| return mark_safe(urlize(value, trim_url_limit=int(limit), nofollow=True, |
| autoescape=autoescape)) |
| urlizetrunc.is_safe = True |
| urlizetrunc.needs_autoescape = True |
| urlizetrunc = stringfilter(urlizetrunc) |
| |
| def wordcount(value): |
| """Returns the number of words.""" |
| return len(value.split()) |
| wordcount.is_safe = False |
| wordcount = stringfilter(wordcount) |
| |
| def wordwrap(value, arg): |
| """ |
| Wraps words at specified line length. |
| |
| Argument: number of characters to wrap the text at. |
| """ |
| from django.utils.text import wrap |
| return wrap(value, int(arg)) |
| wordwrap.is_safe = True |
| wordwrap = stringfilter(wordwrap) |
| |
| def ljust(value, arg): |
| """ |
| Left-aligns the value in a field of a given width. |
| |
| Argument: field size. |
| """ |
| return value.ljust(int(arg)) |
| ljust.is_safe = True |
| ljust = stringfilter(ljust) |
| |
| def rjust(value, arg): |
| """ |
| Right-aligns the value in a field of a given width. |
| |
| Argument: field size. |
| """ |
| return value.rjust(int(arg)) |
| rjust.is_safe = True |
| rjust = stringfilter(rjust) |
| |
| def center(value, arg): |
| """Centers the value in a field of a given width.""" |
| return value.center(int(arg)) |
| center.is_safe = True |
| center = stringfilter(center) |
| |
| def cut(value, arg): |
| """ |
| Removes all values of arg from the given string. |
| """ |
| safe = isinstance(value, SafeData) |
| value = value.replace(arg, u'') |
| if safe and arg != ';': |
| return mark_safe(value) |
| return value |
| cut = stringfilter(cut) |
| |
| ################### |
| # HTML STRINGS # |
| ################### |
| |
| def escape(value): |
| """ |
| Marks the value as a string that should not be auto-escaped. |
| """ |
| from django.utils.safestring import mark_for_escaping |
| return mark_for_escaping(value) |
| escape.is_safe = True |
| escape = stringfilter(escape) |
| |
| def force_escape(value): |
| """ |
| Escapes a string's HTML. This returns a new string containing the escaped |
| characters (as opposed to "escape", which marks the content for later |
| possible escaping). |
| """ |
| from django.utils.html import escape |
| return mark_safe(escape(value)) |
| force_escape = stringfilter(force_escape) |
| force_escape.is_safe = True |
| |
| def linebreaks(value, autoescape=None): |
| """ |
| Replaces line breaks in plain text with appropriate HTML; a single |
| newline becomes an HTML line break (``<br />``) and a new line |
| followed by a blank line becomes a paragraph break (``</p>``). |
| """ |
| from django.utils.html import linebreaks |
| autoescape = autoescape and not isinstance(value, SafeData) |
| return mark_safe(linebreaks(value, autoescape)) |
| linebreaks.is_safe = True |
| linebreaks.needs_autoescape = True |
| linebreaks = stringfilter(linebreaks) |
| |
| def linebreaksbr(value, autoescape=None): |
| """ |
| Converts all newlines in a piece of plain text to HTML line breaks |
| (``<br />``). |
| """ |
| if autoescape and not isinstance(value, SafeData): |
| from django.utils.html import escape |
| value = escape(value) |
| return mark_safe(value.replace('\n', '<br />')) |
| linebreaksbr.is_safe = True |
| linebreaksbr.needs_autoescape = True |
| linebreaksbr = stringfilter(linebreaksbr) |
| |
| def safe(value): |
| """ |
| Marks the value as a string that should not be auto-escaped. |
| """ |
| from django.utils.safestring import mark_safe |
| return mark_safe(value) |
| safe.is_safe = True |
| safe = stringfilter(safe) |
| |
| def removetags(value, tags): |
| """Removes a space separated list of [X]HTML tags from the output.""" |
| tags = [re.escape(tag) for tag in tags.split()] |
| tags_re = u'(%s)' % u'|'.join(tags) |
| starttag_re = re.compile(ur'<%s(/?>|(\s+[^>]*>))' % tags_re, re.U) |
| endtag_re = re.compile(u'</%s>' % tags_re) |
| value = starttag_re.sub(u'', value) |
| value = endtag_re.sub(u'', value) |
| return value |
| removetags.is_safe = True |
| removetags = stringfilter(removetags) |
| |
| def striptags(value): |
| """Strips all [X]HTML tags.""" |
| from django.utils.html import strip_tags |
| return strip_tags(value) |
| striptags.is_safe = True |
| striptags = stringfilter(striptags) |
| |
| ################### |
| # LISTS # |
| ################### |
| |
| def dictsort(value, arg): |
| """ |
| Takes a list of dicts, returns that list sorted by the property given in |
| the argument. |
| """ |
| var_resolve = Variable(arg).resolve |
| decorated = [(var_resolve(item), item) for item in value] |
| decorated.sort() |
| return [item[1] for item in decorated] |
| dictsort.is_safe = False |
| |
| def dictsortreversed(value, arg): |
| """ |
| Takes a list of dicts, returns that list sorted in reverse order by the |
| property given in the argument. |
| """ |
| var_resolve = Variable(arg).resolve |
| decorated = [(var_resolve(item), item) for item in value] |
| decorated.sort() |
| decorated.reverse() |
| return [item[1] for item in decorated] |
| dictsortreversed.is_safe = False |
| |
| def first(value): |
| """Returns the first item in a list.""" |
| try: |
| return value[0] |
| except IndexError: |
| return u'' |
| first.is_safe = False |
| |
| def join(value, arg): |
| """Joins a list with a string, like Python's ``str.join(list)``.""" |
| try: |
| data = arg.join(map(force_unicode, value)) |
| except AttributeError: # fail silently but nicely |
| return value |
| safe_args = reduce(lambda lhs, rhs: lhs and isinstance(rhs, SafeData), |
| value, True) |
| if safe_args: |
| return mark_safe(data) |
| else: |
| return data |
| join.is_safe = True |
| |
| def last(value): |
| "Returns the last item in a list" |
| try: |
| return value[-1] |
| except IndexError: |
| return u'' |
| last.is_safe = True |
| |
| def length(value): |
| """Returns the length of the value - useful for lists.""" |
| return len(value) |
| length.is_safe = True |
| |
| def length_is(value, arg): |
| """Returns a boolean of whether the value's length is the argument.""" |
| return len(value) == int(arg) |
| length_is.is_safe = True |
| |
| def random(value): |
| """Returns a random item from the list.""" |
| return random_module.choice(value) |
| random.is_safe = True |
| |
| def slice_(value, arg): |
| """ |
| Returns a slice of the list. |
| |
| Uses the same syntax as Python's list slicing; see |
| http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice |
| for an introduction. |
| """ |
| try: |
| bits = [] |
| for x in arg.split(u':'): |
| if len(x) == 0: |
| bits.append(None) |
| else: |
| bits.append(int(x)) |
| return value[slice(*bits)] |
| |
| except (ValueError, TypeError): |
| return value # Fail silently. |
| slice_.is_safe = True |
| |
| def unordered_list(value, autoescape=None): |
| """ |
| Recursively takes a self-nested list and returns an HTML unordered list -- |
| WITHOUT opening and closing <ul> tags. |
| |
| The list is assumed to be in the proper format. For example, if ``var`` |
| contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``, |
| then ``{{ var|unordered_list }}`` would return:: |
| |
| <li>States |
| <ul> |
| <li>Kansas |
| <ul> |
| <li>Lawrence</li> |
| <li>Topeka</li> |
| </ul> |
| </li> |
| <li>Illinois</li> |
| </ul> |
| </li> |
| """ |
| if autoescape: |
| from django.utils.html import conditional_escape |
| escaper = conditional_escape |
| else: |
| escaper = lambda x: x |
| def convert_old_style_list(list_): |
| """ |
| Converts old style lists to the new easier to understand format. |
| |
| The old list format looked like: |
| ['Item 1', [['Item 1.1', []], ['Item 1.2', []]] |
| |
| And it is converted to: |
| ['Item 1', ['Item 1.1', 'Item 1.2]] |
| """ |
| if not isinstance(list_, (tuple, list)) or len(list_) != 2: |
| return list_, False |
| first_item, second_item = list_ |
| if second_item == []: |
| return [first_item], True |
| old_style_list = True |
| new_second_item = [] |
| for sublist in second_item: |
| item, old_style_list = convert_old_style_list(sublist) |
| if not old_style_list: |
| break |
| new_second_item.extend(item) |
| if old_style_list: |
| second_item = new_second_item |
| return [first_item, second_item], old_style_list |
| def _helper(list_, tabs=1): |
| indent = u'\t' * tabs |
| output = [] |
| |
| list_length = len(list_) |
| i = 0 |
| while i < list_length: |
| title = list_[i] |
| sublist = '' |
| sublist_item = None |
| if isinstance(title, (list, tuple)): |
| sublist_item = title |
| title = '' |
| elif i < list_length - 1: |
| next_item = list_[i+1] |
| if next_item and isinstance(next_item, (list, tuple)): |
| # The next item is a sub-list. |
| sublist_item = next_item |
| # We've processed the next item now too. |
| i += 1 |
| if sublist_item: |
| sublist = _helper(sublist_item, tabs+1) |
| sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist, |
| indent, indent) |
| output.append('%s<li>%s%s</li>' % (indent, |
| escaper(force_unicode(title)), sublist)) |
| i += 1 |
| return '\n'.join(output) |
| value, converted = convert_old_style_list(value) |
| return mark_safe(_helper(value)) |
| unordered_list.is_safe = True |
| unordered_list.needs_autoescape = True |
| |
| ################### |
| # INTEGERS # |
| ################### |
| |
| def add(value, arg): |
| """Adds the arg to the value.""" |
| return int(value) + int(arg) |
| add.is_safe = False |
| |
| def get_digit(value, arg): |
| """ |
| Given a whole number, returns the requested digit of it, where 1 is the |
| right-most digit, 2 is the second-right-most digit, etc. Returns the |
| original value for invalid input (if input or argument is not an integer, |
| or if argument is less than 1). Otherwise, output is always an integer. |
| """ |
| try: |
| arg = int(arg) |
| value = int(value) |
| except ValueError: |
| return value # Fail silently for an invalid argument |
| if arg < 1: |
| return value |
| try: |
| return int(str(value)[-arg]) |
| except IndexError: |
| return 0 |
| get_digit.is_safe = False |
| |
| ################### |
| # DATES # |
| ################### |
| |
| def date(value, arg=None): |
| """Formats a date according to the given format.""" |
| from django.utils.dateformat import format |
| if not value: |
| return u'' |
| if arg is None: |
| arg = settings.DATE_FORMAT |
| return format(value, arg) |
| date.is_safe = False |
| |
| def time(value, arg=None): |
| """Formats a time according to the given format.""" |
| from django.utils.dateformat import time_format |
| if value in (None, u''): |
| return u'' |
| if arg is None: |
| arg = settings.TIME_FORMAT |
| return time_format(value, arg) |
| time.is_safe = False |
| |
| def timesince(value, arg=None): |
| """Formats a date as the time since that date (i.e. "4 days, 6 hours").""" |
| from django.utils.timesince import timesince |
| if not value: |
| return u'' |
| if arg: |
| return timesince(value, arg) |
| return timesince(value) |
| timesince.is_safe = False |
| |
| def timeuntil(value, arg=None): |
| """Formats a date as the time until that date (i.e. "4 days, 6 hours").""" |
| from django.utils.timesince import timesince |
| from datetime import datetime |
| if not value: |
| return u'' |
| if arg: |
| return timesince(arg, value) |
| return timesince(datetime.now(), value) |
| timeuntil.is_safe = False |
| |
| ################### |
| # LOGIC # |
| ################### |
| |
| def default(value, arg): |
| """If value is unavailable, use given default.""" |
| return value or arg |
| default.is_safe = False |
| |
| def default_if_none(value, arg): |
| """If value is None, use given default.""" |
| if value is None: |
| return arg |
| return value |
| default_if_none.is_safe = False |
| |
| def divisibleby(value, arg): |
| """Returns True if the value is devisible by the argument.""" |
| return int(value) % int(arg) == 0 |
| divisibleby.is_safe = False |
| |
| def yesno(value, arg=None): |
| """ |
| Given a string mapping values for true, false and (optionally) None, |
| returns one of those strings accoding to the value: |
| |
| ========== ====================== ================================== |
| Value Argument Outputs |
| ========== ====================== ================================== |
| ``True`` ``"yeah,no,maybe"`` ``yeah`` |
| ``False`` ``"yeah,no,maybe"`` ``no`` |
| ``None`` ``"yeah,no,maybe"`` ``maybe`` |
| ``None`` ``"yeah,no"`` ``"no"`` (converts None to False |
| if no mapping for None is given. |
| ========== ====================== ================================== |
| """ |
| if arg is None: |
| arg = ugettext('yes,no,maybe') |
| bits = arg.split(u',') |
| if len(bits) < 2: |
| return value # Invalid arg. |
| try: |
| yes, no, maybe = bits |
| except ValueError: |
| # Unpack list of wrong size (no "maybe" value provided). |
| yes, no, maybe = bits[0], bits[1], bits[1] |
| if value is None: |
| return maybe |
| if value: |
| return yes |
| return no |
| yesno.is_safe = False |
| |
| ################### |
| # MISC # |
| ################### |
| |
| def filesizeformat(bytes): |
| """ |
| Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, |
| 102 bytes, etc). |
| """ |
| try: |
| bytes = float(bytes) |
| except TypeError: |
| return u"0 bytes" |
| |
| if bytes < 1024: |
| return ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes} |
| if bytes < 1024 * 1024: |
| return ugettext("%.1f KB") % (bytes / 1024) |
| if bytes < 1024 * 1024 * 1024: |
| return ugettext("%.1f MB") % (bytes / (1024 * 1024)) |
| return ugettext("%.1f GB") % (bytes / (1024 * 1024 * 1024)) |
| filesizeformat.is_safe = True |
| |
| def pluralize(value, arg=u's'): |
| """ |
| Returns a plural suffix if the value is not 1. By default, 's' is used as |
| the suffix: |
| |
| * If value is 0, vote{{ value|pluralize }} displays "0 votes". |
| * If value is 1, vote{{ value|pluralize }} displays "1 vote". |
| * If value is 2, vote{{ value|pluralize }} displays "2 votes". |
| |
| If an argument is provided, that string is used instead: |
| |
| * If value is 0, class{{ value|pluralize:"es" }} displays "0 classes". |
| * If value is 1, class{{ value|pluralize:"es" }} displays "1 class". |
| * If value is 2, class{{ value|pluralize:"es" }} displays "2 classes". |
| |
| If the provided argument contains a comma, the text before the comma is |
| used for the singular case and the text after the comma is used for the |
| plural case: |
| |
| * If value is 0, cand{{ value|pluralize:"y,ies" }} displays "0 candies". |
| * If value is 1, cand{{ value|pluralize:"y,ies" }} displays "1 candy". |
| * If value is 2, cand{{ value|pluralize:"y,ies" }} displays "2 candies". |
| """ |
| if not u',' in arg: |
| arg = u',' + arg |
| bits = arg.split(u',') |
| if len(bits) > 2: |
| return u'' |
| singular_suffix, plural_suffix = bits[:2] |
| |
| try: |
| if int(value) != 1: |
| return plural_suffix |
| except ValueError: # Invalid string that's not a number. |
| pass |
| except TypeError: # Value isn't a string or a number; maybe it's a list? |
| try: |
| if len(value) != 1: |
| return plural_suffix |
| except TypeError: # len() of unsized object. |
| pass |
| return singular_suffix |
| pluralize.is_safe = False |
| |
| def phone2numeric(value): |
| """Takes a phone number and converts it in to its numerical equivalent.""" |
| from django.utils.text import phone2numeric |
| return phone2numeric(value) |
| phone2numeric.is_safe = True |
| |
| def pprint(value): |
| """A wrapper around pprint.pprint -- for debugging, really.""" |
| from pprint import pformat |
| try: |
| return pformat(value) |
| except Exception, e: |
| return u"Error in formatting: %s" % force_unicode(e, errors="replace") |
| pprint.is_safe = True |
| |
| # Syntax: register.filter(name of filter, callback) |
| register.filter(add) |
| register.filter(addslashes) |
| register.filter(capfirst) |
| register.filter(center) |
| register.filter(cut) |
| register.filter(date) |
| register.filter(default) |
| register.filter(default_if_none) |
| register.filter(dictsort) |
| register.filter(dictsortreversed) |
| register.filter(divisibleby) |
| register.filter(escape) |
| register.filter(escapejs) |
| register.filter(filesizeformat) |
| register.filter(first) |
| register.filter(fix_ampersands) |
| register.filter(floatformat) |
| register.filter(force_escape) |
| register.filter(get_digit) |
| register.filter(iriencode) |
| register.filter(join) |
| register.filter(last) |
| register.filter(length) |
| register.filter(length_is) |
| register.filter(linebreaks) |
| register.filter(linebreaksbr) |
| register.filter(linenumbers) |
| register.filter(ljust) |
| register.filter(lower) |
| register.filter(make_list) |
| register.filter(phone2numeric) |
| register.filter(pluralize) |
| register.filter(pprint) |
| register.filter(removetags) |
| register.filter(random) |
| register.filter(rjust) |
| register.filter(safe) |
| register.filter('slice', slice_) |
| register.filter(slugify) |
| register.filter(stringformat) |
| register.filter(striptags) |
| register.filter(time) |
| register.filter(timesince) |
| register.filter(timeuntil) |
| register.filter(title) |
| register.filter(truncatewords) |
| register.filter(truncatewords_html) |
| register.filter(unordered_list) |
| register.filter(upper) |
| register.filter(urlencode) |
| register.filter(urlize) |
| register.filter(urlizetrunc) |
| register.filter(wordcount) |
| register.filter(wordwrap) |
| register.filter(yesno) |