web/lib/django/template/defaultfilters.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     1 """Default variable filters."""
     1 """Default variable filters."""
     2 
     2 
     3 import re
     3 import re
     4 
     4 from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
     5 try:
       
     6     from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
       
     7 except ImportError:
       
     8     from django.utils._decimal import Decimal, InvalidOperation, ROUND_HALF_UP
       
     9 
       
    10 import random as random_module
     5 import random as random_module
    11 try:
     6 try:
    12     from functools import wraps
     7     from functools import wraps
    13 except ImportError:
     8 except ImportError:
    14     from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.
     9     from django.utils.functional import wraps  # Python 2.4 fallback.
    15 
    10 
    16 from django.template import Variable, Library
    11 from django.template import Variable, Library
    17 from django.conf import settings
    12 from django.conf import settings
       
    13 from django.utils import formats
    18 from django.utils.translation import ugettext, ungettext
    14 from django.utils.translation import ugettext, ungettext
    19 from django.utils.encoding import force_unicode, iri_to_uri
    15 from django.utils.encoding import force_unicode, iri_to_uri
    20 from django.utils.safestring import mark_safe, SafeData
    16 from django.utils.safestring import mark_safe, SafeData
    21 
    17 
    22 register = Library()
    18 register = Library()
    66     return value and value[0].upper() + value[1:]
    62     return value and value[0].upper() + value[1:]
    67 capfirst.is_safe=True
    63 capfirst.is_safe=True
    68 capfirst = stringfilter(capfirst)
    64 capfirst = stringfilter(capfirst)
    69 
    65 
    70 _base_js_escapes = (
    66 _base_js_escapes = (
    71     ('\\', r'\x5C'),
    67     ('\\', r'\u005C'),
    72     ('\'', r'\x27'),
    68     ('\'', r'\u0027'),
    73     ('"', r'\x22'),
    69     ('"', r'\u0022'),
    74     ('>', r'\x3E'),
    70     ('>', r'\u003E'),
    75     ('<', r'\x3C'),
    71     ('<', r'\u003C'),
    76     ('&', r'\x26'),
    72     ('&', r'\u0026'),
    77     ('=', r'\x3D'),
    73     ('=', r'\u003D'),
    78     ('-', r'\x2D'),
    74     ('-', r'\u002D'),
    79     (';', r'\x3B'),
    75     (';', r'\u003B'),
    80     (u'\u2028', r'\u2028'),
    76     (u'\u2028', r'\u2028'),
    81     (u'\u2029', r'\u2029')
    77     (u'\u2029', r'\u2029')
    82 )
    78 )
    83 
    79 
    84 # Escape every ASCII character with a value less than 32.
    80 # Escape every ASCII character with a value less than 32.
    85 _js_escapes = (_base_js_escapes +
    81 _js_escapes = (_base_js_escapes +
    86                tuple([('%c' % z, '\\x%02X' % z) for z in range(32)]))
    82                tuple([('%c' % z, '\\u%04X' % z) for z in range(32)]))
    87 
    83 
    88 def escapejs(value):
    84 def escapejs(value):
    89     """Hex encodes characters for use in JavaScript strings."""
    85     """Hex encodes characters for use in JavaScript strings."""
    90     for bad, good in _js_escapes:
    86     for bad, good in _js_escapes:
    91         value = value.replace(bad, good)
    87         value = value.replace(bad, good)
   160     except ValueError:
   156     except ValueError:
   161         return input_val
   157         return input_val
   162 
   158 
   163     try:
   159     try:
   164         m = int(d) - d
   160         m = int(d) - d
   165     except (OverflowError, InvalidOperation):
   161     except (ValueError, OverflowError, InvalidOperation):
   166         return input_val
   162         return input_val
   167 
   163 
   168     if not m and p < 0:
   164     if not m and p < 0:
   169         return mark_safe(u'%d' % (int(d)))
   165         return mark_safe(formats.number_format(u'%d' % (int(d)), 0))
   170 
   166 
   171     if p == 0:
   167     if p == 0:
   172         exp = Decimal(1)
   168         exp = Decimal(1)
   173     else:
   169     else:
   174         exp = Decimal('1.0') / (Decimal(10) ** abs(p))
   170         exp = Decimal('1.0') / (Decimal(10) ** abs(p))
   175     try:
   171     try:
   176         return mark_safe(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)))
   172         return mark_safe(formats.number_format(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)), abs(p)))
   177     except InvalidOperation:
   173     except InvalidOperation:
   178         return input_val
   174         return input_val
   179 floatformat.is_safe = True
   175 floatformat.is_safe = True
   180 
   176 
   181 def iriencode(value):
   177 def iriencode(value):
   247         return u""
   243         return u""
   248 stringformat.is_safe = True
   244 stringformat.is_safe = True
   249 
   245 
   250 def title(value):
   246 def title(value):
   251     """Converts a string into titlecase."""
   247     """Converts a string into titlecase."""
   252     return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title())
   248     t = re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title())
       
   249     return re.sub("\d([A-Z])", lambda m: m.group(0).lower(), t)
   253 title.is_safe = True
   250 title.is_safe = True
   254 title = stringfilter(title)
   251 title = stringfilter(title)
   255 
   252 
   256 def truncatewords(value, arg):
   253 def truncatewords(value, arg):
   257     """
   254     """
   647 # INTEGERS        #
   644 # INTEGERS        #
   648 ###################
   645 ###################
   649 
   646 
   650 def add(value, arg):
   647 def add(value, arg):
   651     """Adds the arg to the value."""
   648     """Adds the arg to the value."""
   652     return int(value) + int(arg)
   649     try:
       
   650         return int(value) + int(arg)
       
   651     except (ValueError, TypeError):
       
   652         try:
       
   653             return value + arg
       
   654         except:
       
   655             return value
   653 add.is_safe = False
   656 add.is_safe = False
   654 
   657 
   655 def get_digit(value, arg):
   658 def get_digit(value, arg):
   656     """
   659     """
   657     Given a whole number, returns the requested digit of it, where 1 is the
   660     Given a whole number, returns the requested digit of it, where 1 is the
   682     if not value:
   685     if not value:
   683         return u''
   686         return u''
   684     if arg is None:
   687     if arg is None:
   685         arg = settings.DATE_FORMAT
   688         arg = settings.DATE_FORMAT
   686     try:
   689     try:
   687         return format(value, arg)
   690         return formats.date_format(value, arg)
   688     except AttributeError:
   691     except AttributeError:
   689         return ''
   692         try:
       
   693             return format(value, arg)
       
   694         except AttributeError:
       
   695             return ''
   690 date.is_safe = False
   696 date.is_safe = False
   691 
   697 
   692 def time(value, arg=None):
   698 def time(value, arg=None):
   693     """Formats a time according to the given format."""
   699     """Formats a time according to the given format."""
   694     from django.utils.dateformat import time_format
   700     from django.utils import dateformat
   695     if value in (None, u''):
   701     if value in (None, u''):
   696         return u''
   702         return u''
   697     if arg is None:
   703     if arg is None:
   698         arg = settings.TIME_FORMAT
   704         arg = settings.TIME_FORMAT
   699     try:
   705     try:
   700         return time_format(value, arg)
   706         return formats.time_format(value, arg)
   701     except AttributeError:
   707     except AttributeError:
   702         return ''
   708         try:
       
   709             return dateformat.time_format(value, arg)
       
   710         except AttributeError:
       
   711             return ''
   703 time.is_safe = False
   712 time.is_safe = False
   704 
   713 
   705 def timesince(value, arg=None):
   714 def timesince(value, arg=None):
   706     """Formats a date as the time since that date (i.e. "4 days, 6 hours")."""
   715     """Formats a date as the time since that date (i.e. "4 days, 6 hours")."""
   707     from django.utils.timesince import timesince
   716     from django.utils.timesince import timesince
   789     Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
   798     Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
   790     102 bytes, etc).
   799     102 bytes, etc).
   791     """
   800     """
   792     try:
   801     try:
   793         bytes = float(bytes)
   802         bytes = float(bytes)
   794     except TypeError:
   803     except (TypeError,ValueError,UnicodeDecodeError):
   795         return u"0 bytes"
   804         return u"0 bytes"
   796 
   805 
   797     if bytes < 1024:
   806     if bytes < 1024:
   798         return ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes}
   807         return ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes}
   799     if bytes < 1024 * 1024:
   808     if bytes < 1024 * 1024: