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

Closed
wants to merge 3 commits into
from
View
@@ -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
@@ -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
@@ -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'):
@@ -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() == '...'
@@ -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(