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
}
}