quot;T1"}}ONE {{println .}}{{end}}
{{- define "T2"}}{{template "T1" $}}{{end}}
{{- template "T2" . -}}
`)
_ = tmpl.Execute(os.Stdout, "hello world")
}
上面使用define额外定义了T1和T2两个模板,T2中嵌套了T1。{{template "T2" .}}
的点代表顶级作用域的"hello world"对象。在T2中使用了特殊变量$
,这个$
的范围是T2的,不会继承顶级作用域"hello world"。但因为执行T2的时候,传递的是".",所以这里的$
的值仍然是"hello world"。
不仅$
不会在模板之间继承,.
也不会在模板之间继承(其它所有变量都不会继承)。实际上,template可以看作是一个函数,它的执行过程是template("T2",.)
。如果把上面的$
换成".",结果是一样的。如果换成{{template "T2"}}
,则$=nil
如果看不懂这些,后文有解释。
条件判断
有以下几种if条件判断语句,其中第三和第四是等价的。
{{if pipeline}} T1 {{end}}
{{if pipeline}} T1 {{else}} T0 {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
{{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}
需要注意的是,pipeline为false的情况是各种数据对象的0值:数值0,指针或接口是nil,数组、slice、map或string则是len为0。
range...end迭代
有两种迭代表达式类型:
{{range pipeline}} T1 {{end}}
{{range pipeline}} T1 {{else}} T0 {{end}}
range可以迭代slice、数组、map或channel。迭代的时候,会设置"."为当前正在迭代的元素。
对于第一个表达式,当迭代对象的值为0值时,则range直接跳过,就像if一样。对于第二个表达式,则在迭代到0值时执行else语句。
tx := template.Must(template.New("hh").Parse(
`{{range $x := . -}}
{{println $x}}
{{- end}}
`))
s := []int{11, 22, 33, 44, 55}
_ = tx.Execute(os.Stdout, s)
需注意的是,range的参数部分是pipeline,所以在迭代的过程中是可以进行赋值的。但有两种赋值情况:
{{range $value := .}}
{{range $key,$value := .}}
如果range中只赋值给一个变量,则这个变量是当前正在迭代元素的值。如果赋值给两个变量,则第一个变量是索引值(map/slice是数值,map是key),第二个变量是当前正在迭代元素的值。
下面是在html中使用range的一个示例。test.html文件内容如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Go Web</title>
</head>
<body>
<ul>
{{ range . }}
<li>{{ . }}</li>
{{ else }}
<li> Nothing to show </li>
{{ end}}
</ul>
</body>
</html>
以下是test.html同目录下的go程序文件:
package main
import (
"html/template"
"net/http"
)
func main() {
server := http.Server{
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/process", process)
server.ListenAndServe()
}
func process(w http.ResponseWriter, r *http.Request) {
t1 := template.Must(template.ParseFiles("test.html"))
s := []string{
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
"星期日",}
t1.Execute(w, s)
}
with...end
with用来设置"."的值。两种格式:
{{with pipeline}} T1 {{end}}
{{with pipeline}} T1 {{else}} T0 {{end}}
对于第一种格式,当pipeline不为0值的时候,点"."设置为pipeline运算的值,否则跳过。对于第二种格式,当pipeline为0值时,执行else语句块,否则"."设置为pipeline运算的值,并执行T1。
例如:
{{with "xx"}}{{println .}}{{end}}
上面将输出xx
,因为"."已经设置为"xx"。
内置函数和自定义函数
template定义了一些内置函数,也支持自定义函数。关于如何自定义函数,见深入剖析Go template。
以下是内置的函数列表:
and
返回第一个为空的参数或最后一个参数。可以有任意多个参数。
and x y等价于if x then y else x
not
布尔取反。只能一个参数。
or
返回第一个不为空的参数或最后一个参数。可以有任意多个参数。
"or x y"等价于"if x then x else y"。
print
printf
println
分别等价于fmt包中的Sprint、Sprintf、Sprintln
len
返回参数的length。
index
对可索引对象进行索引取值。第一个参数是索引对象,后面的参数是索引位。
"index x 1 2 3"代表的是x[1][2][3]。
可索引对象包括map、slice、array。
call
显式调用