Permalink
Browse files

Fixed #17135 -- Made it possible to use decorators (like stringfilter…

…) on template filter functions in combination with auto-escaping. Refs #16726.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17056 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent bebbc9e commit d17bc72880caea967ee1f4332941269837b68a2a @aaugustin aaugustin committed Oct 30, 2011
@@ -11,7 +11,7 @@
register = template.Library()
-@register.filter
+@register.filter(is_safe=True)
def ordinal(value):
"""
Converts an integer to its ordinal as a string. 1 is '1st', 2 is '2nd',
@@ -25,9 +25,8 @@ def ordinal(value):
if value % 100 in (11, 12, 13): # special case
return u"%d%s" % (value, suffixes[0])
return u"%d%s" % (value, suffixes[value % 10])
-ordinal.is_safe = True
-@register.filter
+@register.filter(is_safe=True)
def intcomma(value, use_l10n=True):
"""
Converts an integer to a string containing commas every three digits.
@@ -47,7 +46,6 @@ def intcomma(value, use_l10n=True):
return new
else:
return intcomma(new, use_l10n)
-intcomma.is_safe = True
# A tuple of standard large number to their converters
intword_converters = (
@@ -97,7 +95,7 @@ def intcomma(value, use_l10n=True):
)),
)
-@register.filter
+@register.filter(is_safe=False)
def intword(value):
"""
Converts a large integer to a friendly text representation. Works best
@@ -129,9 +127,8 @@ def _check_for_i18n(value, float_formatted, string_formatted):
new_value = value / float(large_number)
return _check_for_i18n(new_value, *converters(new_value))
return value
-intword.is_safe = False
-@register.filter
+@register.filter(is_safe=True)
def apnumber(value):
"""
For numbers 1-9, returns the number spelled out. Otherwise, returns the
@@ -144,7 +141,6 @@ def apnumber(value):
if not 0 < value < 10:
return value
return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1]
-apnumber.is_safe = True
@register.filter
def naturalday(value, arg=None):
@@ -18,7 +18,7 @@
register = template.Library()
-@register.filter
+@register.filter(is_safe=True)
def textile(value):
try:
import textile
@@ -28,9 +28,8 @@ def textile(value):
return force_unicode(value)
else:
return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8')))
-textile.is_safe = True
-@register.filter
+@register.filter(is_safe=True)
def markdown(value, arg=''):
"""
Runs Markdown over a given value, optionally using various
@@ -73,9 +72,8 @@ def markdown(value, arg=''):
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
else:
return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
-markdown.is_safe = True
-@register.filter
+@register.filter(is_safe=True)
def restructuredtext(value):
try:
from docutils.core import publish_parts
@@ -87,5 +85,3 @@ def restructuredtext(value):
docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings)
return mark_safe(force_unicode(parts["fragment"]))
-restructuredtext.is_safe = True
-
@@ -1057,30 +1057,43 @@ def tag_function(self, func):
self.tags[getattr(func, "_decorated_function", func).__name__] = func
return func
- def filter(self, name=None, filter_func=None):
+ def filter(self, name=None, filter_func=None, **flags):
if name is None and filter_func is None:
# @register.filter()
- return self.filter_function
- elif filter_func is None:
+ def dec(func):
+ return self.filter_function(func, **flags)
+ return dec
+
+ elif name is not None and filter_func is None:
if callable(name):
# @register.filter
- return self.filter_function(name)
+ return self.filter_function(name, **flags)
else:
# @register.filter('somename') or @register.filter(name='somename')
def dec(func):
- return self.filter(name, func)
+ return self.filter(name, func, **flags)
return dec
+
elif name is not None and filter_func is not None:
# register.filter('somename', somefunc)
self.filters[name] = filter_func
+ for attr in ('is_safe', 'needs_autoescape'):
+ if attr in flags:
+ value = flags[attr]
+ # set the flag on the filter for FilterExpression.resolve
+ setattr(filter_func, attr, value)
+ # set the flag on the innermost decorated function
+ # for decorators that need it e.g. stringfilter
+ if hasattr(filter_func, "_decorated_function"):
+ setattr(filter_func._decorated_function, attr, value)
return filter_func
else:
raise InvalidTemplateLibrary("Unsupported arguments to "
"Library.filter: (%r, %r)", (name, filter_func))
- def filter_function(self, func):
- self.filters[getattr(func, "_decorated_function", func).__name__] = func
- return func
+ def filter_function(self, func, **flags):
+ name = getattr(func, "_decorated_function", func).__name__
+ return self.filter(name, func, **flags)
def simple_tag(self, func=None, takes_context=None, name=None):
def dec(func):
Oops, something went wrong.

0 comments on commit d17bc72

Please sign in to comment.