1

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?

ceving
  • 21,900
  • 13
  • 104
  • 178

2 Answers2

2

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.

ceving
  • 21,900
  • 13
  • 104
  • 178
1

I've got working example only with custom config:

j2_custom.py:

def j2_environment_params():
    """ Extra parameters for the Jinja2 Environment """
    # Jinja2 Environment configuration
    # http://jinja.pocoo.org/docs/2.10/api/#jinja2.Environment
    return dict(
        # Remove whitespace around blocks
        trim_blocks=True,
        lstrip_blocks=True,
    )

j2-template.j2:

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

cli call:

$ j2 j2-template.j2 --customize j2_custom.py
// before
function (arg1,
          arg2,
          arg3)
// after

There is white-space control where you could control lstrip_blocks and trim_blocks manually in template via + and -, but I did not find working example with them.

ujlbu4
  • 1,058
  • 8
  • 8