Changeset 4558
- Timestamp:
- 02/23/07 12:02:51 (2 years ago)
- Files:
-
- django/trunk/django/template/defaultfilters.py (modified) (20 diffs)
- django/trunk/django/template/__init__.py (modified) (1 diff)
- django/trunk/docs/templates_python.txt (modified) (1 diff)
- django/trunk/tests/regressiontests/defaultfilters/tests.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/template/defaultfilters.py
r4496 r4558 9 9 register = Library() 10 10 11 ####################### 12 # STRING DECORATOR # 13 ####################### 14 15 def smart_string(obj): 16 # FUTURE: Unicode strings should probably be normalized to a specific 17 # encoding and non-unicode strings should be converted to unicode too. 18 # if isinstance(obj, unicode): 19 # obj = obj.encode(settings.DEFAULT_CHARSET) 20 # else: 21 # obj = unicode(obj, settings.DEFAULT_CHARSET) 22 # FUTURE: Replace dumb string logic below with cool unicode logic above. 23 if not isinstance(obj, basestring): 24 obj = str(obj) 25 return obj 26 27 def stringfilter(func): 28 """ 29 Decorator for filters which should only receive strings. The object passed 30 as the first positional argument will be converted to a string. 31 """ 32 def _dec(*args, **kwargs): 33 if args: 34 args = list(args) 35 args[0] = smart_string(args[0]) 36 return func(*args, **kwargs) 37 38 # Make sure the internal name is the original function name because this 39 # is the internal name of the filter if passed directly to Library().filter 40 _dec.__name__ = func.__name__ 41 42 # Include a reference to the real function (used to check original 43 # arguments by the template parser). 44 _dec._decorated_function = getattr(func, '_decorated_function', func) 45 return _dec 46 11 47 ################### 12 48 # STRINGS # … … 17 53 "Adds slashes - useful for passing strings to JavaScript, for example." 18 54 return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") 55 addslashes = stringfilter(addslashes) 19 56 20 57 def capfirst(value): 21 58 "Capitalizes the first character of the value" 22 value = str(value)23 59 return value and value[0].upper() + value[1:] 24 60 capfirst = stringfilter(capfirst) 61 25 62 def fix_ampersands(value): 26 63 "Replaces ampersands with ``&`` entities" 27 64 from django.utils.html import fix_ampersands 28 65 return fix_ampersands(value) 66 fix_ampersands = stringfilter(fix_ampersands) 29 67 30 68 def floatformat(text, arg=-1): … … 53 91 d = int(arg) 54 92 except ValueError: 55 return s tr(f)93 return smart_string(f) 56 94 m = f - int(f) 57 95 if not m and d < 0: … … 70 108 lines[i] = ("%0" + width + "d. %s") % (i + 1, escape(line)) 71 109 return '\n'.join(lines) 110 linenumbers = stringfilter(linenumbers) 72 111 73 112 def lower(value): 74 113 "Converts a string into all lowercase" 75 114 return value.lower() 115 lower = stringfilter(lower) 76 116 77 117 def make_list(value): … … 80 120 digits. For a string, it's a list of characters. 81 121 """ 82 return list(str(value)) 122 return list(value) 123 make_list = stringfilter(make_list) 83 124 84 125 def slugify(value): … … 86 127 value = re.sub('[^\w\s-]', '', value).strip().lower() 87 128 return re.sub('[-\s]+', '-', value) 129 slugify = stringfilter(slugify) 88 130 89 131 def stringformat(value, arg): … … 97 139 """ 98 140 try: 99 return ("%" + arg) % value141 return ("%" + str(arg)) % value 100 142 except (ValueError, TypeError): 101 143 return "" … … 104 146 "Converts a string into titlecase" 105 147 return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title()) 148 title = stringfilter(title) 106 149 107 150 def truncatewords(value, arg): … … 119 162 value = str(value) 120 163 return truncate_words(value, length) 164 truncatewords = stringfilter(truncatewords) 121 165 122 166 def truncatewords_html(value, arg): … … 134 178 value = str(value) 135 179 return truncate_html_words(value, length) 180 truncatewords_html = stringfilter(truncatewords_html) 136 181 137 182 def upper(value): 138 183 "Converts a string into all uppercase" 139 184 return value.upper() 185 upper = stringfilter(upper) 140 186 141 187 def urlencode(value): … … 145 191 value = str(value) 146 192 return urllib.quote(value) 193 urlencode = stringfilter(urlencode) 147 194 148 195 def urlize(value): … … 150 197 from django.utils.html import urlize 151 198 return urlize(value, nofollow=True) 199 urlize = stringfilter(urlize) 152 200 153 201 def urlizetrunc(value, limit): … … 160 208 from django.utils.html import urlize 161 209 return urlize(value, trim_url_limit=int(limit), nofollow=True) 210 urlizetrunc = stringfilter(urlizetrunc) 162 211 163 212 def wordcount(value): 164 213 "Returns the number of words" 165 214 return len(value.split()) 215 wordcount = stringfilter(wordcount) 166 216 167 217 def wordwrap(value, arg): … … 172 222 """ 173 223 from django.utils.text import wrap 174 return wrap(str(value), int(arg)) 224 return wrap(value, int(arg)) 225 wordwrap = stringfilter(wordwrap) 175 226 176 227 def ljust(value, arg): … … 180 231 Argument: field size 181 232 """ 182 return str(value).ljust(int(arg)) 233 return value.ljust(int(arg)) 234 ljust = stringfilter(ljust) 183 235 184 236 def rjust(value, arg): … … 188 240 Argument: field size 189 241 """ 190 return str(value).rjust(int(arg)) 242 return value.rjust(int(arg)) 243 rjust = stringfilter(rjust) 191 244 192 245 def center(value, arg): 193 246 "Centers the value in a field of a given width" 194 return str(value).center(int(arg)) 247 return value.center(int(arg)) 248 center = stringfilter(center) 195 249 196 250 def cut(value, arg): 197 251 "Removes all values of arg from the given string" 198 252 return value.replace(arg, '') 253 cut = stringfilter(cut) 199 254 200 255 ################### … … 206 261 from django.utils.html import escape 207 262 return escape(value) 263 escape = stringfilter(escape) 208 264 209 265 def linebreaks(value): … … 211 267 from django.utils.html import linebreaks 212 268 return linebreaks(value) 269 linebreaks = stringfilter(linebreaks) 213 270 214 271 def linebreaksbr(value): 215 272 "Converts newlines into <br />s" 216 273 return value.replace('\n', '<br />') 274 linebreaksbr = stringfilter(linebreaksbr) 217 275 218 276 def removetags(value, tags): … … 225 283 value = endtag_re.sub('', value) 226 284 return value 285 removetags = stringfilter(removetags) 227 286 228 287 def striptags(value): 229 288 "Strips all [X]HTML tags" 230 289 from django.utils.html import strip_tags 231 if not isinstance(value, basestring):232 value = str(value)233 290 return strip_tags(value) 291 striptags = stringfilter(striptags) 234 292 235 293 ################### … … 266 324 "Joins a list with a string, like Python's ``str.join(list)``" 267 325 try: 268 return arg.join(map(s tr, value))326 return arg.join(map(smart_string, value)) 269 327 except AttributeError: # fail silently but nicely 270 328 return value django/trunk/django/template/__init__.py
r4465 r4558 581 581 provided = list(provided) 582 582 plen = len(provided) 583 # Check to see if a decorator is providing the real function. 584 func = getattr(func, '_decorated_function', func) 583 585 args, varargs, varkw, defaults = getargspec(func) 584 586 # First argument is filter input. django/trunk/docs/templates_python.txt
r4502 r4558 655 655 will use the function's name as the filter name. 656 656 657 Template filters which expect strings 658 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 659 If you are writing a template filter which only expects a string as the first 660 argument, you should use the included decorator ``to_str`` which will convert 661 an object to it's string value before being passed to your function:: 662 663 def lower(value): 664 return value.lower() 665 lower = template.to_str(lower) 666 657 667 Writing custom template tags 658 668 ---------------------------- django/trunk/tests/regressiontests/defaultfilters/tests.py
r4496 r4558 389 389 '0800 3569377' 390 390 391 391 # Filters shouldn't break if passed non-strings 392 >>> addslashes(123) 393 '123' 394 >>> linenumbers(123) 395 '1. 123' 396 >>> lower(123) 397 '123' 398 >>> make_list(123) 399 ['1', '2', '3'] 400 >>> slugify(123) 401 '123' 402 >>> title(123) 403 '123' 404 >>> truncatewords(123, 2) 405 '123' 406 >>> upper(123) 407 '123' 408 >>> urlencode(123) 409 '123' 410 >>> urlize(123) 411 '123' 412 >>> urlizetrunc(123, 1) 413 '123' 414 >>> wordcount(123) 415 1 416 >>> wordwrap(123, 2) 417 '123' 418 >>> ljust('123', 4) 419 '123 ' 420 >>> rjust('123', 4) 421 ' 123' 422 >>> center('123', 5) 423 ' 123 ' 424 >>> center('123', 6) 425 ' 123 ' 426 >>> cut(123, '2') 427 '13' 428 >>> escape(123) 429 '123' 430 >>> linebreaks(123) 431 '<p>123</p>' 432 >>> linebreaksbr(123) 433 '123' 434 >>> removetags(123, 'a') 435 '123' 436 >>> striptags(123) 437 '123' 392 438 393 439 """
