html/template
包是 Go 语言标准库中用于 HTML 模板渲染的包。它提供了一种安全的方式来渲染 HTML 内容,防止一些常见的 Web 攻击,如注入恶意脚本。以下是对 html/template
包的简单介绍:
Go 中的模板是一种轻量级的数据驱动的模板语言,类似于其他语言中的模板引擎。模板使用双花括号 {{
和 }}
包围的占位符来插入变量、执行条件语句和循环等操作。例如:
package main
import (
"html/template"
"os"
)
func main() {
// 模板定义
tmpl := `
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<h1>{{.Header}}</h1>
<ul>
{{range .Items}}
<li>{{.}}</li>
{{end}}
</ul>
</body>
</html>
`
// 解析模板
template, err := template.New("example").Parse(tmpl)
if err != nil {
panic(err)
}
// 模板渲染的数据
data := struct {
Title string
Header string
Items []string
}{
Title: "My Page",
Header: "Welcome to My Page",
Items: []string{"Item 1", "Item 2", "Item 3"},
}
// 将渲染后的结果输出到标准输出
err = template.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}
html/template
包在模板渲染过程中会对变量进行 HTML 转义,从而避免 XSS(跨站脚本攻击)等安全问题。例如,在上述例子中,模板中的{{.Title}}
和{{ .Header}}
会被自动转义,确保不会被当做 HTML 标签解释。
html/template
包还支持自定义模板函数,这些函数可以在模板中使用。自定义函数可以用于处理各种逻辑,例如格式化日期、字符串截断等。
package main
import (
"html/template"
"os"
"strings"
"time"
)
// 自定义截断字符串函数
func truncate(s string, length int) string {
if len(s) > length {
return s[:length] + "..."
}
return s
}
func main() {
// 模板定义
tmpl := `
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<h1>{{.Header}}</h1>
<ul>
{{range .Items}}
<li>{{truncate . 5}}</li>
{{end}}
</ul>
</body>
</html>
`
// 创建带有自定义函数的模板
template := template.New("example").Funcs(template.FuncMap{"truncate": truncate})
template, err := template.Parse(tmpl)
if err != nil {
panic(err)
}
// 模板渲染的数据
data := struct {
Title string
Header string
Items []string
}{
Title: "My Page",
Header: "Welcome to My Page",
Items: []string{"Item 1", "Item 2", "Item 3"},
}
// 将渲染后的结果输出到标准输出
err = template.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}
html/template
支持模板的嵌套,可以在一个模板中引用其他模板。
package main
import (
"html/template"
"os"
)
// 定义子模板
const subTemplate = `
{{define "sub"}}
<h2>{{.Subtitle}}</h2>
<p>{{.Content}}</p
>
{{end}}
`
func main() {
// 主模板定义
tmpl := `
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<h1>{{.Header}}</h1>
{{template "sub" .SubData}}
</body>
</html>
`
// 创建主模板
template, err := template.New("example").Parse(tmpl)
if err != nil {
panic(err)
}
// 解析并添加子模板
template, err = template.Parse(subTemplate)
if err != nil {
panic(err)
}
// 模板渲染的数据
data := struct {
Title string
Header string
SubData SubData
}{
Title: "My Page",
Header: "Welcome to My Page",
SubData: SubData{
Subtitle: "Subsection",
Content: "This is the content of the subsection.",
},
}
// 将渲染后的结果输出到标准输出
err = template.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}
// 定义子模板数据
type SubData struct {
Subtitle string
Content string
}
在这个例子中,通过 {{template "sub" .SubData}}
引用了名为 "sub" 的子模板,并传递了子模板需要的数据。
text/template
html/template
和 text/template
都是 Go 语言标准库中用于模板渲染的包,它们有一些相似之处,但也有一些关键的区别。下面是它们的对比:
html/template
。{{. | safeHTML}}
的方式来指定不进行转义的内容。{{. | html}}
的方式来手动进行 HTML 转义。package main
import (
"text/template"
"os"
)
func main() {
// 纯文本模板定义
tmpl := `
Title: {{.Title}}
Header: {{.Header}}
Items:
{{range .Items}}
- {{.}}
{{end}}
`
// 解析纯文本模板
template, err := template.New("example").Parse(tmpl)
if err != nil {
panic(err)
}
// 模板渲染的数据
data := struct {
Title string
Header string
Items []string
}{
Title: "My Page",
Header: "Welcome to My Page",
Items: []string{"Item 1", "Item 2", "Item 3"},
}
// 将渲染后的结果输出到标准输出
err = template.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。