- 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
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:
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)
class AssignBlock(Stmt):
"""Assigns a block to a target."""
- fields = ('target', 'body')
+ fields = ('target', 'filter', 'body')
class Expr(Node):
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."""
'{{ 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><unsafe></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_