1
"Default variable filters"
3
from django.core.template import resolve_variable, Library
4
from django.conf.settings import DATE_FORMAT, TIME_FORMAT
5
from django.utils.translation import gettext
7
import random as random_module
16
def addslashes(value):
17
"Adds slashes - useful for passing strings to JavaScript, for example."
18
return value.replace('"', '\\"').replace("'", "\\'")
21
"Capitalizes the first character of the value"
23
return value and value[0].upper() + value[1:]
25
def fix_ampersands(value):
26
"Replaces ampersands with ``&`` entities"
27
from django.utils.html import fix_ampersands
28
return fix_ampersands(value)
30
def floatformat(text):
32
Displays a floating point number as 34.2 (with one decimal place) -- but
33
only if there's a point to be displayed
45
def linenumbers(value):
46
"Displays text with line numbers"
47
from django.utils.html import escape
48
lines = value.split('\n')
49
# Find the maximum width of the line count, for use with zero padding string format command
50
width = str(len(str(len(lines))))
51
for i, line in enumerate(lines):
52
lines[i] = ("%0" + width + "d. %s") % (i + 1, escape(line))
53
return '\n'.join(lines)
56
"Converts a string into all lowercase"
61
Returns the value turned into a list. For an integer, it's a list of
62
digits. For a string, it's a list of characters.
64
return list(str(value))
67
"Converts to lowercase, removes non-alpha chars and converts spaces to hyphens"
68
value = re.sub('[^\w\s-]', '', value).strip().lower()
69
return re.sub('\s+', '-', value)
71
def stringformat(value, arg):
73
Formats the variable according to the argument, a string formatting specifier.
74
This specifier uses Python string formating syntax, with the exception that
75
the leading "%" is dropped.
77
See http://docs.python.org/lib/typesseq-strings.html for documentation
78
of Python string formatting
81
return ("%" + arg) % value
82
except (ValueError, TypeError):
86
"Converts a string into titlecase"
87
return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title())
89
def truncatewords(value, arg):
91
Truncates a string after a certain number of words
93
Argument: Number of words to truncate after
95
from django.utils.text import truncate_words
98
except ValueError: # invalid literal for int()
99
return value # Fail silently.
100
if not isinstance(value, basestring):
102
return truncate_words(value, length)
105
"Converts a string into all uppercase"
108
def urlencode(value):
109
"Escapes a value for use in a URL"
111
return urllib.quote(value)
114
"Converts URLs in plain text into clickable links"
115
from django.utils.html import urlize
116
return urlize(value, nofollow=True)
118
def urlizetrunc(value, limit):
120
Converts URLs into clickable links, truncating URLs to the given character limit,
121
and adding 'rel=nofollow' attribute to discourage spamming.
123
Argument: Length to truncate URLs to.
125
from django.utils.html import urlize
126
return urlize(value, trim_url_limit=int(limit), nofollow=True)
128
def wordcount(value):
129
"Returns the number of words"
130
return len(value.split())
132
def wordwrap(value, arg):
134
Wraps words at specified line length
136
Argument: number of characters at which to wrap the text
138
from django.utils.text import wrap
139
return wrap(str(value), int(arg))
141
def ljust(value, arg):
143
Left-aligns the value in a field of a given width
147
return str(value).ljust(int(arg))
149
def rjust(value, arg):
151
Right-aligns the value in a field of a given width
155
return str(value).rjust(int(arg))
157
def center(value, arg):
158
"Centers the value in a field of a given width"
159
return str(value).center(int(arg))
162
"Removes all values of arg from the given string"
163
return value.replace(arg, '')
170
"Escapes a string's HTML"
171
from django.utils.html import escape
174
def linebreaks(value):
175
"Converts newlines into <p> and <br />s"
176
from django.utils.html import linebreaks
177
return linebreaks(value)
179
def linebreaksbr(value):
180
"Converts newlines into <br />s"
181
return value.replace('\n', '<br />')
183
def removetags(value, tags):
184
"Removes a space separated list of [X]HTML tags from the output"
185
tags = [re.escape(tag) for tag in tags.split()]
186
tags_re = '(%s)' % '|'.join(tags)
187
starttag_re = re.compile(r'<%s(/?>|(\s+[^>]*>))' % tags_re)
188
endtag_re = re.compile('</%s>' % tags_re)
189
value = starttag_re.sub('', value)
190
value = endtag_re.sub('', value)
193
def striptags(value):
194
"Strips all [X]HTML tags"
195
from django.utils.html import strip_tags
196
if not isinstance(value, basestring):
198
return strip_tags(value)
204
def dictsort(value, arg):
206
Takes a list of dicts, returns that list sorted by the property given in
209
decorated = [(resolve_variable('var.' + arg, {'var' : item}), item) for item in value]
211
return [item[1] for item in decorated]
213
def dictsortreversed(value, arg):
215
Takes a list of dicts, returns that list sorted in reverse order by the
216
property given in the argument.
218
decorated = [(resolve_variable('var.' + arg, {'var' : item}), item) for item in value]
221
return [item[1] for item in decorated]
224
"Returns the first item in a list"
230
def join(value, arg):
231
"Joins a list with a string, like Python's ``str.join(list)``"
233
return arg.join(map(str, value))
234
except AttributeError: # fail silently but nicely
238
"Returns the length of the value - useful for lists"
241
def length_is(value, arg):
242
"Returns a boolean of whether the value's length is the argument"
243
return len(value) == int(arg)
246
"Returns a random item from the list"
247
return random_module.choice(value)
249
def slice_(value, arg):
251
Returns a slice of the list.
253
Uses the same syntax as Python's list slicing; see
254
http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
259
for x in arg.split(':'):
264
return value[slice(*bits)]
266
except (ValueError, TypeError):
267
return value # Fail silently.
269
def unordered_list(value):
271
Recursively takes a self-nested list and returns an HTML unordered list --
272
WITHOUT opening and closing <ul> tags.
274
The list is assumed to be in the proper format. For example, if ``var`` contains
275
``['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]``,
276
then ``{{ var|unordered_list }}`` would return::
290
def _helper(value, tabs):
293
return '%s<li>%s\n%s<ul>\n%s\n%s</ul>\n%s</li>' % (indent, value[0], indent,
294
'\n'.join([_helper(v, tabs+1) for v in value[1]]), indent, indent)
296
return '%s<li>%s</li>' % (indent, value[0])
297
return _helper(value, 1)
304
"Adds the arg to the value"
305
return int(value) + int(arg)
307
def get_digit(value, arg):
309
Given a whole number, returns the requested digit of it, where 1 is the
310
right-most digit, 2 is the second-right-most digit, etc. Returns the
311
original value for invalid input (if input or argument is not an integer,
312
or if argument is less than 1). Otherwise, output is always an integer.
318
return value # Fail silently for an invalid argument
322
return int(str(value)[-arg])
330
def date(value, arg=DATE_FORMAT):
331
"Formats a date according to the given format"
332
from django.utils.dateformat import format
333
return format(value, arg)
335
def time(value, arg=TIME_FORMAT):
336
"Formats a time according to the given format"
337
from django.utils.dateformat import time_format
338
return time_format(value, arg)
340
def timesince(value):
341
'Formats a date as the time since that date (i.e. "4 days, 6 hours")'
342
from django.utils.timesince import timesince
343
return timesince(value)
349
def default(value, arg):
350
"If value is unavailable, use given default"
353
def default_if_none(value, arg):
354
"If value is None, use given default"
359
def divisibleby(value, arg):
360
"Returns true if the value is devisible by the argument"
361
return int(value) % int(arg) == 0
363
def yesno(value, arg=None):
365
Given a string mapping values for true, false and (optionally) None,
366
returns one of those strings accoding to the value:
368
========== ====================== ==================================
369
Value Argument Outputs
370
========== ====================== ==================================
371
``True`` ``"yeah,no,maybe"`` ``yeah``
372
``False`` ``"yeah,no,maybe"`` ``no``
373
``None`` ``"yeah,no,maybe"`` ``maybe``
374
``None`` ``"yeah,no"`` ``"no"`` (converts None to False
375
if no mapping for None is given.
376
========== ====================== ==================================
379
arg = gettext('yes,no,maybe')
380
bits = arg.split(',')
382
return value # Invalid arg.
384
yes, no, maybe = bits
385
except ValueError: # unpack list of wrong size (no "maybe" value provided)
386
yes, no, maybe = bits[0], bits[1], bits[1]
397
def filesizeformat(bytes):
399
Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102
404
return "%d byte%s" % (bytes, bytes != 1 and 's' or '')
405
if bytes < 1024 * 1024:
406
return "%.1f KB" % (bytes / 1024)
407
if bytes < 1024 * 1024 * 1024:
408
return "%.1f MB" % (bytes / (1024 * 1024))
409
return "%.1f GB" % (bytes / (1024 * 1024 * 1024))
411
def pluralize(value):
412
"Returns 's' if the value is not 1, for '1 vote' vs. '2 votes'"
416
except ValueError: # invalid string that's not a number
418
except TypeError: # value isn't a string or a number; maybe it's a list?
422
except TypeError: # len() of unsized object
426
def phone2numeric(value):
427
"Takes a phone number and converts it in to its numerical equivalent"
428
from django.utils.text import phone2numeric
429
return phone2numeric(value)
432
"A wrapper around pprint.pprint -- for debugging, really"
433
from pprint import pformat
434
return pformat(value)
436
# Syntax: register.filter(name of filter, callback)
438
register.filter(addslashes)
439
register.filter(capfirst)
440
register.filter(center)
442
register.filter(date)
443
register.filter(default)
444
register.filter(default_if_none)
445
register.filter(dictsort)
446
register.filter(dictsortreversed)
447
register.filter(divisibleby)
448
register.filter(escape)
449
register.filter(filesizeformat)
450
register.filter(first)
451
register.filter(fix_ampersands)
452
register.filter(floatformat)
453
register.filter(get_digit)
454
register.filter(join)
455
register.filter(length)
456
register.filter(length_is)
457
register.filter(linebreaks)
458
register.filter(linebreaksbr)
459
register.filter(linenumbers)
460
register.filter(ljust)
461
register.filter(lower)
462
register.filter(make_list)
463
register.filter(phone2numeric)
464
register.filter(pluralize)
465
register.filter(pprint)
466
register.filter(removetags)
467
register.filter(random)
468
register.filter(rjust)
469
register.filter('slice', slice_)
470
register.filter(slugify)
471
register.filter(stringformat)
472
register.filter(striptags)
473
register.filter(time)
474
register.filter(timesince)
475
register.filter(title)
476
register.filter(truncatewords)
477
register.filter(unordered_list)
478
register.filter(upper)
479
register.filter(urlencode)
480
register.filter(urlize)
481
register.filter(urlizetrunc)
482
register.filter(wordcount)
483
register.filter(wordwrap)
484
register.filter(yesno)