Skip to content

Commit 072cdf9

Browse files
committed
Support filters in set block
- e.g {% set foo | trim %}...{% endset %} - closes #486
1 parent d17c7db commit 072cdf9

File tree

6 files changed

+49
-3
lines changed

6 files changed

+49
-3
lines changed

CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ Version 2.10
3333
- Add ``reverse`` argument for ``dictsort`` filter. (`#692`_)
3434
- Add a ``NativeEnvironment`` that renders templates to native Python types
3535
instead of strings. (`#708`_)
36+
- Added filter support to the block ``set`` tag. (`#489`_)
3637

3738
.. _#469: https://github.com/pallets/jinja/pull/469
3839
.. _#475: https://github.com/pallets/jinja/pull/475
3940
.. _#478: https://github.com/pallets/jinja/pull/478
41+
.. _#489: https://github.com/pallets/jinja/pull/489
4042
.. _#617: https://github.com/pallets/jinja/pull/617
4143
.. _#618: https://github.com/pallets/jinja/pull/618
4244
.. _#665: https://github.com/pallets/jinja/pull/665

docs/templates.rst

+11
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,17 @@ Example::
947947

948948
The `navigation` variable then contains the navigation HTML source.
949949

950+
.. versionchanged:: 2.10
951+
952+
Starting with Jinja 2.10, the block assignment supports filters.
953+
954+
Example::
955+
956+
{% set reply | wordwrap %}
957+
You wrote:
958+
{{ message }}
959+
{% endset %}
960+
950961

951962
.. _extends:
952963

jinja2/compiler.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,12 @@ def visit_AssignBlock(self, node, frame):
13851385
self.newline(node)
13861386
self.visit(node.target, frame)
13871387
self.write(' = (Markup if context.eval_ctx.autoescape '
1388-
'else identity)(concat(%s))' % block_frame.buffer)
1388+
'else identity)(')
1389+
if node.filter is not None:
1390+
self.visit_Filter(node.filter, block_frame)
1391+
else:
1392+
self.write('concat(%s)' % block_frame.buffer)
1393+
self.write(')')
13891394
self.pop_assign_tracking(frame)
13901395
self.leave_frame(block_frame)
13911396

jinja2/nodes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ class Assign(Stmt):
387387

388388
class AssignBlock(Stmt):
389389
"""Assigns a block to a target."""
390-
fields = ('target', 'body')
390+
fields = ('target', 'filter', 'body')
391391

392392

393393
class Expr(Node):

jinja2/parser.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,10 @@ def parse_set(self):
180180
if self.stream.skip_if('assign'):
181181
expr = self.parse_tuple()
182182
return nodes.Assign(target, expr, lineno=lineno)
183+
filter_node = self.parse_filter(None)
183184
body = self.parse_statements(('name:endset',),
184185
drop_needle=True)
185-
return nodes.AssignBlock(target, body, lineno=lineno)
186+
return nodes.AssignBlock(target, filter_node, body, lineno=lineno)
186187

187188
def parse_for(self):
188189
"""Parse a for loop."""

tests/test_core_tags.py

+27
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,33 @@ def test_namespace_macro(self, env_trim):
453453
'{{ ns.a }}|{{ ns.b }}')
454454
assert tmpl.render() == '13|37'
455455

456+
def test_block_escaping_filtered(self):
457+
env = Environment(autoescape=True)
458+
tmpl = env.from_string('{% set foo | trim %}<em>{{ test }}</em> '
459+
'{% endset %}foo: {{ foo }}')
460+
assert tmpl.render(test='<unsafe>') == 'foo: <em>&lt;unsafe&gt;</em>'
461+
462+
def test_block_filtered(self, env_trim):
463+
tmpl = env_trim.from_string(
464+
'{% set foo | trim | length | string %} 42 {% endset %}'
465+
'{{ foo }}')
466+
assert tmpl.render() == '2'
467+
assert tmpl.module.foo == u'2'
468+
469+
def test_block_filtered_set(self, env_trim):
470+
def _myfilter(val, arg):
471+
assert arg == ' xxx '
472+
return val
473+
env_trim.filters['myfilter'] = _myfilter
474+
tmpl = env_trim.from_string(
475+
'{% set a = " xxx " %}'
476+
'{% set foo | myfilter(a) | trim | length | string %}'
477+
' {% set b = " yy " %} 42 {{ a }}{{ b }} '
478+
'{% endset %}'
479+
'{{ foo }}')
480+
assert tmpl.render() == '11'
481+
assert tmpl.module.foo == u'11'
482+
456483

457484
@pytest.mark.core_tags
458485
@pytest.mark.with_

0 commit comments

Comments
 (0)