Go语言中的html/template标准库学习笔记一(template库的使用)

在MVC(model-view-controller)架构中,我们经常会用到模板文件,本片博文介绍html/template的使用方法,关于模板语法,请参考我的另一篇博客Go语言中的html/template标准库学习笔记一(template语法介绍)

1.先介绍一下Template结构体
// Template is a specialized Template from "text/template" that produces a safe
// HTML document fragment.
type Template struct {
	// Sticky error if escaping fails, or escapeOK if succeeded.
	escapeErr error
	// We could embed the text/template field, but it's safer not to because
	// we need to keep our version of the name space and the underlying
	// template's in sync.
	text *template.Template
	// The underlying template's parse tree, updated to be HTML-safe.
	Tree       *parse.Tree
	*nameSpace // common to all associated templates
}

在Template中text为*template.Template类型,保存了模板的基础信息:

// Template is the representation of a parsed template. The *parse.Tree
// field is exported only for use by html/template and should be treated
// as unexported by all other clients.
type Template struct {
	name string
	*parse.Tree
	*common
	leftDelim  string
	rightDelim string
}
2.新建模板

我们可以使用func New(name string) *Template新建一个模板,并指定模板的名称。

package main

import (
	"fmt"
	"html/template"
)

func main() {
    // 这里我们创建了一个名称为test的模板
	tpl := template.New("test")
	// 查看模板名称
	fmt.Println(tpl.Name())
}

Output:

$ go run main.go
test
3. 查看模板名称

因为name字段我们是不能直接查看的,因此我们需要使用func (t *Template) Name() string方法获取模板名称。

4.解析模板

(1)使用func ParseFiles(filenames ...string) (*Template, error)解析模板文件
我们在项目的templates目录添加一个index.html文件,文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>html/template教程</title>
</head>
<body>
    {{ . }}
</body>
</html>

文件中的{{ . }}表示接收到的内容,然后我们解析index.html模板:

package main

import (
	"html/template"
	"os"
)

func main() {
	tpl, err := template.ParseFiles("templates/index.html")
	if err != nil {
		panic(err)
	}
	// 如果不报错则将内容输出,os.Stdout为标准输出
	if err := tpl.Execute(os.Stdout, "hello world"); err != nil {
		panic(err)
	}
}

Output:

$ go run main.go
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>html/template教程</title>
</head>
<body>
    hello world
</body>
</html>

我们可以看到已经成功解析到了index.html模板,并且进行了渲染。

(2)使用func (t *Template) Parse(text string) (*Template, error)解析字符串

package main

import (
	"html/template"
	"os"
)

func main() {
    // 在Parse方法中传入要解析的字符串`Output: {{ . }}`
	tpl, err := template.New("test").Parse(`Output: {{ . }}`)
	if err != nil {
		panic(err)
	}
	// 如果不报错则将内容输出,os.Stdout为标准输出
	if err := tpl.Execute(os.Stdout, "hello world"); err != nil {
		panic(err)
	}
}

Output:

$ go run main.go
Output: hello world
5.模板渲染
(1)使用func (t *Template) Execute(wr io.Writer, data interface{}) error渲染模板,这个在前面已经用到了,就不举例了。
(2)使用func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error渲染指定模板
package main

import (
	"html/template"
	"os"
)

func main() {
    // 在Parse方法中传入要解析的字符串`Output: {{ . }}`
	tpl, err := template.New("test").Parse(`Output: {{ . }}`)
	if err != nil {
		panic(err)
	}
	// 如果不报错则将内容输出,os.Stdout为标准输出
	if err := tpl.ExecuteTemplate(os.Stdout, "test", "hello world"); err != nil {
		panic(err)
	}
}

Output:

$ go run main.go
Output: hello world
(3)`func ParseGlob(pattern string) (*Template, error)

`ParseGlob函数从指定的匹配文件中创建并解析模板,必须得至少匹配一个文件.
这里我们在templates目录创建两个文件:
body.html文件内容为:

{{ define "body" }}
<body>
    <p>Hello World</p>
</body>
{{ end }}

header.html文件内容为:

<!DOCTYPE html>
<html>
<head> 
    <meta charset="utf-8"> 
    <title>html/template教程</title> 
</head>
    {{ template "body" . }}
</html>

我们使用ParseGlob进行模板解析:

package main

import (
	"html/template"
	"os"
)
func main() {
	tpl, err := template.ParseGlob("templates/*.html")
	if err != nil {
		panic(err)
	}
	// 如果不报错则将内容输出,os.Stdout为标准输出
	if err := tpl.ExecuteTemplate(os.Stdout, "header.html", nil); err != nil {
		panic(err)
	}
}

Output:

$ go run main.go
<!DOCTYPE html>
<html>
<head> 
    <meta charset="utf-8"> 
    <title>html/template教程</title> 
</head>

<body>
    <p>Hello World</p>
</body>

</html>
6.添加模板函数

模板文件中支持函数操作,我们可以使用func (t *Template) Funcs(funcMap FuncMap) *Template方法给模板添加函数,模板函数的返回值最多为两个,并且如果有第二个参数,则必须为error类型。

package main

import (
	"html/template"
	"os"
	"strings"
)
// 定义模板函数返回hello world
func Hello() (string, error) {
	return "hello world", nil
}
func main() {
	// 首先创建一个函数字典用于注册函数
	funcMap := template.FuncMap{
		"hello": Hello,
	}
	tpl, err := template.New("test").Funcs(funcMap).Parse(`Output: {{ hello }}`)
	if err != nil {
		panic(err)
	}
	// 如果不报错则将内容输出,os.Stdout为标准输出
	if err := tpl.Execute(os.Stdout, "hello world"); err != nil {
		panic(err)
	}
}

Output:

$ go run main.go
Output: hello world
7. 其他方法
(1)func Must(t *Template, err error) *Template

Must函数会在Parse返回err不为nil时,调用panic,不需要初始化后再调用Parse方法去检测,下面举个例子:

package main

import (
	"html/template"
	"os"
)

func main() {
	//	Must会判断解析结果是否报错,如果报错则panic
	// {{ templates/*.html是错误的模板语法,因此会报错
	tpl := template.Must(template.New("test").Parse("{{ templates/*.html"))

	// 如果不报错则将内容输出,os.Stdout为标准输出
	if err := tpl.ExecuteTemplate(os.Stdout, "test", nil); err != nil {
		panic(err)
	}
}

Output:

$ go run main.go
panic: template: test:1: unexpected bad character U+002F '/' in command

goroutine 1 [running]:
html/template.Must(...)
        c:/Go/src/html/template/template.go:372
main.main()
        D:/GOCODE/Test/main.go:15 +0xff
exit status 2
(2)func (t *Template) Delims(left, right string) *Template

Delims可以自定义模板中的分界符号,默认是{{}}

package main

import (
	"html/template"
	"os"
)

func main() {
	//	## Delims()方法用来指定分隔符来分割字符串,随后会使用Parse, ParseFiles, or ParseGlob方法进行模板内容解析
	tpl := template.Must(template.New("test").Delims("{{", "]]").Parse("{{ . ]]"))
	// 如果不报错则将内容输出,os.Stdout为标准输出
	if err := tpl.Execute(os.Stdout, "hello world"); err != nil {
		panic(err)
	}
}

Output:

$ go run main.go
hello world

可以看到界定符被改成{{]],程序正确对模块进行了解析。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值