text/template, Text and spaces:的包文件
默认情况下,执行模板时会逐字复制操作之间的所有文本。 [...]
但是,为了帮助格式化模板源代码,如果操作的左分隔符(默认为“{{”)后紧跟一个减号和空格,则所有尾随空格都会从紧接在前面的文本中删除。类似地,如果右分隔符(“}}”)前面有空格和减号,则所有前导空格都会从紧随其后的文本中删除。在这些修剪标记中,必须存在空格:“{{- 3}}”类似于“{{3}}”,但会修剪前面的文本,而“{{-3}}”解析为包含数字 -3。
TLDR; 模板中的所有(空白)空间在动作之间保留。如果您不想要它们,您可以在“就地”操作的开始分隔符之后或结束分隔符之前使用减号- 来修剪前导或尾随空格。
您必须将模板缩进您想要的输出,或使用- 符号来修剪格式缩进。
{{if}} 操作的主要问题:
{{if eq $vv.Id $performedBy}}
{{$pSurname = $vv.ContactData.Surname}} {{$pName = $vv.ContactData.Name}}
{{- end}}
{{if}} 的结束分隔符后有一个换行符,如果{{if}} 的主体被执行,它将被保留。 - 登录 {{- end}} 仅修剪此 {{- end}} 之前的换行符(位于变量分配之后的换行符),而不是位于 {{if}} 末尾的换行符。
例如使用这个模板:
const src = `{{$performedBy := "1"}}{{$pSurname := ""}}{{$pName := "" -}}
{{range $kk, $vv := .Users -}}
User idx: {{$kk}}
{{if eq $vv.Id $performedBy -}}
{{- $pSurname = $vv.ContactData.Surname -}} {{- $pName = $vv.ContactData.Name -}}
{{- end -}}
{{- end}}`
测试它:
type CData struct {
Surname, Name string
}
type User struct {
Id string
ContactData CData
}
func main() {
t := template.Must(template.New("").Parse(src))
p := map[string]interface{}{
"Users": []User{
{Id: "1", ContactData: CData{"Foo", "Bar"}},
{Id: "2", ContactData: CData{"Foo2", "Bar2"}},
{Id: "1", ContactData: CData{"Foo3", "Bar3"}},
{Id: "4", ContactData: CData{"Foo4", "Bar4"}},
},
}
if err := t.Execute(os.Stdout, p); err != nil {
panic(err)
}
}
输出(在Go Playground上试试):
User idx: 0
User idx: 1
User idx: 2
User idx: 3