网上搜golang的html模板引擎,发现没有啥内容。后来查看官方html template包,才发现这个html template已经很强大了,结合text template的模板语法,基本上可以满足大部分需求了。
模板和服务端代码耦合
package main import ( "html/template" "log" "os" ) func main() { // 声明模板内容 const tpl = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{.Title}}</title> </head> <body> {{range .Items}}<div>{{ . }}</div>{{else}}<div><strong>no rows</strong></div>{{end}} </body> </html>` check := func(err error) { if err != nil { log.Fatal(err) } } // 创建一个新的模板,并且载入内容 t, err := template.New("webpage").Parse(tpl) check(err) // 定义传入到模板的数据,并在终端打印 data := struct { Title string Items []string }{ Title: "My page", Items: []string{ "My photos", "My blog", }, } err = t.Execute(os.Stdout, data) check(err) // 定义Items为空的数据 noItems := struct { Title string Items []string }{ Title: "My another page", Items: []string{}, } err = t.Execute(os.Stdout, noItems) check(err) }
运行
$ go run main.go <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My page</title> </head> <body> <div>My photos</div><div>My blog</div> </body> </html> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My another page</title> </head> <body> <div><strong>no rows</strong></div> </body> </html>
这个示例来自golang官方,但是模板内容是直接放在代码里,实际开发的时候一般都会将模板文件和golang代码区分开,从上面的代码可以初步想到将tpl的内容存放到文件里,然后通过文件操作方法将内容读取出来。这个代码我们不用自己写,template中提供了另外一个函数ParseFiles可以直接解析文件。
模板和服务端代码分离
tpl.html内容:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{.Title}}</title> </head> <body> </body> </html> </pre>
golang代码
package main import ( "html/template" "log" "os" ) func main() { t, err := template.ParseFiles("./tpl.html") if err != nil { log.Fatal(err) } data := struct { Title string }{ Title: "golang html template demo", } err = t.Execute(os.Stdout, data) if err != nil { log.Fatal(err) } }
运行
$ go run tpl.go <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>golang html template demo</title> </head> <body> </body> </html>
上面实现了单个模板的载入,在模板比较多的时候一般会考虑将公共的部分提取出来,例如提取出公共的头部(header)和底部(footer)这样。
模板内嵌入公共模板
模板目录结构:

golang html template
index.html
<html> {{template "header" .}} <body> <h1>index</h1> {{template "footer"}} </body> </html>
在模板嵌入其它模板使用template语法,其中{{template “header” .}}最后的一个点表示将当前模板中的变量传递到header模板。
header.html
{{define "header"}} <head> <title>{{.Title}}</title> </head> {{end}}
footer.html
{{define "footer"}} <div>footer</div> {{end}}
golang代码:
template.ParseFiles这个函数可以接收多个文件参数
package main import ( "html/template" "log" "os" ) func main() { t, err := template.ParseFiles("tpl/index.html", "tpl/public/header.html", "tpl/public/footer.html") if err != nil { log.Fatal(err) } data := struct { Title string }{ Title: "load common template", } err = t.Execute(os.Stdout, data) if err != nil { log.Fatal(err) } }
运行
$ go run muti.go <html> <head> <title>load common template</title> </head> <body> <h1>index</h1> <div>footer</div> </body> </html>
到此我们可能还会问,那么模板除了tempate这样的语法,还有什么样的语法呢?比如循环数组输出主要怎么写?这点可以参考text.template包,里面有详细的说明。如果阅读html.template的源码可以发现该包也是构建在text.template基础之上的。
转载请注明:快乐编程 » golang中html template模板