Fixed #34577 -- Added escapeseq template filter.

This commit is contained in:
Arthur Moreira 2023-05-19 19:33:51 -03:00 committed by Mariusz Felisiak
parent 98f6ada0e2
commit 061a8a1bd8
5 changed files with 91 additions and 1 deletions

View File

@ -108,6 +108,7 @@ answer newbie questions, and generally made Django that much better:
Arthur <avandorp@gmail.com>
Arthur Jovart <arthur@jovart.com>
Arthur Koziel <http://arthurkoziel.com>
Arthur Moreira <moreirarthur96@gmail.com>
Arthur Rio <arthur.rio44@gmail.com>
Arvis Bickovskis <viestards.lists@gmail.com>
Arya Khaligh <bartararya@gmail.com>

View File

@ -444,6 +444,16 @@ def escape_filter(value):
return conditional_escape(value)
@register.filter(is_safe=True)
def escapeseq(value):
"""
An "escape" filter for sequences. Mark each element in the sequence,
individually, as a string that should be auto-escaped. Return a list with
the results.
"""
return [conditional_escape(obj) for obj in value]
@register.filter(is_safe=True)
@stringfilter
def force_escape(value):

View File

@ -1831,6 +1831,8 @@ For example, you can apply ``escape`` to fields when :ttag:`autoescape` is off:
{{ title|escape }}
{% endautoescape %}
To escape each element of a sequence, use the :tfilter:`escapeseq` filter.
.. templatefilter:: escapejs
``escapejs``
@ -1849,6 +1851,23 @@ For example:
If ``value`` is ``"testing\r\njavascript 'string\" <b>escaping</b>"``,
the output will be ``"testing\\u000D\\u000Ajavascript \\u0027string\\u0022 \\u003Cb\\u003Eescaping\\u003C/b\\u003E"``.
.. templatefilter:: escapeseq
``escapeseq``
-------------
.. versionadded:: 5.0
Applies the :tfilter:`escape` filter to each element of a sequence. Useful in
conjunction with other filters that operate on sequences, such as
:tfilter:`join`. For example:
.. code-block:: html+django
{% autoescape off %}
{{ my_list|escapeseq|join:", " }}
{% endautoescape %}
.. templatefilter:: filesizeformat
``filesizeformat``

View File

@ -345,7 +345,8 @@ Signals
Templates
~~~~~~~~~
* ...
* The new :tfilter:`escapeseq` template filter applies :tfilter:`escape` to
each element of a sequence.
Tests
~~~~~

View File

@ -0,0 +1,59 @@
from django.test import SimpleTestCase
from django.utils.safestring import mark_safe
from ..utils import setup
class EscapeseqTests(SimpleTestCase):
"""
The "escapeseq" filter works the same whether autoescape is on or off,
and has no effect on strings already marked as safe.
"""
@setup(
{
"escapeseq_basic": (
'{{ a|escapeseq|join:", " }} -- {{ b|escapeseq|join:", " }}'
),
}
)
def test_basic(self):
output = self.engine.render_to_string(
"escapeseq_basic",
{"a": ["x&y", "<p>"], "b": [mark_safe("x&y"), mark_safe("<p>")]},
)
self.assertEqual(output, "x&amp;y, &lt;p&gt; -- x&y, <p>")
@setup(
{
"escapeseq_autoescape_off": (
'{% autoescape off %}{{ a|escapeseq|join:", " }}'
" -- "
'{{ b|escapeseq|join:", "}}{% endautoescape %}'
)
}
)
def test_autoescape_off(self):
output = self.engine.render_to_string(
"escapeseq_autoescape_off",
{"a": ["x&y", "<p>"], "b": [mark_safe("x&y"), mark_safe("<p>")]},
)
self.assertEqual(output, "x&amp;y, &lt;p&gt; -- x&y, <p>")
@setup({"escapeseq_join": '{{ a|escapeseq|join:"<br/>" }}'})
def test_chain_join(self):
output = self.engine.render_to_string("escapeseq_join", {"a": ["x&y", "<p>"]})
self.assertEqual(output, "x&amp;y<br/>&lt;p&gt;")
@setup(
{
"escapeseq_join_autoescape_off": (
'{% autoescape off %}{{ a|escapeseq|join:"<br/>" }}{% endautoescape %}'
),
}
)
def test_chain_join_autoescape_off(self):
output = self.engine.render_to_string(
"escapeseq_join_autoescape_off", {"a": ["x&y", "<p>"]}
)
self.assertEqual(output, "x&amp;y<br/>&lt;p&gt;")