Go语言模板引擎的使用可以分为三部分:定义模板文件、解析模板文件和模板渲染。

定义模板

按照相应的语法编写模板文件。

1
2
3
4
5
6
7
8
<html>
<head>
<title>模板文件</title>
</head>
<body>
hello {{ . }}
</body>
</html>
text/templatehtml/template
.tmpl.tplUTF8{{}}.{{ .FieldName }}{{}}

解析模板

系统定义了一些模板解析方法,获得模板对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 创建模板对象,并为其添加一个模板名称
func New(name string) *Template {}

// 解析字符串,比如template.New("name").Parse(src string) 创建模板对象,并完成模板解析。
func (t *Template) Parse(src string) (*Template, error) {}

// 解析模板文件得到模板对象,可以同时解析多个文件
func ParseFiles(filenames ...string) (*Template, error) {}

// 批量解析文件,比如解析当前目录下有以h开头的模板文件:template.ParseGlob("h*")
func ParseGlob(pattern string) (*Template, error) {}

解析模板的时候,有几个实用的方法

1
2
3
4
5
6
7
8
// 模板包里面有一个函数Must,它的作用是检测模板是否正确。
// 例如大括号是否匹配,注释是否正确的关闭,变量是否正确的书写
func Must(t *Template, err error) *Template

// Funcs方法向模板t的函数字典里加入参数funcMap内的键值对。
// 如果funcMap某个键值对的值不是函数类型或者返回值不符合要求会panic。
// 但是,可以对t函数列表的成员进行重写。方法返回t以便进行链式调用
func (t *Template) Funcs(funcMapFuncMap) *Template

模板渲染

{{ . }}
1
2
func (t *Template) Execute(wr io.Writer, data interface{}) error {}
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {}
ExecuteParseFiles,ParseGlobExecuteTemplate

模板语法汇总

模板函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func xss2(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("demo/tpl/xss2.html")
	if err != nil {
		fmt.Println("模板解析异常 err = ", err)
		return
	}
	str := "<a href = 'http://www.baidu.com'>百度</a>"
	// 此时,我们想在页面上留下百度的跳转链接,但是这样写的话,肯定会被转义
	_ = t.Execute(w, str)
}

func xss3(w http.ResponseWriter, r *http.Request) {
	// 自定义模板函数,将特定字符串渲染成HTML标签输出显示,不要转义。
    // 注意:New传入的模板名不能带路径,下面ParseFiles解析模板则需要带路径
	t, err := template.New("xss3.html").Funcs(
		template.FuncMap {
			"safe": func(s string) template.HTML {
				return template.HTML(s)
			},
		},
	).ParseFiles("demo/tpl/xss3.html")

	if err != nil {
		fmt.Println("模板解析异常 err = ", err)
		return
	}
	str := "<a href = 'http://www.baidu.com'>百度</a>"
	_ = t.Execute(w, str)
}

模板嵌套

1
2
3
4
5
6
7
8
9
// 定义名称为 name 的 template
{{ define "name" }} T {{ end }}

// 执行名为 name 的 template
{{ template "name" }}
{{ template "name"  pipeline }}

// 先定义,并执行
{{ block "name" pipeline }} T {{ end }}
blockdefinename.pipeline{{ define "name" }} T {{ end }}{{ template "name" pipeline }}

参考:

(未完待续…)