Permalink
Browse files

added with-statement extension.

--HG--
branch : trunk
  • Loading branch information...
1 parent 8e64adf commit 9b4cc9ff08b2a80c948c442344b6fca1650e64e6 @mitsuhiko mitsuhiko committed Feb 7, 2010
Showing with 81 additions and 0 deletions.
  1. +1 −0 CHANGES
  2. +14 −0 docs/extensions.rst
  3. +32 −0 docs/templates.rst
  4. +22 −0 jinja2/ext.py
  5. +12 −0 tests/test_ext.py
View
@@ -19,6 +19,7 @@ Version 2.3
This change makes ``{% if %}...{% endif %}`` a syntax error
now. (#364)
- added support for translator comments if extracted via babel.
+- added with-statement extension.
Version 2.2.1
-------------
View
@@ -112,6 +112,20 @@ This extension adds support for `break` and `continue` in loops. After
enabling Jinja2 provides those two keywords which work exactly like in
Python.
+.. _with-extension:
+
+With Statement
+--------------
+
+**Import name:** `jinja2.ext.with_`
+
+.. versionadded:: 2.3
+
+This extension adds support for the with keyword. Using this keyword it
+is possible to enforce a nested scope in a template. Variables can be
+declared directly in the opening block of the with statement or using a
+standard `set` statement directly within.
+
.. _writing-extensions:
View
@@ -1252,3 +1252,35 @@ Likewise a look that stops processing after the 10th iteration::
{% for user in users %}
{%- if loop.index >= 10 %}{% break %}{% endif %}
{%- endfor %}
+
+
+With Statement
+~~~~~~~~~~~~~~
+
+.. versionadded:: 2.3
+
+If the application enables the :ref:`with-extension` it is possible to
+use the `with` keyword in templates. This makes it possible to create
+a new inner scope. Variables set within this scope are not visible
+outside of the scope.
+
+With in a nutshell::
+
+ {% with %}
+ {% set foo = 42 %}
+ {{ foo }} foo is 42 here
+ {% endwith %}
+ foo is not visible here any longer
+
+Because it is common to set variables at the beginning of the scope
+you can do that within the with statement. The following two examples
+are equivalent::
+
+ {% with foo = 42 %}
+ {{ foo }}
+ {% endwith %}
+
+ {% with %}
+ {% set foo = 42 %}
+ {{ foo }}
+ {% endwith %}
View
@@ -336,6 +336,27 @@ def parse(self, parser):
return nodes.Continue(lineno=token.lineno)
+class WithExtension(Extension):
+ """Adds support for a django-like with block."""
+ tags = set(['with'])
+
+ def parse(self, parser):
+ node = nodes.Scope(lineno=next(parser.stream).lineno)
+ assignments = []
+ while parser.stream.current.type != 'block_end':
+ lineno = parser.stream.current.lineno
+ if assignments:
+ parser.stream.expect('comma')
+ target = parser.parse_assign_target()
+ parser.stream.expect('assign')
+ expr = parser.parse_expression()
+ assignments.append(nodes.Assign(target, expr, lineno=lineno))
+ node.body = assignments + \
+ list(parser.parse_statements(('name:endwith',),
+ drop_needle=True))
+ return node
+
+
def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS,
babel_style=True):
"""Extract localizable strings from the given template node. Per
@@ -507,3 +528,4 @@ def babel_extract(fileobj, keywords, comment_tags, options):
i18n = InternationalizationExtension
do = ExprStmtExtension
loopcontrols = LoopControlExtension
+with_ = WithExtension
View
@@ -106,6 +106,18 @@ def test_do():
assert tmpl.render() == '0f, 1o, 2o'
+def test_with():
+ env = Environment(extensions=['jinja2.ext.with_'])
+ tmpl = env.from_string('''\
+ {% with a=42, b=23 -%}
+ {{ a }} = {{ b }}
+ {% endwith -%}
+ {{ a }} = {{ b }}\
+ ''')
+ assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] \
+ == ['42 = 23', '1 = 2']
+
+
def test_extension_nodes():
env = Environment(extensions=[TestExtension])
tmpl = env.from_string('{% test %}')

0 comments on commit 9b4cc9f

Please sign in to comment.