函数。第一个参数必须是函数类型,且不是template中的函数,而是外部函数。
例如一个struct中的某个字段是func类型的。
"call .X.Y 1 2"表示调用dot.X.Y(1, 2),Y必须是func类型,函数参数是1和2。
函数必须只能有一个或2个返回值,如果有第二个返回值,则必须为error类型。
除此之外,还内置一些用于比较的函数:
eq arg1 arg2:
arg1 == arg2时为true
ne arg1 arg2:
arg1 != arg2时为true
lt arg1 arg2:
arg1 < arg2时为true
le arg1 arg2:
arg1 <= arg2时为true
gt arg1 arg2:
arg1 > arg2时为true
ge arg1 arg2:
arg1 >= arg2时为true
对于eq函数,支持多个参数:
eq arg1 arg2 arg3 arg4...
它们都和第一个参数arg1进行比较。它等价于:
arg1==arg2 || arg1==arg3 || arg1==arg4
示例:
{{ if (gt $x 33) }}{{println $x}}{{ end }}
嵌套template:define和template
define可以直接在待解析内容中定义一个模板,这个模板会加入到common结构组中,并关联到关联名称上。如果不理解,还是建议阅读深入剖析Go template。
定义了模板之后,可以使用template这个action来执行模板。template有两种格式:
{{template "name"}}
{{template "name" pipeline}}
第一种是直接执行名为name的template,点设置为nil。第二种是点"."设置为pipeline的值,并执行名为name的template。可以将template看作是函数:
template("name)
template("name",pipeline)
例如:
func main() {
t1 := template.New("test1")
tmpl, _ := t1.Parse(
`{{- define "T1"}}ONE {{println .}}{{end}}
{{- define "T2"}}TWO {{println .}}{{end}}
{{- define "T3"}}{{template "T1"}}{{template "T2" "haha"}}{{end}}
{{- template "T3" -}}
`)
_ = tmpl.Execute(os.Stdout, "hello world")
}
输出结果:
ONE <nil>
TWO haha
上面定义了4个模板,一个是test1,另外三个是使用define来定义的T1、T2、T3,其中t1是test1模板的关联名称。T1、T2、T3和test1共享一个common结构。其中T3中包含了执行T1和T2的语句。最后只要{{template T3}}
就可以执行T3,执行T3又会执行T1和T2。也就是实现了嵌套。此外,执行{{template "T1"}}
时,点设置为nil,而{{temlate "T2" "haha"}}
的点设置为了"haha"。
注意,模板之间的变量是不会继承的。
下面是html文件中嵌套模板的几个示例。
t1.html文件内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=9">
<title>Go Web Programming</title>
</head>
<body>
<div> This is t1.html before</div>
<div>This is the value of the dot in t1.html - [{{ . }}]</div>
<hr />
{{ template "t2.html" }}
<hr />
<div> This is t1.html after</div>
</body>
</html>
因为内部有{{template "t2.html"}}
,且此处没有使用define去定义名为"t2.html"的模板,所以需要加载解析名为t2.html的文件。t2.html文件内容如下:
<div style="background-color: yellow;">
This is t2.html<br/>
This is the value of the dot in t2.html - [{{ . }}]
</div>
处理这两个文件的handler函数如下:
func process(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("t1.html", "t2.html")
t.Execute(w, "Hello World!")
}
上面也可以不额外定义t2.html文件,而是直接在t1.html文件中使用define定义一个模板。修改t1.html文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=9">
<title>Go Web Programming</title>
</head>
<body>
<div> This is t1.html before</div>
<div>This is the value of the dot in t1.html - [{{ . }}]</div>
<hr />
{{ template "t2.html" }}
<hr />
<div> This is t1.html after&l