jinja2 how to remove trailing newline

PythonYamlJinja2Newline

Python Problem Overview


I'm using jinja 2 to output a yaml file but can't seem to get rid of a trailing newline and the end of a for loop. Eg the below

 - request:
        path: {{ path }}
        headers:
          origin: 'somedomain.com'
          user-agent: 'agent'
          referer: 'some.domain.com'
          authority: 'somedomain.com'
        querystring:
          {% for key, value in querystring.items() -%}
          {{ key }}: '{{ value }}'
          {% endfor %}
      response:
        content:
          file: {{ content }}

gives me the output:

- request:
    path: /some/path
    headers:
      origin: 'somedomain.com'
      user-agent: 'agent'
      referer: 'somedomain.com'
      authority: 'somedomain.com'
    querystring:
      postcode: 'xxxxxx'
      houseNo: '55'
      
  response:
    content:
      file: address.json

With an additional unwanted blank line after houseNo. How do I get rid of this line?

Python Solutions


Solution 1 - Python

Change your loop to strip whitespace from the top AND bottom of the output (notice extra - at the for loop close):

{% for key, value in querystring.items() -%}
  {{ key }}: '{{ value }}'
{%- endfor %}

In my tests (using https://github.com/abourguignon/jinja2-live-parser), the - must come after the first {%, not before the last to achieve what you're asking for.

Docs: https://jinja.palletsprojects.com/en/latest/templates/#whitespace-control

Solution 2 - Python

I think you can get rid of it using the whitespace control feature. Thus I would modify the endfor block to {% endfor -%}

See if that does it!

Solution 3 - Python

For those using Flask who arrive here, these lines did the trick for me:

app = Flask(__name__)
app.jinja_env.lstrip_blocks = True
app.jinja_env.trim_blocks = True

Solution 4 - Python

I found a way to solve this problem:

- request:
    path: {{ path }}
    headers:
      origin: 'somedomain.com'
      user-agent: 'agent'
      referer: 'some.domain.com'
      authority: 'somedomain.com'
    querystring: >-
      {% for key, value in querystring.items() -%}
      {{ key }}: '{{ value }}'
      {% endfor %}
  response:
    content:
      file: {{ content }}
  • >, |: "clip": keep the line feed, remove the trailing blank lines.
  • >-, |=: "strip": remove the line feed, remove the trailing blank lines.
  • >+, |+: "keep": keep the line feed, keep trailing blank lines.

Thx Steve Bennett's post: https://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines/21699210#21699210

Solution 5 - Python

The accepted answer is only half of the solution, because it removes all newlines.

You can avoid the trailing newline by first removing all newlines (using the minus signs at -%} and {%- in the for loop), and then inserting the desired newlines at the right place (using the loop.last condition).

The following templates renders a dictionary, d, to as JSON text:

{
    {% for key, value in d.items() -%}
    "{{ key }}": "{{ value }}"{{ ",
    " if not loop.last }}
    {%- endfor %}
}

For d = {'a':'1', 'b':'2'}, the template renders to

{
    "a": "1",
    "b": "2"
}

Solution 6 - Python

You can suppress rendering of the below lines:

<% for ... %>
<% endfor %>
<% if ... %>
<% endif %>

by setting trim_blocks=True and lstrip_blocks=True in your jinja2 environment. See the example below, info from their docs

context = {'querystring': querystring, 'path': path, 'content': content}    
jinja_env = jinja2.Environment(
    loader=jinja2.FileSystemLoader('templates/'),
    trim_blocks=True,
    lstrip_blocks=True
)
print(jinja_env.get_template('my_template.yaml').render(context))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYuntiView Question on Stackoverflow
Solution 1 - PythontknickmanView Answer on Stackoverflow
Solution 2 - PythonScratch'N'PurrView Answer on Stackoverflow
Solution 3 - PythonMarredCheeseView Answer on Stackoverflow
Solution 4 - PythonZhou Shuai-MingView Answer on Stackoverflow
Solution 5 - PythonKasper DokterView Answer on Stackoverflow
Solution 6 - PythonspacetherView Answer on Stackoverflow