在 StringTemplate 引擎中——我在一些项目中使用它来发出 C 代码——空白前缀会自动添加到输出行中:
PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
if (someRuntimeFlag) {
<linesGlobal>
if (anotherRuntimeFlag) {
<linesLocal>
}
}
}
>>
当在 StringTemplate 中呈现此模板时,会为所有发出的行复制多行 linesGlobal 和linesLocal 字符串的前缀空白。 生成的 C 代码是:
void foo() {
if (someRuntimeFlag) {
int i;
i=1; // <=== whitespace prefix copied in 2nd
i++; // <=== and 3rd line
if (anotherRuntimeFlag) {
int j=i;
j++; // <=== ditto
}
}
}
我是 Jinja2 的新手 - 并试图复制这个:
#!/usr/bin/env python
from jinja2 import Template
linesGlobal='\n'.join(['int i;', 'i=1;'])
linesLocal='\n'.join(['int j=i;', 'j++;'])
tmpl = Template(u'''\
void foo() {
if (someRuntimeFlag) {
{{linesGlobal}}
if (anotherRuntimeFlag) {
{{linesLocal}}
}
}
}
''')
print tmpl.render(
linesGlobal=linesGlobal,
linesLocal=linesLocal)
...但看到它产生了这个:
void foo() {
if (someRuntimeFlag) {
int i;
i=1;
if (anotherRuntimeFlag) {
int j=i;
j++;
}
}
}
……这不是我想要的。 我设法使输出发出正确的空白前缀:
...
if (someRuntimeFlag) {
{{linesGlobal|indent(8)}}
if (anotherRuntimeFlag) {
{{linesLocal|indent(12)}}
}
}
...但这可以说是糟糕的,因为我需要为我发出的每个字符串手动计算空格...
有没有更好的方法让我失踪?
我对基本相同的事情感兴趣。 这个问题也出现在 stackoverflow: http :
+1
使用表单时也是如此:
{{linesGlobal|join('\n')}}
这种形式的行为不像人们预期的那样——因为 jinja2 是发出换行符的形式,它应该确保它们与最后一个缩进级别保持一致。
这将是非常好的! 这将导致更好的模板和同时呈现的输出。
为什么不创建另一个类似于 {%+ 和 {%- 的空白选项,将当前缩进放在它评估的任何内容之前? 可以是 {%= 或 {%|
+1
+1
这里需要模板 API 蓝图文档:
{% macro entity_one() -%}
{
"one": 1,
"two": 2
}
{% endmacro -%}
+ Response 200 (application/json):
{
"entity": [
{{ entity_one() }}
]
}
现在呈现:
+ Response 200 (application/json):
{
"entity": [
{
"one": 1,
"two": 2
}
]
}
当发出 YAML 或 Python 时,这变得非常重要。
遇到了同样的问题。
除了为每个包含的 tempkate 定义一个宏并手动输入缩进之外,现在还有其他解决方法吗?
很抱歉重提这个老问题,我刚刚遇到了同样的问题,谷歌搜索把我带到了这里。 经过更多的环顾四周后,我发现现在有一个很好的方法可以通过缩进过滤器来实现这一点
@kaikuchn谢谢你,伙计! 有用。
@kaikuchn ,@Cigizmoond-Vyhuholev 伙计们,我不确定我是否遵循...正如您在顶部的原始报告中看到的那样,我确实提到了indent
过滤器的解决方法 - 但也明确指出它并没有像 StringTemplate 那样以简单而强大的方式解决这个问题,因为它迫使你每次需要发出一行行时都要计算缩进空间......如果你必须这样做并且你正在生成代码任何形式(C、Python 等等),你很快就会完全放弃这个过程......
再说一次,我可能误解了你的意思......你能确切地分享一下你是如何实现我在顶部显示的原始要求的吗? 即使用 Jinja2 语法生成相同类型的输出? 这是我不喜欢的...
if (someRuntimeFlag) {
{{linesGlobal|indent(8)}}
if (anotherRuntimeFlag) {
{{linesLocal|indent(12)}}
}
}
...因为我需要计算我发出代码的每个模板中的“8”和“12”。 相比之下,在 StringTemplate 中...
PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
if (someRuntimeFlag) {
<linesGlobal>
if (anotherRuntimeFlag) {
<linesLocal>
}
}
}
>>
我注意到 #919 由于代码更改而关闭,这显然需要对 PR 进行一些重大重构。 然而,我真的很想看到这个功能在我最喜欢的模板引擎中实现。
如果这仍然是核心开发人员希望实现的东西(社区肯定想要它,因为它是公关和开放问题,获得最多的赞许)我会很乐意提供帮助,甚至可能尝试自己实现。
也很想看到这个功能。 我会注意到,当缩进级别未知时,不能使用indent
解决方法。 例如:
{{field.type}} {{field.name}}; {{field.comment|indent(??)}}
要保留的缩进级别取决于前两个值的长度。
我有一个假设。 在块声明中左修剪第一级缩进怎么样?
例子:
{%- macro some_yaml_block(sub_block) ~%}
label indented with how many spaces: 2
amount of spaces that will be trimmed due to that "~" char above: 2
{%- if sub_block ~%}
"yay! we can indent ifs!": true
the minimal indent in this if block is 2, so:
this extra-indented value is still indented properly
{%- endif %}
{%- endmacro -%}
now we invoke that here:
{{ some_yaml_block(true) }}
渲染将是:
now we invoke that here:
label indented with how many spaces: 2
amount of spaces that will be trimmed due to that "~" char above: 2
"yay! we can indent ifs!": true
the minimal indent in this if block is 2, so:
this extra-indented value is still indented properly
基本上,当用~%}
完成一个块时,Jinja 会:
newline_sequence
环境参数中所示。如果您稍后需要使用某些特定缩进包含此块,您只需将其命名为some_yaml_block|indent
。 由于缩进在块声明时被规范化,您可以稍后毫无问题地指定它。 并且该块将在调用之间保持一致。
最有用的评论
当发出 YAML 或 Python 时,这变得非常重要。