Ticket #17135: 17135.3.patch

File 17135.3.patch, 30.0 KB (added by aaugustin, 4 years ago)
  • docs/internals/deprecation.txt

     
    251251  :mod:`django.core.management`. This also means that the old (pre-1.4)
    252252  style of :file:`manage.py` file will no longer work.
    253253
     254* Setting the ``is_safe`` and ``needs_autoescape`` flags as attributes of
     255  template filter functions will no longer be supported.
     256
    2542572.0
    255258---
    256259
  • docs/howto/custom-template-tags.txt

     
    2062061. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
    207207   ``'``, ``"`` or ``&``) into the result that were not already present. In
    208208   this case, you can let Django take care of all the auto-escaping
    209    handling for you. All you need to do is put the ``is_safe`` attribute on
    210    your filter function and set it to ``True``, like so:
     209   handling for you. All you need to do is set the ``is_safe`` flag to ``True``
     210   when you register your filter function, like so:
    211211
    212212   .. code-block:: python
    213213
    214        @register.filter
     214       @register.filter(is_safe=True)
    215215       def myfilter(value):
    216216           return value
    217        myfilter.is_safe = True
    218217
    219218   This attribute tells Django that if a "safe" string is passed into your
    220219   filter, the result will still be "safe" and if a non-safe string is
     
    236235
    237236   .. code-block:: python
    238237
    239        @register.filter
     238       @register.filter(is_safe=True)
    240239       def add_xx(value):
    241240           return '%sxx' % value
    242        add_xx.is_safe = True
    243241
    244242   When this filter is used in a template where auto-escaping is enabled,
    245243   Django will escape the output whenever the input is not already marked
    246244   as "safe".
    247245
    248    By default, ``is_safe`` defaults to ``False``, and you can omit it from
    249    any filters where it isn't required.
     246   By default, ``is_safe`` is ``False``, and you can omit it from any filters
     247   where it isn't required.
    250248
    251249   Be careful when deciding if your filter really does leave safe strings
    252250   as safe. If you're *removing* characters, you might inadvertently leave
     
    279277   can operate in templates where auto-escaping is either on or off in
    280278   order to make things easier for your template authors.
    281279
    282    In order for your filter to know the current auto-escaping state, set
    283    the ``needs_autoescape`` attribute to ``True`` on your function. (If you
    284    don't specify this attribute, it defaults to ``False``). This attribute
    285    tells Django that your filter function wants to be passed an extra
    286    keyword argument, called ``autoescape``, that is ``True`` if
    287    auto-escaping is in effect and ``False`` otherwise.
     280   In order for your filter to know the current auto-escaping state, set the
     281   ``needs_autoescape`` flag to ``True`` when you register your filter function.
     282   (If you don't specify this flag, it defaults to ``False``). This flag tells
     283   Django that your filter function wants to be passed an extra keyword
     284   argument, called ``autoescape``, that is ``True`` if auto-escaping is in
     285   effect and ``False`` otherwise.
    288286
    289287   For example, let's write a filter that emphasizes the first character of
    290288   a string:
     
    294292       from django.utils.html import conditional_escape
    295293       from django.utils.safestring import mark_safe
    296294
     295       @register.filter(needs_autoescape=True)
    297296       def initial_letter_filter(text, autoescape=None):
    298297           first, other = text[0], text[1:]
    299298           if autoescape:
     
    302301               esc = lambda x: x
    303302           result = '<strong>%s</strong>%s' % (esc(first), esc(other))
    304303           return mark_safe(result)
    305        initial_letter_filter.needs_autoescape = True
    306304
    307    The ``needs_autoescape`` attribute on the filter function and the
    308    ``autoescape`` keyword argument mean that our function will know whether
    309    automatic escaping is in effect when the filter is called. We use
    310    ``autoescape`` to decide whether the input data needs to be passed
    311    through ``django.utils.html.conditional_escape`` or not. (In the latter
    312    case, we just use the identity function as the "escape" function.) The
    313    ``conditional_escape()`` function is like ``escape()`` except it only
    314    escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
    315    instance is passed to ``conditional_escape()``, the data is returned
    316    unchanged.
     305   The ``needs_autoescape`` flag and the ``autoescape`` keyword argument mean
     306   that our function will know whether automatic escaping is in effect when the
     307   filter is called. We use ``autoescape`` to decide whether the input data
     308   needs to be passed through ``django.utils.html.conditional_escape`` or not.
     309   (In the latter case, we just use the identity function as the "escape"
     310   function.) The ``conditional_escape()`` function is like ``escape()`` except
     311   it only escapes input that is **not** a ``SafeData`` instance. If a
     312   ``SafeData`` instance is passed to ``conditional_escape()``, the data is
     313   returned unchanged.
    317314
    318315   Finally, in the above example, we remember to mark the result as safe
    319316   so that our HTML is inserted directly into the template without further
     
    324321   handle the auto-escaping issues and return a safe string, the
    325322   ``is_safe`` attribute won't change anything either way.
    326323
     324.. versionchanged:: 1.4
     325
     326``is_safe`` and ``needs_autoescape`` used to be attributes of the filter
     327function:
     328
     329.. code-block:: python
     330
     331    @register.filter
     332    def myfilter(value):
     333        return value
     334    myfilter.is_safe = True
     335
     336.. code-block:: python
     337
     338    @register.filter
     339    def initial_letter_filter(text, autoescape=None):
     340        # ...
     341        return mark_safe(result)
     342    initial_letter_filter.needs_autoescape = True
     343
     344This syntax is deprecated.
     345
    327346Writing custom template tags
    328347----------------------------
    329348
  • tests/regressiontests/templates/templatetags/custom.py

     
    66
    77register = template.Library()
    88
     9@register.filter
     10@stringfilter
    911def trim(value, num):
    1012    return value[:num]
    11 trim = stringfilter(trim)
    1213
    13 register.filter(trim)
    14 
    1514@register.simple_tag
    1615def no_params():
    1716    """Expected no_params __doc__"""
  • django/templatetags/l10n.py

     
    55
    66register = Library()
    77
    8 @register.filter
     8@register.filter(is_safe=False)
    99def localize(value):
    1010    """
    1111    Forces a value to be rendered as a localized value,
    1212    regardless of the value of ``settings.USE_L10N``.
    1313    """
    1414    return force_unicode(formats.localize(value, use_l10n=True))
    15 localize.is_safe = False
    1615
    17 @register.filter
     16@register.filter(is_safe=False)
    1817def unlocalize(value):
    1918    """
    2019    Forces a value to be rendered as a non-localized value,
    2120    regardless of the value of ``settings.USE_L10N``.
    2221    """
    2322    return force_unicode(value)
    24 unlocalize.is_safe = False
    2523
    2624class LocalizeNode(Node):
    2725    def __init__(self, nodelist, use_l10n):
  • django/contrib/humanize/templatetags/humanize.py

     
    1111
    1212register = template.Library()
    1313
    14 @register.filter
     14@register.filter(is_safe=True)
    1515def ordinal(value):
    1616    """
    1717    Converts an integer to its ordinal as a string. 1 is '1st', 2 is '2nd',
     
    2525    if value % 100 in (11, 12, 13): # special case
    2626        return u"%d%s" % (value, suffixes[0])
    2727    return u"%d%s" % (value, suffixes[value % 10])
    28 ordinal.is_safe = True
    2928
    30 @register.filter
     29@register.filter(is_safe=True)
    3130def intcomma(value, use_l10n=True):
    3231    """
    3332    Converts an integer to a string containing commas every three digits.
     
    4746        return new
    4847    else:
    4948        return intcomma(new, use_l10n)
    50 intcomma.is_safe = True
    5149
    5250# A tuple of standard large number to their converters
    5351intword_converters = (
     
    9795    )),
    9896)
    9997
    100 @register.filter
     98@register.filter(is_safe=False)
    10199def intword(value):
    102100    """
    103101    Converts a large integer to a friendly text representation. Works best
     
    129127            new_value = value / float(large_number)
    130128            return _check_for_i18n(new_value, *converters(new_value))
    131129    return value
    132 intword.is_safe = False
    133130
    134 @register.filter
     131@register.filter(is_safe=True)
    135132def apnumber(value):
    136133    """
    137134    For numbers 1-9, returns the number spelled out. Otherwise, returns the
     
    144141    if not 0 < value < 10:
    145142        return value
    146143    return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1]
    147 apnumber.is_safe = True
    148144
    149145@register.filter
    150146def naturalday(value, arg=None):
  • django/contrib/markup/templatetags/markup.py

     
    1818
    1919register = template.Library()
    2020
    21 @register.filter
     21@register.filter(is_safe=True)
    2222def textile(value):
    2323    try:
    2424        import textile
     
    2828        return force_unicode(value)
    2929    else:
    3030        return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8')))
    31 textile.is_safe = True
    3231
    33 @register.filter
     32@register.filter(is_safe=True)
    3433def markdown(value, arg=''):
    3534    """
    3635    Runs Markdown over a given value, optionally using various
     
    7372                return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
    7473        else:
    7574            return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
    76 markdown.is_safe = True
    7775
    78 @register.filter
     76@register.filter(is_safe=True)
    7977def restructuredtext(value):
    8078    try:
    8179        from docutils.core import publish_parts
     
    8785        docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
    8886        parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings)
    8987        return mark_safe(force_unicode(parts["fragment"]))
    90 restructuredtext.is_safe = True
    91 
  • django/template/base.py

     
    10571057        self.tags[getattr(func, "_decorated_function", func).__name__] = func
    10581058        return func
    10591059
    1060     def filter(self, name=None, filter_func=None):
     1060    def filter(self, name=None, filter_func=None, **flags):
    10611061        if name is None and filter_func is None:
    10621062            # @register.filter()
    1063             return self.filter_function
    1064         elif filter_func is None:
     1063            def dec(func):
     1064                return self.filter_function(func, **flags)
     1065            return dec
     1066
     1067        elif name is not None and filter_func is None:
    10651068            if callable(name):
    10661069                # @register.filter
    1067                 return self.filter_function(name)
     1070                return self.filter_function(name, **flags)
    10681071            else:
    10691072                # @register.filter('somename') or @register.filter(name='somename')
    10701073                def dec(func):
    1071                     return self.filter(name, func)
     1074                    return self.filter(name, func, **flags)
    10721075                return dec
     1076
    10731077        elif name is not None and filter_func is not None:
    10741078            # register.filter('somename', somefunc)
    10751079            self.filters[name] = filter_func
     1080            for attr in ('is_safe', 'needs_autoescape'):
     1081                if attr in flags:
     1082                    value = flags[attr]
     1083                    setattr(filter_func, attr, value)
     1084                    if hasattr(filter_func, "_decorated_function"):
     1085                        setattr(filter_func._decorated_function, attr, value)
    10761086            return filter_func
    10771087        else:
    10781088            raise InvalidTemplateLibrary("Unsupported arguments to "
    10791089                "Library.filter: (%r, %r)", (name, filter_func))
    10801090
    1081     def filter_function(self, func):
    1082         self.filters[getattr(func, "_decorated_function", func).__name__] = func
    1083         return func
     1091    def filter_function(self, func, **flags):
     1092        name = getattr(func, "_decorated_function", func).__name__
     1093        return self.filter(name, func, **flags)
    10841094
    10851095    def simple_tag(self, func=None, takes_context=None, name=None):
    10861096        def dec(func):
  • django/template/defaultfilters.py

     
    3737        if args:
    3838            args = list(args)
    3939            args[0] = force_unicode(args[0])
    40             if isinstance(args[0], SafeData) and getattr(func, 'is_safe', False):
     40            if (isinstance(args[0], SafeData) and
     41                getattr(_dec._decorated_function, 'is_safe', False)):
    4142                return mark_safe(func(*args, **kwargs))
    4243        return func(*args, **kwargs)
    4344
     
    4647    _dec._decorated_function = getattr(func, '_decorated_function', func)
    4748    for attr in ('is_safe', 'needs_autoescape'):
    4849        if hasattr(func, attr):
     50            import warnings
     51            warnings.warn("Setting the %s attribute of a template filter "
     52                          "function is deprecated; use @register.filter(%s=%s) "
     53                          "instead" % (attr, attr, getattr(func, attr)),
     54                          PendingDeprecationWarning)
    4955            setattr(_dec, attr, getattr(func, attr))
    5056    return wraps(func)(_dec)
    5157
     
    5359# STRINGS         #
    5460###################
    5561
    56 @register.filter
     62@register.filter(is_safe=True)
    5763@stringfilter
    5864def addslashes(value):
    5965    """
     
    6268    filter instead.
    6369    """
    6470    return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'")
    65 addslashes.is_safe = True
    6671
    67 @register.filter
     72@register.filter(is_safe=True)
    6873@stringfilter
    6974def capfirst(value):
    7075    """Capitalizes the first character of the value."""
    7176    return value and value[0].upper() + value[1:]
    72 capfirst.is_safe = True
    7377
    7478@register.filter("escapejs")
    7579@stringfilter
     
    7781    """Hex encodes characters for use in JavaScript strings."""
    7882    return escapejs(value)
    7983
    80 @register.filter("fix_ampersands")
     84@register.filter("fix_ampersands", is_safe=True)
    8185@stringfilter
    8286def fix_ampersands_filter(value):
    8387    """Replaces ampersands with ``&amp;`` entities."""
    8488    return fix_ampersands(value)
    85 fix_ampersands_filter.is_safe = True
    8689
    8790# Values for testing floatformat input against infinity and NaN representations,
    8891# which differ across platforms and Python versions.  Some (i.e. old Windows
     
    9699nan = (1e200 * 1e200) // (1e200 * 1e200)
    97100special_floats = [str(pos_inf), str(neg_inf), str(nan)]
    98101
    99 @register.filter
     102@register.filter(is_safe=True)
    100103def floatformat(text, arg=-1):
    101104    """
    102105    Displays a float to a specified number of decimal places.
     
    172175        return mark_safe(formats.number_format(number, abs(p)))
    173176    except InvalidOperation:
    174177        return input_val
    175 floatformat.is_safe = True
    176178
    177 @register.filter
     179@register.filter(is_safe=True)
    178180@stringfilter
    179181def iriencode(value):
    180182    """Escapes an IRI value for use in a URL."""
    181183    return force_unicode(iri_to_uri(value))
    182 iriencode.is_safe = True
    183184
    184 @register.filter
     185@register.filter(is_safe=True, needs_autoescape=True)
    185186@stringfilter
    186187def linenumbers(value, autoescape=None):
    187188    """Displays text with line numbers."""
     
    196197        for i, line in enumerate(lines):
    197198            lines[i] = (u"%0" + width  + u"d. %s") % (i + 1, escape(line))
    198199    return mark_safe(u'\n'.join(lines))
    199 linenumbers.is_safe = True
    200 linenumbers.needs_autoescape = True
    201200
    202 @register.filter
     201@register.filter(is_safe=True)
    203202@stringfilter
    204203def lower(value):
    205204    """Converts a string into all lowercase."""
    206205    return value.lower()
    207 lower.is_safe = True
    208206
    209 @register.filter
     207@register.filter(is_safe=False)
    210208@stringfilter
    211209def make_list(value):
    212210    """
     
    216214    For a string, it's a list of characters.
    217215    """
    218216    return list(value)
    219 make_list.is_safe = False
    220217
    221 @register.filter
     218@register.filter(is_safe=True)
    222219@stringfilter
    223220def slugify(value):
    224221    """
     
    228225    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
    229226    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
    230227    return mark_safe(re.sub('[-\s]+', '-', value))
    231 slugify.is_safe = True
    232228
    233 @register.filter
     229@register.filter(is_safe=True)
    234230def stringformat(value, arg):
    235231    """
    236232    Formats the variable according to the arg, a string formatting specifier.
     
    245241        return (u"%" + unicode(arg)) % value
    246242    except (ValueError, TypeError):
    247243        return u""
    248 stringformat.is_safe = True
    249244
    250 @register.filter
     245@register.filter(is_safe=True)
    251246@stringfilter
    252247def title(value):
    253248    """Converts a string into titlecase."""
    254249    t = re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title())
    255250    return re.sub("\d([A-Z])", lambda m: m.group(0).lower(), t)
    256 title.is_safe = True
    257251
    258 @register.filter
     252@register.filter(is_safe=True)
    259253@stringfilter
    260254def truncatechars(value, arg):
    261255    """
     
    268262    except ValueError: # Invalid literal for int().
    269263        return value # Fail silently.
    270264    return Truncator(value).chars(length)
    271 truncatechars.is_safe = True
    272265
    273 @register.filter
     266@register.filter(is_safe=True)
    274267@stringfilter
    275268def truncatewords(value, arg):
    276269    """
     
    285278    except ValueError: # Invalid literal for int().
    286279        return value # Fail silently.
    287280    return Truncator(value).words(length, truncate=' ...')
    288 truncatewords.is_safe = True
    289281
    290 @register.filter
     282@register.filter(is_safe=True)
    291283@stringfilter
    292284def truncatewords_html(value, arg):
    293285    """
     
    302294    except ValueError: # invalid literal for int()
    303295        return value # Fail silently.
    304296    return Truncator(value).words(length, html=True, truncate=' ...')
    305 truncatewords_html.is_safe = True
    306297
    307 @register.filter
     298@register.filter(is_safe=False)
    308299@stringfilter
    309300def upper(value):
    310301    """Converts a string into all uppercase."""
    311302    return value.upper()
    312 upper.is_safe = False
    313303
    314 @register.filter
     304@register.filter(is_safe=False)
    315305@stringfilter
    316306def urlencode(value, safe=None):
    317307    """
     
    326316    if safe is not None:
    327317        kwargs['safe'] = safe
    328318    return urlquote(value, **kwargs)
    329 urlencode.is_safe = False
    330319
    331 @register.filter
     320@register.filter(is_safe=True, needs_autoescape=True)
    332321@stringfilter
    333322def urlize(value, autoescape=None):
    334323    """Converts URLs in plain text into clickable links."""
    335324    return mark_safe(urlize_impl(value, nofollow=True, autoescape=autoescape))
    336 urlize.is_safe = True
    337 urlize.needs_autoescape = True
    338325
    339 @register.filter
     326@register.filter(is_safe=True, needs_autoescape=True)
    340327@stringfilter
    341328def urlizetrunc(value, limit, autoescape=None):
    342329    """
     
    347334    """
    348335    return mark_safe(urlize_impl(value, trim_url_limit=int(limit), nofollow=True,
    349336                            autoescape=autoescape))
    350 urlizetrunc.is_safe = True
    351 urlizetrunc.needs_autoescape = True
    352337
    353 @register.filter
     338@register.filter(is_safe=False)
    354339@stringfilter
    355340def wordcount(value):
    356341    """Returns the number of words."""
    357342    return len(value.split())
    358 wordcount.is_safe = False
    359343
    360 @register.filter
     344@register.filter(is_safe=True)
    361345@stringfilter
    362346def wordwrap(value, arg):
    363347    """
     
    366350    Argument: number of characters to wrap the text at.
    367351    """
    368352    return wrap(value, int(arg))
    369 wordwrap.is_safe = True
    370353
    371 @register.filter
     354@register.filter(is_safe=True)
    372355@stringfilter
    373356def ljust(value, arg):
    374357    """
     
    377360    Argument: field size.
    378361    """
    379362    return value.ljust(int(arg))
    380 ljust.is_safe = True
    381363
    382 @register.filter
     364@register.filter(is_safe=True)
    383365@stringfilter
    384366def rjust(value, arg):
    385367    """
     
    388370    Argument: field size.
    389371    """
    390372    return value.rjust(int(arg))
    391 rjust.is_safe = True
    392373
    393 @register.filter
     374@register.filter(is_safe=True)
    394375@stringfilter
    395376def center(value, arg):
    396377    """Centers the value in a field of a given width."""
    397378    return value.center(int(arg))
    398 center.is_safe = True
    399379
    400380@register.filter
    401381@stringfilter
     
    413393# HTML STRINGS    #
    414394###################
    415395
    416 @register.filter("escape")
     396@register.filter("escape", is_safe=True)
    417397@stringfilter
    418398def escape_filter(value):
    419399    """
    420400    Marks the value as a string that should not be auto-escaped.
    421401    """
    422402    return mark_for_escaping(value)
    423 escape_filter.is_safe = True
    424403
    425 @register.filter
     404@register.filter(is_safe=True)
    426405@stringfilter
    427406def force_escape(value):
    428407    """
     
    431410    possible escaping).
    432411    """
    433412    return mark_safe(escape(value))
    434 force_escape.is_safe = True
    435413
    436 @register.filter("linebreaks")
     414@register.filter("linebreaks", is_safe=True, needs_autoescape=True)
    437415@stringfilter
    438416def linebreaks_filter(value, autoescape=None):
    439417    """
     
    443421    """
    444422    autoescape = autoescape and not isinstance(value, SafeData)
    445423    return mark_safe(linebreaks(value, autoescape))
    446 linebreaks_filter.is_safe = True
    447 linebreaks_filter.needs_autoescape = True
    448424
    449 @register.filter
     425@register.filter(is_safe=True, needs_autoescape=True)
    450426@stringfilter
    451427def linebreaksbr(value, autoescape=None):
    452428    """
     
    458434    if autoescape:
    459435        value = escape(value)
    460436    return mark_safe(value.replace('\n', '<br />'))
    461 linebreaksbr.is_safe = True
    462 linebreaksbr.needs_autoescape = True
    463437
    464 @register.filter
     438@register.filter(is_safe=True)
    465439@stringfilter
    466440def safe(value):
    467441    """
    468442    Marks the value as a string that should not be auto-escaped.
    469443    """
    470444    return mark_safe(value)
    471 safe.is_safe = True
    472445
    473 @register.filter
     446@register.filter(is_safe=True)
    474447def safeseq(value):
    475448    """
    476449    A "safe" filter for sequences. Marks each element in the sequence,
     
    478451    with the results.
    479452    """
    480453    return [mark_safe(force_unicode(obj)) for obj in value]
    481 safeseq.is_safe = True
    482454
    483 @register.filter
     455@register.filter(is_safe=True)
    484456@stringfilter
    485457def removetags(value, tags):
    486458    """Removes a space separated list of [X]HTML tags from the output."""
     
    491463    value = starttag_re.sub(u'', value)
    492464    value = endtag_re.sub(u'', value)
    493465    return value
    494 removetags.is_safe = True
    495466
    496 @register.filter
     467@register.filter(is_safe=True)
    497468@stringfilter
    498469def striptags(value):
    499470    """Strips all [X]HTML tags."""
    500471    return strip_tags(value)
    501 striptags.is_safe = True
    502472
    503473###################
    504474# LISTS           #
    505475###################
    506476
    507 @register.filter
     477@register.filter(is_safe=False)
    508478def dictsort(value, arg):
    509479    """
    510480    Takes a list of dicts, returns that list sorted by the property given in
    511481    the argument.
    512482    """
    513483    return sorted(value, key=Variable(arg).resolve)
    514 dictsort.is_safe = False
    515484
    516 @register.filter
     485@register.filter(is_safe=False)
    517486def dictsortreversed(value, arg):
    518487    """
    519488    Takes a list of dicts, returns that list sorted in reverse order by the
    520489    property given in the argument.
    521490    """
    522491    return sorted(value, key=Variable(arg).resolve, reverse=True)
    523 dictsortreversed.is_safe = False
    524492
    525 @register.filter
     493@register.filter(is_safe=False)
    526494def first(value):
    527495    """Returns the first item in a list."""
    528496    try:
    529497        return value[0]
    530498    except IndexError:
    531499        return u''
    532 first.is_safe = False
    533500
    534 @register.filter
     501@register.filter(is_safe=True, needs_autoescape=True)
    535502def join(value, arg, autoescape=None):
    536503    """
    537504    Joins a list with a string, like Python's ``str.join(list)``.
     
    544511    except AttributeError: # fail silently but nicely
    545512        return value
    546513    return mark_safe(data)
    547 join.is_safe = True
    548 join.needs_autoescape = True
    549514
    550 @register.filter
     515@register.filter(is_safe=True)
    551516def last(value):
    552517    "Returns the last item in a list"
    553518    try:
    554519        return value[-1]
    555520    except IndexError:
    556521        return u''
    557 last.is_safe = True
    558522
    559 @register.filter
     523@register.filter(is_safe=True)
    560524def length(value):
    561525    """Returns the length of the value - useful for lists."""
    562526    try:
    563527        return len(value)
    564528    except (ValueError, TypeError):
    565529        return ''
    566 length.is_safe = True
    567530
    568 @register.filter
     531@register.filter(is_safe=False)
    569532def length_is(value, arg):
    570533    """Returns a boolean of whether the value's length is the argument."""
    571534    try:
    572535        return len(value) == int(arg)
    573536    except (ValueError, TypeError):
    574537        return ''
    575 length_is.is_safe = False
    576538
    577 @register.filter
     539@register.filter(is_safe=True)
    578540def random(value):
    579541    """Returns a random item from the list."""
    580542    return random_module.choice(value)
    581 random.is_safe = True
    582543
    583 @register.filter("slice")
     544@register.filter("slice", is_safe=True)
    584545def slice_filter(value, arg):
    585546    """
    586547    Returns a slice of the list.
     
    600561
    601562    except (ValueError, TypeError):
    602563        return value # Fail silently.
    603 slice_filter.is_safe = True
    604564
    605 @register.filter
     565@register.filter(is_safe=True, needs_autoescape=True)
    606566def unordered_list(value, autoescape=None):
    607567    """
    608568    Recursively takes a self-nested list and returns an HTML unordered list --
     
    688648        return '\n'.join(output)
    689649    value, converted = convert_old_style_list(value)
    690650    return mark_safe(_helper(value))
    691 unordered_list.is_safe = True
    692 unordered_list.needs_autoescape = True
    693651
    694652###################
    695653# INTEGERS        #
    696654###################
    697655
    698 @register.filter
     656@register.filter(is_safe=False)
    699657def add(value, arg):
    700658    """Adds the arg to the value."""
    701659    try:
     
    705663            return value + arg
    706664        except Exception:
    707665            return ''
    708 add.is_safe = False
    709666
    710 @register.filter
     667@register.filter(is_safe=False)
    711668def get_digit(value, arg):
    712669    """
    713670    Given a whole number, returns the requested digit of it, where 1 is the
     
    726683        return int(str(value)[-arg])
    727684    except IndexError:
    728685        return 0
    729 get_digit.is_safe = False
    730686
    731687###################
    732688# DATES           #
    733689###################
    734690
    735 @register.filter
     691@register.filter(is_safe=False)
    736692def date(value, arg=None):
    737693    """Formats a date according to the given format."""
    738694    if not value:
     
    746702            return format(value, arg)
    747703        except AttributeError:
    748704            return ''
    749 date.is_safe = False
    750705
    751 @register.filter
     706@register.filter(is_safe=False)
    752707def time(value, arg=None):
    753708    """Formats a time according to the given format."""
    754709    if value in (None, u''):
     
    762717            return time_format(value, arg)
    763718        except AttributeError:
    764719            return ''
    765 time.is_safe = False
    766720
    767 @register.filter("timesince")
     721@register.filter("timesince", is_safe=False)
    768722def timesince_filter(value, arg=None):
    769723    """Formats a date as the time since that date (i.e. "4 days, 6 hours")."""
    770724    if not value:
     
    775729        return timesince(value)
    776730    except (ValueError, TypeError):
    777731        return u''
    778 timesince_filter.is_safe = False
    779732
    780 @register.filter("timeuntil")
     733@register.filter("timeuntil", is_safe=False)
    781734def timeuntil_filter(value, arg=None):
    782735    """Formats a date as the time until that date (i.e. "4 days, 6 hours")."""
    783736    if not value:
     
    786739        return timeuntil(value, arg)
    787740    except (ValueError, TypeError):
    788741        return u''
    789 timeuntil_filter.is_safe = False
    790742
    791743###################
    792744# LOGIC           #
    793745###################
    794746
    795 @register.filter
     747@register.filter(is_safe=False)
    796748def default(value, arg):
    797749    """If value is unavailable, use given default."""
    798750    return value or arg
    799 default.is_safe = False
    800751
    801 @register.filter
     752@register.filter(is_safe=False)
    802753def default_if_none(value, arg):
    803754    """If value is None, use given default."""
    804755    if value is None:
    805756        return arg
    806757    return value
    807 default_if_none.is_safe = False
    808758
    809 @register.filter
     759@register.filter(is_safe=False)
    810760def divisibleby(value, arg):
    811761    """Returns True if the value is devisible by the argument."""
    812762    return int(value) % int(arg) == 0
    813 divisibleby.is_safe = False
    814763
    815 @register.filter
     764@register.filter(is_safe=False)
    816765def yesno(value, arg=None):
    817766    """
    818767    Given a string mapping values for true, false and (optionally) None,
     
    843792    if value:
    844793        return yes
    845794    return no
    846 yesno.is_safe = False
    847795
    848796###################
    849797# MISC            #
    850798###################
    851799
    852 @register.filter
     800@register.filter(is_safe=True)
    853801def filesizeformat(bytes):
    854802    """
    855803    Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
     
    873821    if bytes < 1024 * 1024 * 1024 * 1024 * 1024:
    874822        return ugettext("%s TB") % filesize_number_format(bytes / (1024 * 1024 * 1024 * 1024))
    875823    return ugettext("%s PB") % filesize_number_format(bytes / (1024 * 1024 * 1024 * 1024 * 1024))
    876 filesizeformat.is_safe = True
    877824
    878 @register.filter
     825@register.filter(is_safe=False)
    879826def pluralize(value, arg=u's'):
    880827    """
    881828    Returns a plural suffix if the value is not 1. By default, 's' is used as
     
    918865        except TypeError: # len() of unsized object.
    919866            pass
    920867    return singular_suffix
    921 pluralize.is_safe = False
    922868
    923 @register.filter("phone2numeric")
     869@register.filter("phone2numeric", is_safe=True)
    924870def phone2numeric_filter(value):
    925871    """Takes a phone number and converts it in to its numerical equivalent."""
    926872    return phone2numeric(value)
    927 phone2numeric_filter.is_safe = True
    928873
    929 @register.filter
     874@register.filter(is_safe=True)
    930875def pprint(value):
    931876    """A wrapper around pprint.pprint -- for debugging, really."""
    932877    try:
    933878        return pformat(value)
    934879    except Exception, e:
    935880        return u"Error in formatting: %s" % force_unicode(e, errors="replace")
    936 pprint.is_safe = True
Back to Top