Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja docx template, avoiding new line in nested for

I was wondering if there is a way to avoid newline characters inside a for in a docx template with jinja. The code is as follows:

{% for customer in customers %}
{% for account in customer.accounts %}
{{ account.number }}
{% endfor %}{% endfor %}. 

But the result is account numbers separated by row:

234090

29292

29292

I'm testing on LibreOffice.

Could someone help me?

like image 532
Patterson Junior Avatar asked Aug 16 '17 16:08

Patterson Junior


People also ask

What is the difference between Jinja and Jinja2?

from_string . Jinja 2 provides a Template class that can be used to do the same, but with optional additional configuration. Jinja 1 performed automatic conversion of bytes in a given encoding into unicode objects.

What is jinja2templates?

A Jinja template file is a text file that does not have a particular extension. We will be using the . html extension with the template files because they will also include HTML syntax.


1 Answers

understanding where the extra linebreaks (and thus lines) come from

Whitespace in a Jinja template isn't being ignored. So what Jinja sees is

{% for customer in customers %}¶
{% for account in customer.accounts %}¶
{{ account.number }}¶
{% endfor %}{% endfor %}.·¶

And it actually doesn't care about lines too much, so make that

{% for customer in customers %}¶{% for account in customer.accounts %}¶{{ account.number }}¶{% endfor %}{% endfor %}.·¶

So that is the loop

{% for customer in customers %}…{% endfor %}.·

with body

¶{% for account in customer.accounts %}¶{{ account.number }}¶{% endfor %}

Note the at the beginning. The rest of the outer loop's body is another loop

{% for account in customer.accounts %}…{% endfor %}

with body

¶{{ account.number }}¶

Note the s at the beginning and end.

So you'll get a line break before the group accounts of each separate customer, and another line break before and after each account number. You probably don't want to get rid of all of them, because that would glue all the numbers together on a single line without any separation:

2340902929229292

mitigation

You can just avoid the line breaks except for the ones you want:

{% for customer in customers %}{% for account in customer.accounts %}{{ account.number }}¶
{% endfor %}{% endfor %}.·¶

That makes the template hard to read, though. You can let Jinja2 ignore whitespace between template tags. To do that, add a - at the end of the tag preceding the whitespace in question or at the beginning of the tag following that whitespace (or both):

{% for customer in customers -%}
{% for account in customer.accounts -%}
{{ account.number }}
{% endfor -%}
{% endfor %}. 

or

{% for customer in customers %}
{%- for account in customer.accounts %}
{{- account.number }}
{%- endfor %}
{% endfor %}. 

or

{% for customer in customers -%}
{%- for account in customer.accounts -%}
{{- account.number }}
{% endfor -%}
{%- endfor %}. 

(See Jinja2 documentation)

This even allows you to use indentation without having that additional whitespace end up in the result:

{% for customer in customers -%}
  {% for account in customer.accounts -%}
    {{ account.number }}{{ '\n' -}}
  {% endfor -%}
{% endfor %}. 

or

{% for customer in customers %}
  {%- for account in customer.accounts %}
    {{- account.number }}{{ '\n' }}
  {%- endfor %}
{% endfor %}. 

or

{% for customer in customers -%}
  {%- for account in customer.accounts -%}
    {{- account.number }}{{ '\n' -}}
  {% endfor -%}
{%- endfor %}. 

I've used the fact that not just variables but also literals can be used in template tags, so that I can produce a line break with {{ '\n' }}. This is necessary with this style, as a - to eat the indentation would swallow the (literal literal) line break in your template source, too.

like image 189
das-g Avatar answered Sep 22 '22 14:09

das-g