网上搜golang的html模板引擎,发现没有啥内容。后来查看官方html template包,才发现这个html template已经很强大了,结合text template的模板语法,基本上可以满足大部分需求了。

模板和服务端代码耦合

package main

import (

"html/template"

"log"

"os"

)

func main() {

// 声明模板内容

const tpl = `

{{.Title}}

{{range .Items}}

{{else}} {{end}}

`

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 My another 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 template index

到此我们可能还会问,那么模板除了tempate这样的语法,还有什么样的语法呢?比如循环数组输出主要怎么写?这点可以参考text.template包,里面有详细的说明。如果阅读html.template的源码可以发现该包也是构建在text.template基础之上的。