Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue #100 #107

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions docs/switching.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
~~~~~
Expand Down
1 change: 1 addition & 0 deletions jinja2/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand Down
7 changes: 6 additions & 1 deletion jinja2/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'):
Expand Down
2 changes: 2 additions & 0 deletions jinja2/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ def parse_signature(self, node):
while self.stream.current.type != 'rparen':
if args:
self.stream.expect('comma')
if self.stream.current.type == 'rparen':
break
arg = self.parse_assign_target(name_only=True)
arg.set_ctx('param')
if self.stream.skip_if('assign'):
Expand Down
10 changes: 10 additions & 0 deletions jinja2/testsuite/core_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -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() == '...'
Expand Down Expand Up @@ -222,6 +226,12 @@ def test_arguments(self):
{{ m() }}|{{ m('a') }}|{{ m('a', 'b') }}|{{ m(1, 2, 3) }}''')
assert tmpl.render() == '||c|d|a||c|d|a|b|c|d|1|2|3|d'

def test_trailing_comma(self):
tmpl = self.env.from_string('''\
{% macro m(a, b,) %}{{ a }}|{{ b }}{% endmacro %}
{{ m(1,2,) }}''')
assert tmpl.render() == '1|2'

def test_varargs(self):
tmpl = self.env.from_string('''\
{% macro test() %}{{ varargs|join('|') }}{% endmacro %}\
Expand Down
10 changes: 10 additions & 0 deletions jinja2/testsuite/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down