网上搜golang的html模板引擎,发现没有啥内容。后来查看官方html template包,才发现这个html template已经很强大了,结合text template的模板语法,基本上可以满足大部分需求了。
模板和服务端代码耦合
package main
import (
"html/template"
"log"
"os"
)
func main() {
// 声明模板内容
const tpl = `
{{.Title}}{{range .Items}}
`
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
My page这个示例来自golang官方,但是模板内容是直接放在代码里,实际开发的时候一般都会将模板文件和golang代码区分开,从上面的代码可以初步想到将tpl的内容存放到文件里,然后通过文件操作方法将内容读取出来。这个代码我们不用自己写,template中提供了另外一个函数ParseFiles可以直接解析文件。
模板和服务端代码分离
tpl.html内容:
{{.Title}}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
golang html template demo上面实现了单个模板的载入,在模板比较多的时候一般会考虑将公共的部分提取出来,例如提取出公共的头部(header)和底部(footer)这样。
模板内嵌入公共模板
模板目录结构:
golang html template
index.html
{{template "header" .}}
index
{{template "footer"}}
在模板嵌入其它模板使用template语法,其中{{template “header” .}}最后的一个点表示将当前模板中的变量传递到header模板。
header.html
{{define "header"}}
{{.Title}}{{end}}
footer.html
{{define "footer"}}
{{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
load common templateindex
到此我们可能还会问,那么模板除了tempate这样的语法,还有什么样的语法呢?比如循环数组输出主要怎么写?这点可以参考text.template包,里面有详细的说明。如果阅读html.template的源码可以发现该包也是构建在text.template基础之上的。