给定以下模板:
{{ range $item := . }}
{{ if $item.IsA}}
Ok
{{ else }}
Fine
{{ end }}
{{ end }}
Done!
当我使用
渲染时t := template.New("test").Parse(_types)
text, err := t.Execute(&buffer, strct)
输出类似于:
!empty line
!empty line
Ok
!empty line
!empty line
Done!
这意味着如果我想正确地格式化文本,我必须将其重写为
{{ range $item := .}}{{ if $item.IsA }}OK{{ else }}{{ end }}{{ end }}
Done!
然后我得到像这样的东西:
Ok
Done!
这是期望的输出。
用第二种方式写模板是非常不可读和混乱的。是否有任何方法,我们可以用适当的缩进编写模板,但以某种方式配置呈现,使模板占位符不会被转换为新行,或者它们的缩进将被忽略(以便生成所需的输出)?
编辑:使用{- ""}
甚至使整个事情变得更糟!为什么?请考虑以下内容:
{{- range $item := . }}
{{- if $item.IsA }}
{{- "How many spaces??" -}}OK
...
那么让我用另一种方式来表达,golang中是否有任何内置的后处理器可用于模板?
在使用模板一段时间后,我遇到了这个解决方案。为了使模板更简洁,我们可以做一个技巧。模板确实接受自定义函数,诀窍是定义一个indentation
函数:
const _indent = "___START___"
_funcs = template.FuncMap {
"Indent": func(indent int) string {
str := bytes.NewBufferString(_indent)
for i := 0; i < indent; i++ {
str.WriteString(" ")
}
return str.String()
},
}
我们也可以包括一个字符作为缩进,但这里我只需要空格。然后我们需要一个后置处理器:
func PostProcess(strBuffer bytes.Buffer) bytes.Buffer {
buffer := bytes.NewBufferString("")
lines := strings.Split(strBuffer.String(), "n")
for _, line := range lines {
tmp := strings.TrimLeftFunc(line, func(r rune) bool {
return r == ' '
})
tmp = strings.TrimPrefix(tmp, _indent)
buffer.WriteString(tmp)
}
return *buffer
}
现在我们可以将标记写成:
{{ range $i := . }}
{{ if $i.IsOk }}
{{ 4 | Indent }}OK
...
,我们可以在渲染文本上运行PostProcess
函数。我的PostProcess
函数不能消除空行,但是我们也可以很容易地添加它。
这比{{- " " -}}
语法更容易读。