模闆是我們常用的手段用于動态生成頁面,或者用于代碼生成器的編寫等。比如把資料庫的表映射成 go struct
語言的
,這些體力活,寫個代碼生成器是最合适不過的了.
示例例把表轉成 struct :

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)
}
輸出
hello world!
obj: map[age:18 name:world]
結構體内的字段也是用
{{.field}}
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)
}
空格
在
{{}}
内添加
-
可以去掉空格
-
去掉左邊所有的空格{{- }}
-
去掉右邊所有的空格{{ -}}
-
去掉兩邊所有的空格{{- -}}
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 := }}
,變量定義後,可以在模闆内其他任意地方使用:
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)
}
hello li
方法
方法可以分為全局方法和結構體方法還有内置方法,内置方法也是全局方法的一種
全局方法
template.FuncMap
是一個
map
裡面的
value
必需是方法,傳入的值的參數沒有限制
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
判斷
{{if }} {{end}}
,可以用于
字元串
bool
或者
數值類型
當
字元串有資料
bool
值為
true
數值類型
大于
時為真
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
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
内嵌template
除了可以在自定義對象還可以自定義内嵌的模闆
{{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)
}