Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix issue #100 #107

Closed
wants to merge 4 commits into from

2 participants

@njl

No description provided.

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
@njl njl Fix Issue #100, tailing commas in macros args
This change will allow trailing commas in macro definitions, and in
calls to macros.
7b2f718
@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.
  4. @njl

    Fix Issue #100, tailing commas in macros args

    njl authored
    This change will allow trailing commas in macro definitions, and in
    calls to macros.
This page is out of date. Refresh to see the latest.
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
2  jinja2/parser.py
@@ -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'):
View
10 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() == '...'
@@ -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 %}\
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.