summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2011-10-30 07:32:21 +0000
committerAymeric Augustin <aymeric.augustin@m4x.org>2011-10-30 07:32:21 +0000
commitd17bc72880caea967ee1f4332941269837b68a2a (patch)
treefc1fa3537f139a2f2f1829c7bbdff008fdbc684a /docs
parentbebbc9e4a537f45bfd24a902d223ad96d743a524 (diff)
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
Diffstat (limited to 'docs')
-rw-r--r--docs/howto/custom-template-tags.txt79
-rw-r--r--docs/internals/deprecation.txt3
2 files changed, 54 insertions, 28 deletions
diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt
index 581d69c631..6b2355e8d0 100644
--- a/docs/howto/custom-template-tags.txt
+++ b/docs/howto/custom-template-tags.txt
@@ -143,6 +143,10 @@ You can use ``register.filter()`` as a decorator instead:
If you leave off the ``name`` argument, as in the second example above, Django
will use the function's name as the filter name.
+Finally, ``register.filter()`` also accepts two keyword arguments, ``is_safe``
+and ``needs_autoescape``, described in :ref:`filters and auto-escaping
+<filters-auto-escaping>` below.
+
Template filters that expect strings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -166,6 +170,8 @@ This way, you'll be able to pass, say, an integer to this filter, and it
won't cause an ``AttributeError`` (because integers don't have ``lower()``
methods).
+.. _filters-auto-escaping:
+
Filters and auto-escaping
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -206,17 +212,16 @@ Template filter code falls into one of two situations:
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
``'``, ``"`` or ``&``) into the result that were not already present. In
this case, you can let Django take care of all the auto-escaping
- handling for you. All you need to do is put the ``is_safe`` attribute on
- your filter function and set it to ``True``, like so:
+ handling for you. All you need to do is set the ``is_safe`` flag to ``True``
+ when you register your filter function, like so:
.. code-block:: python
- @register.filter
+ @register.filter(is_safe=True)
def myfilter(value):
return value
- myfilter.is_safe = True
- This attribute tells Django that if a "safe" string is passed into your
+ This flag tells Django that if a "safe" string is passed into your
filter, the result will still be "safe" and if a non-safe string is
passed in, Django will automatically escape it, if necessary.
@@ -236,17 +241,16 @@ Template filter code falls into one of two situations:
.. code-block:: python
- @register.filter
+ @register.filter(is_safe=True)
def add_xx(value):
return '%sxx' % value
- add_xx.is_safe = True
When this filter is used in a template where auto-escaping is enabled,
Django will escape the output whenever the input is not already marked
as "safe".
- By default, ``is_safe`` defaults to ``False``, and you can omit it from
- any filters where it isn't required.
+ By default, ``is_safe`` is ``False``, and you can omit it from any filters
+ where it isn't required.
Be careful when deciding if your filter really does leave safe strings
as safe. If you're *removing* characters, you might inadvertently leave
@@ -279,12 +283,12 @@ Template filter code falls into one of two situations:
can operate in templates where auto-escaping is either on or off in
order to make things easier for your template authors.
- In order for your filter to know the current auto-escaping state, set
- the ``needs_autoescape`` attribute to ``True`` on your function. (If you
- don't specify this attribute, it defaults to ``False``). This attribute
- tells Django that your filter function wants to be passed an extra
- keyword argument, called ``autoescape``, that is ``True`` if
- auto-escaping is in effect and ``False`` otherwise.
+ In order for your filter to know the current auto-escaping state, set the
+ ``needs_autoescape`` flag to ``True`` when you register your filter function.
+ (If you don't specify this flag, it defaults to ``False``). This flag tells
+ Django that your filter function wants to be passed an extra keyword
+ argument, called ``autoescape``, that is ``True`` if auto-escaping is in
+ effect and ``False`` otherwise.
For example, let's write a filter that emphasizes the first character of
a string:
@@ -294,6 +298,7 @@ Template filter code falls into one of two situations:
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
+ @register.filter(needs_autoescape=True)
def initial_letter_filter(text, autoescape=None):
first, other = text[0], text[1:]
if autoescape:
@@ -302,27 +307,45 @@ Template filter code falls into one of two situations:
esc = lambda x: x
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
return mark_safe(result)
- initial_letter_filter.needs_autoescape = True
- The ``needs_autoescape`` attribute on the filter function and the
- ``autoescape`` keyword argument mean that our function will know whether
- automatic escaping is in effect when the filter is called. We use
- ``autoescape`` to decide whether the input data needs to be passed
- through ``django.utils.html.conditional_escape`` or not. (In the latter
- case, we just use the identity function as the "escape" function.) The
- ``conditional_escape()`` function is like ``escape()`` except it only
- escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
- instance is passed to ``conditional_escape()``, the data is returned
- unchanged.
+ The ``needs_autoescape`` flag and the ``autoescape`` keyword argument mean
+ that our function will know whether automatic escaping is in effect when the
+ filter is called. We use ``autoescape`` to decide whether the input data
+ needs to be passed through ``django.utils.html.conditional_escape`` or not.
+ (In the latter case, we just use the identity function as the "escape"
+ function.) The ``conditional_escape()`` function is like ``escape()`` except
+ it only escapes input that is **not** a ``SafeData`` instance. If a
+ ``SafeData`` instance is passed to ``conditional_escape()``, the data is
+ returned unchanged.
Finally, in the above example, we remember to mark the result as safe
so that our HTML is inserted directly into the template without further
escaping.
- There's no need to worry about the ``is_safe`` attribute in this case
+ There's no need to worry about the ``is_safe`` flag in this case
(although including it wouldn't hurt anything). Whenever you manually
handle the auto-escaping issues and return a safe string, the
- ``is_safe`` attribute won't change anything either way.
+ ``is_safe`` flag won't change anything either way.
+
+.. versionchanged:: 1.4
+
+``is_safe`` and ``needs_autoescape`` used to be attributes of the filter
+function; this syntax is deprecated.
+
+.. code-block:: python
+
+ @register.filter
+ def myfilter(value):
+ return value
+ myfilter.is_safe = True
+
+.. code-block:: python
+
+ @register.filter
+ def initial_letter_filter(text, autoescape=None):
+ # ...
+ return mark_safe(result)
+ initial_letter_filter.needs_autoescape = True
Writing custom template tags
----------------------------
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index f50b0423e5..603f20dbab 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -251,6 +251,9 @@ these changes.
:mod:`django.core.management`. This also means that the old (pre-1.4)
style of :file:`manage.py` file will no longer work.
+* Setting the ``is_safe`` and ``needs_autoescape`` flags as attributes of
+ template filter functions will no longer be supported.
+
2.0
---