]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
Support filters in set block 489/head
authorThiefMaster <adrian@planetcoding.net>
Fri, 11 Sep 2015 22:27:07 +0000 (00:27 +0200)
committerAdrian Moennich <adrian@planetcoding.net>
Tue, 31 Oct 2017 22:04:45 +0000 (23:04 +0100)
- e.g {% set foo | trim %}...{% endset %}
- closes #486

CHANGES
docs/templates.rst
jinja2/compiler.py
jinja2/nodes.py
jinja2/parser.py
tests/test_core_tags.py

diff --git a/CHANGES b/CHANGES
index 7481a61a6eeed086e35e6b673a747d1dfacf14a6..f55718c3d4e01bab1bace2b84f4bdd36004555a8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -33,10 +33,12 @@ Version 2.10
 - Add ``reverse`` argument for ``dictsort`` filter. (`#692`_)
 - Add a ``NativeEnvironment`` that renders templates to native Python types
   instead of strings. (`#708`_)
+- Added filter support to the block ``set`` tag. (`#489`_)
 
 .. _#469: https://github.com/pallets/jinja/pull/469
 .. _#475: https://github.com/pallets/jinja/pull/475
 .. _#478: https://github.com/pallets/jinja/pull/478
+.. _#489: https://github.com/pallets/jinja/pull/489
 .. _#617: https://github.com/pallets/jinja/pull/617
 .. _#618: https://github.com/pallets/jinja/pull/618
 .. _#665: https://github.com/pallets/jinja/pull/665
index fd3408a76d342cfedefd436b6736d4da66149e2b..d10d5e6729bb84811a1409ff4b6819e1c914836a 100644 (file)
@@ -947,6 +947,17 @@ Example::
 
 The `navigation` variable then contains the navigation HTML source.
 
+.. versionchanged:: 2.10
+
+Starting with Jinja 2.10, the block assignment supports filters.
+
+Example::
+
+    {% set reply | wordwrap %}
+        You wrote:
+        {{ message }}
+    {% endset %}
+
 
 .. _extends:
 
index a1bc554ad208dfbbc382e749c17d0dd53eca12bf..d534a827391aeb6f81f94c1ce5688af8d05c5505 100644 (file)
@@ -1385,7 +1385,12 @@ class CodeGenerator(NodeVisitor):
         self.newline(node)
         self.visit(node.target, frame)
         self.write(' = (Markup if context.eval_ctx.autoescape '
-                   'else identity)(concat(%s))' % block_frame.buffer)
+                   'else identity)(')
+        if node.filter is not None:
+            self.visit_Filter(node.filter, block_frame)
+        else:
+            self.write('concat(%s)' % block_frame.buffer)
+        self.write(')')
         self.pop_assign_tracking(frame)
         self.leave_frame(block_frame)
 
index 9b2c98405a8056cb8528d3cecc58d55b70b7c0a1..4d9a01ad8bb2e7b0b63ed483e7c4c34ed0a22033 100644 (file)
@@ -387,7 +387,7 @@ class Assign(Stmt):
 
 class AssignBlock(Stmt):
     """Assigns a block to a target."""
-    fields = ('target', 'body')
+    fields = ('target', 'filter', 'body')
 
 
 class Expr(Node):
index 565e7c0c0e3935564886f46e6a79c99dd334c942..ed00d9708e962f16c6b9ce061be47068d9b9b1ad 100644 (file)
@@ -180,9 +180,10 @@ class Parser(object):
         if self.stream.skip_if('assign'):
             expr = self.parse_tuple()
             return nodes.Assign(target, expr, lineno=lineno)
+        filter_node = self.parse_filter(None)
         body = self.parse_statements(('name:endset',),
                                      drop_needle=True)
-        return nodes.AssignBlock(target, body, lineno=lineno)
+        return nodes.AssignBlock(target, filter_node, body, lineno=lineno)
 
     def parse_for(self):
         """Parse a for loop."""
index 477465fa101b01b76df3eb3c45a59c9c19bd6143..3b51e972248d96fd66f9dc188a859eb6bbce8631 100644 (file)
@@ -453,6 +453,33 @@ class TestSet(object):
                                     '{{ ns.a }}|{{ ns.b }}')
         assert tmpl.render() == '13|37'
 
+    def test_block_escaping_filtered(self):
+        env = Environment(autoescape=True)
+        tmpl = env.from_string('{% set foo | trim %}<em>{{ test }}</em>    '
+                               '{% endset %}foo: {{ foo }}')
+        assert tmpl.render(test='<unsafe>') == 'foo: <em>&lt;unsafe&gt;</em>'
+
+    def test_block_filtered(self, env_trim):
+        tmpl = env_trim.from_string(
+            '{% set foo | trim | length | string %} 42    {% endset %}'
+            '{{ foo }}')
+        assert tmpl.render() == '2'
+        assert tmpl.module.foo == u'2'
+
+    def test_block_filtered_set(self, env_trim):
+        def _myfilter(val, arg):
+            assert arg == ' xxx '
+            return val
+        env_trim.filters['myfilter'] = _myfilter
+        tmpl = env_trim.from_string(
+            '{% set a = " xxx " %}'
+            '{% set foo | myfilter(a) | trim | length | string %}'
+            ' {% set b = " yy " %} 42 {{ a }}{{ b }}   '
+            '{% endset %}'
+            '{{ foo }}')
+        assert tmpl.render() == '11'
+        assert tmpl.module.foo == u'11'
+
 
 @pytest.mark.core_tags
 @pytest.mark.with_