使用go模板缩进和文本格式化



给定以下模板:

{{ 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函数不能消除空行,但是我们也可以很容易地添加它。

这比{{- " " -}}语法更容易读。

最新更新