From: ThiefMaster Date: Fri, 11 Sep 2015 22:27:07 +0000 (+0200) Subject: Support filters in set block X-Git-Tag: 2.10~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=072cdf97fa2899efe1d12715edf19706b6425fb5;p=thirdparty%2Fjinja.git Support filters in set block - e.g {% set foo | trim %}...{% endset %} - closes #486 --- diff --git a/CHANGES b/CHANGES index 7481a61a..f55718c3 100644 --- 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 diff --git a/docs/templates.rst b/docs/templates.rst index fd3408a7..d10d5e67 100644 --- a/docs/templates.rst +++ b/docs/templates.rst @@ -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: diff --git a/jinja2/compiler.py b/jinja2/compiler.py index a1bc554a..d534a827 100644 --- a/jinja2/compiler.py +++ b/jinja2/compiler.py @@ -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) diff --git a/jinja2/nodes.py b/jinja2/nodes.py index 9b2c9840..4d9a01ad 100644 --- a/jinja2/nodes.py +++ b/jinja2/nodes.py @@ -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): diff --git a/jinja2/parser.py b/jinja2/parser.py index 565e7c0c..ed00d970 100644 --- a/jinja2/parser.py +++ b/jinja2/parser.py @@ -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.""" diff --git a/tests/test_core_tags.py b/tests/test_core_tags.py index 477465fa..3b51e972 100644 --- a/tests/test_core_tags.py +++ b/tests/test_core_tags.py @@ -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 %}{{ test }} ' + '{% endset %}foo: {{ foo }}') + assert tmpl.render(test='') == 'foo: <unsafe>' + + 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_