Search code examples
jinja2jinja2-cli

How to omit an empty line after a for loop in Jinja?


I would like to generate the following output with the j2cli:

// before
function (arg1,
          arg2,
          arg3)
// after

I tried the following template:

// before
function ({% for param in ['arg1', 'arg2', 'arg3'] -%}
          {{param}}{{"," if not loop.last else ")"}}
          {% endfor %}
// after

But it produces always an additional empty line at the end:

// before
function (arg1,
          arg2,
          arg3)
          
// after

When I try this template:

// before
function ({% for param in ['arg1', 'arg2', 'arg3'] -%}
          {{param}}{{"," if not loop.last else ")"}}
          {% endfor -%}
// after

The comment gets indented.

// before
function (arg1,
          arg2,
          arg3)
          // after

This one

// before
function ({% for param in ['arg1', 'arg2', 'arg3'] %}
          {{param}}{{"," if not loop.last else ")"}}
          {%- endfor %}
// after

removes the empty line at the end but produces one at the beginning.

// before
function (
          arg1,
          arg2,
          arg3)
// after

And this one

// before
function ({% for param in ['arg1', 'arg2', 'arg3'] -%}
          {{param}}{{"," if not loop.last else ")"}}
          {%- endfor %}
// after

removes all whitespace.

// before
function (arg1,arg2,arg3)
// after

How to format the function correctly?


Solution

  • I got it: (sometimes it helps to sleep one night)

    // before
    function ({% for param in ['arg1', 'arg2', 'arg3'] -%}
              {{param}}{% if not loop.last %},
              {% endif %}
              {%- endfor %})
    // after
    

    The default of Jinja's for loop does not help here, because it formats every line in the same way. Either at the beginning of every loop or at the end it keeps the combination of newline+indent. But before the first line and after the last line newline+indent are unwanted. The lines can not be formatted uniformly.

    So the solution is to disable the default whitespace handling of the for loop {% for -%}...{%- endfor %} and generate newline+indent after every but the last line manually.

    This is possibly by aligning the endif in the same column as the {{param}}. The - of the endfor just prevents the generation of whitespace and eats the whitespace after the endif but does not eat the whitespace generated by the body of the if.