
Jinja2 模板中调用宏时出现多余空行,根本原因是宏内部的换行符未被自动修剪;需在宏定义内使用 {%- -%} 等空白控制语法,而非仅依赖 trim_blocks 和 lstrip_blocks 全局配置。
jinja2 模板中调用宏时出现多余空行,根本原因是宏内部的换行符未被自动修剪;需在宏定义内使用 `{%- -%}` 等空白控制语法,而非仅依赖 `trim_blocks` 和 `lstrip_blocks` 全局配置。
在 Jinja2 中,trim_blocks=True 和 lstrip_blocks=True 仅作用于宏调用处所在的块级语句(如 {% for %}、{% if %})的起始/结束标签周围,而对宏体(macro body)内部的换行、缩进和空白完全无效。你遇到的每个 {{ print_name(name) }} 后多出的一行,正是宏定义中 {{ data }} 前后换行符(\n)被原样保留所致:
{% macro print_name(data)%}
{{ data }}
{% endmacro %}此处 {{ data }} 上方的换行、下方的换行,以及 {{ data }} 自身渲染后留下的换行,共同导致了输出中 Bob\n\n} 的结构。
✅ 正确解法:在宏内部使用 Jinja2 的空白控制修饰符(whitespace control),即在变量表达式两侧添加短横线 -:
{% macro print_name(data) %}
{{- data -}}
{% endmacro %}
People {
{% for name in names %}
Name {
{{ print_name(name) }}
}
{% endfor %}
}{{- data -}} 表示:
-
-在{{右侧 → 删除{{与其后内容之间的所有空白(含换行); -
-在}}左侧 → 删除}}与其前内容之间的所有空白(含换行)。
这样,宏体内的换行被精准剥离,仅保留 data 渲染值本身,且不破坏外部模板的缩进结构。
⚠️ 注意事项:
- ❌ 不要写成
{{ print_name(name) -}}(仅在调用处加-):这会删掉宏调用后到下一行之间的换行,导致}提前顶格,破坏 YAML/类结构化格式; - ✅ 必须在宏定义内部(即
{{ data }}处)使用{{- data -}},才能根治源头空白; - 若宏返回多行内容(如嵌套结构),可进一步组合
| indent过滤器或使用{%- ... -%}包裹整个宏体逻辑块; -
trim_blocks和lstrip_blocks仍建议保留,它们对循环、条件等外层结构的整洁性仍有价值。
最终输出将严格符合预期,无冗余空行,同时保持清晰缩进:
People {
Name {
Bob
}
Name {
Jason
}
Name {
James
}
}

















