template
html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出。
模板语法
{{.}}
模板语法都包含在{{和}}中间,其中{{.}}中的点表示当前对象。
当我们传入一个结构体对象时,我们可以根据.来访问结构体的对应字段。例如:
typeUserInfostruct{NamestringGenderstringAgeint}funcsayHello(whttp.ResponseWriter,r*http.Request){//解析指定文件生成模板对象tmpl,err:=template.ParseFiles("./hello.html")iferr!=nil{fmt.Println("createtemplatefailed,err:",err)return}user:=UserInfo{Name:"枯藤",Gender:"男",Age:18,}//利用给定数据渲染模板,并将结果写入wtmpl.Execute(w,user)}
.表示当前对象/结构体user(w只是服务端的一个变量,也保存了user这个结构体而已)
<body><p>Hello{{.Name}}</p><p>性别:{{.Gender}}</p><p>年龄:{{.Name}}</p></body>
模板注释
{{/*acomment*/}}注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。
管道pipeline
Go的模板语法中支持使用管道符号|链接多个命令,用法和unix下的管道类似:|前面的命令会将运算结果(或返回值)传递给后一个命令的最后一个位置。
Actions
以下这些动作基本包含golang模板中常用的动作与含义说明
{{/*acomment*/}}注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止,就像这里表示的一样。{{pipeline}}pipeline的值的默认文本表示会被拷贝到输出里。{{ifpipeline}}T1{{end}}如果pipeline的值为empty,不产生输出,否则输出T1执行结果。不改变dot的值。Empty值包括false、0、任意nil指针或者nil接口,任意长度为0的数组、切片、字典。{{ifpipeline}}T1{{else}}T0{{end}}如果pipeline的值为empty,输出T0执行结果,否则输出T1执行结果。不改变dot的值。{{ifpipeline}}T1{{elseifpipeline}}T0{{end}}用于简化if-else链条,elseaction可以直接包含另一个if;等价于:{{ifpipeline}}T1{{else}}{{ifpipeline}}T0{{end}}{{end}}{{rangepipeline}}T1{{end}}pipeline的值必须是数组、切片、字典或者通道。如果pipeline的值其长度为0,不会有任何输出;否则dot依次设为数组、切片、字典或者通道的每一个成员元素并执行T1;如果pipeline的值为字典,且键可排序的基本类型,元素也会按键的顺序排序。{{rangepipeline}}T1{{else}}T0{{end}}pipeline的值必须是数组、切片、字典或者通道。如果pipeline的值其长度为0,不改变dot的值并执行T0;否则会修改dot并执行T1。{{template"name"}}执行名为name的模板,提供给模板的参数为nil,如模板不存在输出为""{{template"name"pipeline}}执行名为name的模板,提供给模板的参数为pipeline的值。{{withpipeline}}T1{{end}}如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1。不修改外面的dot。{{withpipeline}}T1{{else}}T0{{end}}如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1。
比较
eq如果arg1==arg2则返回真ne如果arg1!=arg2则返回真lt如果arg1<arg2则返回真le如果arg1<=arg2则返回真gt如果arg1>arg2则返回真ge如果arg1>=arg2则返回真
{{eqarg1arg2arg3}}
嵌套模板
<!DOCTYPEhtml><html><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><metahttp-equiv="X-UA-Compatible"content="ie=edge"><title>tmpltest</title></head><body><h1>测试嵌套template语法</h1><hr>{{template"ul.html"}}<hr>{{template"ol.html"}}</body></html>{{define"ol.html"}}<h1>这是ol.html</h1><ol><li>AA</li><li>BB</li><li>CC</li></ol>{{end}}
ul.html模板 不在当前html文档内,需要通过服务端template.ParseFiles指定加载的模板页,才能使用(有点耦合,要是都由前端模板文件去include包含模板可能会更自然些)
functmplDemo(whttp.ResponseWriter,r*http.Request){tmpl,err:=template.ParseFiles("./t.html","./ul.html")iferr!=nil{fmt.Println("createtemplatefailed,err:",err)return}user:=UserInfo{Name:"枯藤",Gender:"男",Age:18,}tmpl.Execute(w,user)