Jinja docx模板,避免嵌套

时间:2017-08-16 16:48:59

标签: python jinja2 docx

我想知道是否有办法在带有jinja的docx模板中避免换行中的换行符。代码如下:

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

但结果是按行分隔的帐号:

234090

29292

29292

我正在对LibreOffice进行测试。

有人可以帮助我吗?

5 个答案:

答案 0 :(得分:4)

了解额外的换行符(以及行)来自

Jinja模板中的空格不会被忽略。所以Jinja看到的是

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

它实际上并不太关心线条,所以要做到这一点

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

这就是循环

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

身体

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

请注意开头的外部循环体的其余部分是另一个循环

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

身体

¶{{ account.number }}¶

请注意开头和结尾的

因此,您将在每个单独客户的组帐户之前获得换行符,并在每个帐号之前和之后获得另一个换行符。你可能不想摆脱所有这些,因为这会将所有数字粘在一条线上,而不会有任何分离:

2340902929229292

减轻

除了你想要的换行符之外,你可以避免换行:

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

但这使得模板难以阅读。你可以让Jinja2忽略模板标签之间的空格。为此,请在相关空格之前的标记末尾或该空格(或两者)之后的标记开头添加-

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

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

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

(见Jinja2 documentation

这甚至允许您使用缩进而不会在结果中结束额外的空格:

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

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

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

我已经使用了这样一个事实,即不仅可以在模板标签中使用变量而且还可以使用文字,这样我就可以使用{{ '\n' }}生成换行符。这种风格是必要的,因为吃缩进的-也会吞噬模板源中的(字面文字)换行符。

答案 1 :(得分:2)

您可以禁止渲染以下行:

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

在jinja2环境中设置trim_blocks = True和lstrip_blocks = True。请参阅以下示例,来自their docs

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

答案 2 :(得分:0)

受到das-g答案的启发,我遇到了类似的问题,经过大量的试验和错误后,我放弃并决定永远删除新行但是像他一样手动添加换行符,但前提是不是最后一个索引循环,所以我的宏最终像这样:

{% macro service_envs() %}
{% if app_envs is defined %}
    environment:
{% for env in app_envs %}
      - {{ env }}{% if not loop.last %}{{ '\n' }}{% endif %}
{%- endfor %}
{% endif %}
{% endmacro %}

结果是:

    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - 5432:5432

重要的是删除{% - endfor%}中的空格,但在if语句中添加空格。 所以在我的情况下,空格被保留了,但是我没有列表最后一项的换行符。所以我的下一行就是在环境清单之后。现在,每次调用宏时,我都不需要添加{{ - }}。 使用ansible 2.5.0进行测试

答案 3 :(得分:0)

感谢@ das-g的详细评论。他解释了空间是如何来的,但没有阐明Jinja如何吃掉空白空间。我想在这里为我和其他遇到相同问题的人添加一些评论。

{%-for客户in客户%}:删除for循环块之前的空白

{客户中客户的百分比-%}:删除每个for循环项之前的空白

{%-endfor%}:在每个for循环项目后删除空白

{%endfor-%}:删除for循环块后的空白

简单地说,

{%for%}在此标记后有换行符,即{%for%}¶

{%--%}首先删除标记后的换行符,然后展开循环

endfor标签的想法相同

答案 4 :(得分:0)

如果不需要换行,那么我们可以将语句放在单行中,如下所示: <% for … %><% if … %><% endif %><% endfor %>

使用此Jinj2,解析不会引入新行。