模板是咱们经常使用的手段用于动态生成页面,或者用于代码生成器的编写等。好比把数据库的表映射成go
语言的struct
,这些体力活,写个代码生成器是最合适不过的了.
示例例把表转成 struct :golang
固然这篇帖子不是写关于代码生成器的,是详细说一下go
的Template
,对Template
的操做熟悉了后,就能够利用他实现你想要的一些功能。数据库
{{.}}
来渲染对象自己,对象内部的字段能够{{.field}}
好比下面,我是用一个 map
来存储的数据,访问key: name
,并使用{{.}}
来把 map
打印出来 eg:数组
tmpl, err := template.New("test").Parse(`hello {{.name}}!
obj: {{.}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, map[string]interface{}{
"name": "world", "age": 18})
if err != nil {
panic(err)
}
复制代码
输出bash
hello world!
obj: map[age:18 name:world]
复制代码
结构体内的字段也是用{{.field}}
ui
tmpl, err := template.New("test").Parse(`hello {{.Name}}!
obj: {{.}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "li", Age: 18})
if err != nil {
panic(err)
}
复制代码
在{{}}
内添加 -
能够去掉空格spa
{{- }}
去掉左边全部的空格{{ -}}
去掉右边全部的空格{{- -}}
去掉两边全部的空格 eg:
tmpl, err := template.New("test").Parse(`hello: {{- .Name}}
age: {{.Age -}} !!!
obj:
{{- . -}} end.`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "li", Age: 18})
if err != nil {
panic(err)
}
复制代码
hello:
后面的空格到{{- .Name}}
之间的空格会被去掉.{{.Age -}}
到 !!!
之间的空格会被去掉obj:
到{{- . -}}
到 end.
之间的空格都会被去掉。hello:li
age: 18!!!
obj:{li 18}end.
复制代码
除了能够直接使用go
的对象,也能够直接在模板中定义变量{{ $var := }}
,变量定义后,能够在模板内其余任意地方使用:code
tmpl, err := template.New("test").Parse(`{{$a := "li"}} hello {{$a}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
panic(err)
}
复制代码
输出cdn
hello li
复制代码
方法能够分为全局方法和结构体方法还有内置方法,内置方法也是全局方法的一种对象
template.FuncMap
是一个map
里面的value
必需是方法,传入的值的参数没有限制blog
type FuncMap map[string]interface{}
复制代码
好比:定义一个ReplaceAll
方法,替换全部的指定字符串 例子中把全部的zhang
替换成li
tmpl, err := template.New("test").Funcs(template.FuncMap{
"ReplaceAll": func(src string, old, new string) string {
return strings.ReplaceAll(src, old, new)
},
}).Parse(`func replace: {{ReplaceAll .Name "zhang" "li"}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "zhang_san zhang_si", Age: 18})
if err != nil {
panic(err)
}
复制代码
输出
func replace: li_san li_si
复制代码
模板有一些内置方法好比 call
printf
等,和全局方法同样,直接调用就行
tmpl, err := template.New("test").Parse(`{{printf "name: %s age: %d" .Name .Age}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Age int
}{Name: "li", Age: 18})
if err != nil {
panic(err)
}
复制代码
输出
name: li age: 18
复制代码
经常使用的行为有if
range
template
等
判断 {{if }} {{end}}
,能够用于字符串
bool
或者数值类型
当 字符串有数据
或者bool
值为true
或者数值类型
大于0
时为真
tmpl, err := template.New("test").Parse(`
name: {{.Name}}
{{- if .Name}}
string .Name true
{{else}}
string .Name false
{{end -}}
desc: {{.Desc}}
{{- if .Desc}}
string .Desc true
{{else}}
string .Desc false
{{end -}}
age: {{.Age}}
{{- if .Age}}
number .Age true
{{else}}
number .Age true false
{{end -}}
isAdmin: {{.IsAdmin}}
{{- if .Age}}
bool .IsAdmin true
{{else}}
bool .IsAdmin true false
{{end}}
`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, struct {
Name string
Desc string
Age int
IsAdmin bool
}{Name: "", Desc: "xyz", Age: 18, IsAdmin: true})
if err != nil {
panic(err)
}
复制代码
输出:
name:
string .Name false
desc: xyz
string .Desc true
age: 18
number .Age true
isAdmin: true
bool .IsAdmin true
复制代码
range
用于遍例数组,和go
的 range
同样,能够直接获得每一个变量,或者获得 index
和value
tmpl, err := template.New("test").Parse(`
{{range .val}} {{.}} {{end}}
{{range $idx, $value := .val}} id: {{$idx}}: {{$value}} {{end}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, map[string]interface{}{
"val": []string{"a", "b", "c", "d"}})
if err != nil {
panic(err)
}
复制代码
输出
a b c d
id: 0: a id: 1: b id: 2: c id: 3: d
复制代码
除了能够在自定义对象还能够自定义内嵌的模板{{define "name"}}
,也能够传参数
tmpl, err := template.New("test").Parse(`
{{define "content"}} hello {{.}} {{end}}
content: {{template "content" "zhang san"}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
panic(err)
}
复制代码
在调用时{{template "content" "zhang san"}}
传递了参数 zhang san
输出:
content: hello zhang san
复制代码
模板的注释: {{/* comment */}}
tmpl, err := template.New("test").Parse(`
{{/* 注释 */}}
{{define "content"}} hello {{.}} {{end}}
content: {{template "content" "zhang san"}}`)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, nil)
if err != nil {
panic(err)
}
复制代码