
模板语法
1.模板标签
{{ }} 模板标签使用“{{"和"}}“括起来
2.注释
{{/* a comment*/}}使用
{{/*和**/}}来包含注释内容
3.变量
{{ . }} 此标签输出对象中字段或方法名称为Admpub的值
{{.Admpub}} 表示输出对象中字段或方法名称为Admpub的值
当Admpub是匿名字段时,可以访问其内部字段或方法,如“Com": {{.Admpub.Com}}。如果Com是一个方法并返回一个结构体对象,同样也可以访问其字段或方法:{{.Admpub.Com.Field1}}。
{{.Method1 “参数值 1”“参数值 2”}}调用方法Method1,将后面的参数值一次传递给此方法,并输出其返回值
{{admpub}}此标签用于输出模板中定义的名称为“admpub”的变量。当admpub本身是一个结构体对象时,可访问其字段{{$admpub.Field1}}。
在模板中定义变量,变量名称用字母和数组组成,并加上$前缀,采用简式赋值。
例如:{{x := 'OK'}}或{{x := pipeline}}
4.通道函数
{{FuncNmae1}}此标签将调用名称为“FuncName1”的模板函数(等于执行FuncName1(),不传递任何参数)并输出其返回值
{{FuncNmae1 "参数值 1"参数值 2“}}此标签将调用FuncName1(“参数值 1“,“参数值 2“),并输出其返回值
{{.Admpub|FuncNmae1}},此标签调用FuncNmae1的模板函数(等于执行“FuncName1(this.Admpub)”,将竖线“|”左边的".Admpub"变量值作为函数参数传送)并输出其返回值
5.条件判断
{{if pipeline}} T1 {{end}}标签结构为{{if...}} ... {{end}}
{{if pipeline}} TI {{else}} T2 {{end} 标签结构为{{if...}} ... {{else}} ... {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}} 标签结构为{{if}} ... {{else if ...}} ... {{end}}
其中if后面可以是一个条件表达式(包括通道函数表达式),也可以是一个字符串变量或布尔值变量。当为字符串变量时,如果空字符串则判断为false,否则判断为true
6.循环遍历
{{range k,v := .Var}} {{k}} => {{v}} {{end}} range ... end结构体内部如要使用外部的变量,如.Var2,需要简写为:.Var2(即在外部变量名称前加字符)
{{range .Var}} {{.}} {{end}} 将遍历值直接显示出来
{{range pipeline}} T1 {{else}} T0 {{end}} 当没有可遍历的值时,将执行else部分。
8.子模板嵌套
{{define "T1"}}ONE{{end}} {{define "T2"}}TWO{{end}} {{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}} {{template "T3"}}输出如下:
ONE TWO
9.定义局部变量
{{with pipeline}} T1 {{end}} 通道的值将赋给该标签内部的“.”,内部是指被{{with pipeline}}...{{end}}包围起来的部分,既T1所在位置
{{with pipeline}} T1 {{else}} T0 {{end}} 如果通道的值为空,“.”不受影响并且执行了T0,否则,将通道的值赋给".",并且执行T1.
{{end}} 标签是if、with、range的结束标签
10.输出字符串
打印输出
{{"\"output\""}} 输出一个字符串常量 {{`“output”`}} 输出一个原始字符串常量 {{printf"%q""output"}} 函数调用,相当于printf("%q","output") {{"output"|printf"%q"}} 竖线“|”左边的结果作为函数的最后一个参数,相当于printf("%q","output") {{printf"%q"(print"out""put")}} 圆括号中表达式的整体结果作为printf函数的参数,相当于printf("%q",print("out","put")) {{"put"|printf "%s%s""out"|printf"%q"}} 一个更复杂的调用,相当于printf("%q",printf(%s%s,"out","put")) {{"output"|printf"%s"|printf"q"}} 相当于printf("%q",printf("%s","output")) {{with "output"}}{{printf"%q" .}}{{end}} 一个使用点号“.”的with操作,相当于printf("%q","output") {{with $x := "output"}}{{printf "q"}}{{$x}}{{end}} with结构定义变量,值为执行通道函数之后的结果,相当于$x := printf("%q","output") {{with $x := "output"}}{{printf"%q"$x}}{{end}} with结构体,在其他动作中使用定义的变量 {{with $x := "output"}}{{$x | printf"%q"}}{{end}} with结构使用了通道,相当于printf("%q","output")
11.预定义的模板全局函数
{{and x y}}模板全局函数and,如果x为真,返回y,否则返回x。相当于Go中的x&&y
{{call .X.Y 1 2}}模板全局函数call,后面的第一个参数的结果必须是一个函数(既这是一个函数类型的值),其余参数作为该函数的参数
该函数必须返回一个或两个结果值,其中第二个结果值是error类型
如果传递的参数与函数定义的不匹配或返回的error值不为nil,则停止执行
{{html }}模板全局函数html,转义文本中的html标签,如将“<”转义为“< ;”,“>”转义为“> ;” 等
{{index x 1 2 3}}模板全局函数index,返回Index后面的第一个参数的某个索引对应的元素值,其余的参数为索引值。x必须是一个map、slice或数组
{{js}}模板全局函数js,返回用JavaScript的escape处理后的文本
{{len x}}模板全局函数len,返回参数的长度值(int类型)
{{not x}}模板全局函数not,返回单一参参数的布尔否定值
{{or x y}}模板全局函数or,如果x为真,返回x,否则返回y,相当于go的x||y
{{print }}模板全局函数print,fmt.Sprint的别名
{{printf }}模板全局函数printf,fmt.Sprintf的别名
{{println }}模板全局函数println,fmt.Sprintln的别名
{{urlquery }}模板全局函数urlquery,返回适合在URL查询中嵌入到形参中的文本转义值
12.布尔函数
{{eq arg1 arg2}}布尔函数eq,返回表达式“arg1 == arg2”的布尔值
{{ne arg1 arg2}}布尔函数ne,返回表达式“arg1 != arg2”的布尔值
{{lt arg1 arg2}}布尔函数lt,返回表达式“arg1 < arg2”的布尔值
{{le arg1 arg2}}布尔函数le,返回表达式“arg1 <= arg2”的布尔值
{{gt arg1 arg2}}布尔函数gt,返回表达式“arg1 > arg2”的布尔值
{{ge arg1 arg2}}布尔函数ge,返回表达式“arg1 => arg2”的布尔值
布尔函数对任何零值返回false,非零值返回true,对于简单的多路相等测试,eq只接受两个参数进行比较,后面其他的参数将依次与第一个参数进行比较。例如:
{{eq arg1 arg2 arg3 arg4}}相当于
arg1 == arg2 || arg1 == arg3 || arg1 == arg4
13.text/template包示例
将加载的字符和数据进行格式化处理,1.创建模板对西昂 2.加载模板 3.执行渲染模板
示例:
tmp.txt
{{range .}}---------------------------------------- Name: {{.Name}} Price: {{.Price | printf "%6.2f"}} {{end}}main.go
package main import ( "log" "os" "text/template" ) var report = template.Must(template.ParseFiles("tmp.txt")) type Book struct { Name string Price float64 } func main() { Data := []Book{{"《三国演义》", 19.82}, {"《儒林外史》", 99.09}, {"《史记》", 26.89}} if err := report.Execute(os.Stdout, Data); err != nil { log.Fatal(err) } }使用template.ParseFils("tmp.txt")加载模板文件时,如有多个.txt模板文件,可以用template.ParseGlob(*.txt)这种正则匹配模式来加载模板文件,也可以使用template.ParseFiles("a.txt","b.txt","c.txt")这种方式加载。template.Must()函数的作用是检测现模板是否正确
14.html/template包
示例实现一个动态HTML页面
index.html.tmpl模板文件
<!doctype html> <head> <meta charset="UTF-8"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>Go</title> </head> <body> {{ . }} </body> </html>main.go
func tHandler(w http.ResponseWriter, r *http.Request) { t := template.Must(template.ParseGlob("*.html.tmpl")) t.Execute(w, "Hello World!") } func main() { http.HandleFunc("/", tHandler) http.ListenAndServe(":8080", nil) }如果需要把数据传递到指定模板执行渲染,可以使用ExecuteTemplate(),这个方法可用于执行指定名字的模板,因为在多个模板文件加载情况下,需要指定特定的模板渲染执行
layout.html.tmpl:注意在模板文件的开头,根据模板语法定义了模板的名字{{define "layout"}}
{{ define "layout" }} <!doctype html> <head> <meta charset="UTF-8"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>Go</title> </head> <body> {{ . }} {{ template "index" }} </body> </html> {{ end }}index.html.tmpl: 第二个模板定义为{{ define "index"}},通过{{ template "index"}}嵌入了模板index
{{ define "index" }} <div> <b>Go 语言值得你拥有!</b> </div> {{ end }}渲染时,layout模板中的{{ . }}会接收字符串并显示出来
main.go
func tHandler(w http.ResponseWriter, r *http.Request) { t, _ := template.ParseFiles("layout.html.tmpl", "index.html.tmpl") t.ExecuteTemplate(w, "layout", "Hello World!") } func main() { http.HandleFunc("/", tHandler) http.ListenAndServe(":8080", nil) }