Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix to #86, Nested For Loop in else #105

Closed
wants to merge 3 commits into from

2 participants

@njl

This definitely needs close review by @mitsuhiko, modifies python generated by Jinja2.

njl added some commits
@njl njl Fix to #93, this time respecting whitespace
Rejigger of title split to respect whitespace, also capitalize follow-on
hyphenated words.
8f0c8ee
@njl njl Fixes issue #77 by adding explanation to docs
Points out that the Django empty is replaced by the
Flask else.
7336b7a
@njl njl Fix to issue #86, nested loop in a loop else tag
The generated code assumed that l_loop exists inside the if statement
following the for loop. If the LoopContext doesn't have anything,
the l_loop won't be defined, and stuff blows up.
f6f3704
@mitsuhiko mitsuhiko closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 13, 2012
  1. @njl

    Fix to #93, this time respecting whitespace

    njl authored
    Rejigger of title split to respect whitespace, also capitalize follow-on
    hyphenated words.
  2. @njl

    Fixes issue #77 by adding explanation to docs

    njl authored
    Points out that the Django empty is replaced by the
    Flask else.
  3. @njl

    Fix to issue #86, nested loop in a loop else tag

    njl authored
    The generated code assumed that l_loop exists inside the if statement
    following the for loop. If the LoopContext doesn't have anything,
    the l_loop won't be defined, and stuff blows up.
This page is out of date. Refresh to see the latest.
View
22 docs/switching.rst
@@ -177,9 +177,25 @@ operator. Here are some examples::
Loops
~~~~~
-For loops work very similar to Django, the only incompatibility is that in
-Jinja2 the special variable for the loop context is called `loop` and not
-`forloop` like in Django.
+For loops work very similar to Django. Notably, in Jinja2 the special variable for
+the loop context is called `loop` and not `forloop` like in Django.
+
+In addition, the Django `empty` argument is called `else` in Jinja2. For example, the
+Django template::
+
+ {% for item in items %}
+ {{item}}
+ {% empty %}
+ No items!
+ {% endfor %}
+
+would be handled in Flask as::
+
+ {% for item in items %}
+ {{item}}
+ {% else %}
+ No items!
+ {% endfor %}
Cycle
~~~~~
View
1  jinja2/compiler.py
@@ -1068,6 +1068,7 @@ def visit_For(self, node, frame):
# make sure the loop variable is a special one and raise a template
# assertion error if a loop tries to write to loop
if extended_loop:
+ self.writeline('l_loop = None')
loop_frame.identifiers.add_special('loop')
for name in node.find_all(nodes.Name):
if name.ctx == 'store' and name.name == 'loop':
View
7 jinja2/filters.py
@@ -176,7 +176,12 @@ def do_title(s):
"""Return a titlecased version of the value. I.e. words will start with
uppercase letters, all remaining characters are lowercase.
"""
- return soft_unicode(s).title()
+ rv = []
+ for item in re.compile(r'([-\s]+)(?u)').split(s):
+ if not item:
+ continue
+ rv.append(item[0].upper() + item[1:])
+ return ''.join(rv)
def do_dictsort(value, case_sensitive=False, by='key'):
View
4 jinja2/testsuite/core_tags.py
@@ -24,6 +24,10 @@ def test_simple(self):
tmpl = env.from_string('{% for item in seq %}{{ item }}{% endfor %}')
assert tmpl.render(seq=range(10)) == '0123456789'
+ def test_embedded_for_in_else(self):
+ tmpl = env.from_string('{% for item in seq %}{{ loop.index0 }}{% else %}{% for i in range(3) %}{{ i }}{% endfor %}{% endfor %}')
+ assert tmpl.render(seq=[]) == '012'
+
def test_else(self):
tmpl = env.from_string('{% for item in seq %}XXX{% else %}...{% endfor %}')
assert tmpl.render() == '...'
View
10 jinja2/testsuite/filters.py
@@ -193,6 +193,16 @@ def test_string(self):
def test_title(self):
tmpl = env.from_string('''{{ "foo bar"|title }}''')
assert tmpl.render() == "Foo Bar"
+ tmpl = env.from_string('''{{ "foo's bar"|title }}''')
+ assert tmpl.render() == "Foo's Bar"
+ tmpl = env.from_string('''{{ "foo bar"|title }}''')
+ assert tmpl.render() == "Foo Bar"
+ tmpl = env.from_string('''{{ "f bar f"|title }}''')
+ assert tmpl.render() == "F Bar F"
+ tmpl = env.from_string('''{{ "foo-bar"|title }}''')
+ assert tmpl.render() == "Foo-Bar"
+ tmpl = env.from_string('''{{ "foo\tbar"|title }}''')
+ assert tmpl.render() == "Foo\tBar"
def test_truncate(self):
tmpl = env.from_string(
Something went wrong with that request. Please try again.