前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go标准库:html/template

Go标准库:html/template

原创
作者头像
孟斯特
发布2023-11-26 20:13:57
1960
发布2023-11-26 20:13:57
举报
文章被收录于专栏:code人生code人生

html/template 包是 Go 语言标准库中用于 HTML 模板渲染的包。它提供了一种安全的方式来渲染 HTML 内容,防止一些常见的 Web 攻击,如注入恶意脚本。以下是对 html/template 包的简单介绍:

1. 模板定义

Go 中的模板是一种轻量级的数据驱动的模板语言,类似于其他语言中的模板引擎。模板使用双花括号 {{}} 包围的占位符来插入变量、执行条件语句和循环等操作。例如:

代码语言: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)
	}
}

2. 安全性

html/template 包在模板渲染过程中会对变量进行 HTML 转义,从而避免 XSS(跨站脚本攻击)等安全问题。例如,在上述例子中,模板中的{{.Title}}{{ .Header}}会被自动转义,确保不会被当做 HTML 标签解释。

3. 模板函数

html/template 包还支持自定义模板函数,这些函数可以在模板中使用。自定义函数可以用于处理各种逻辑,例如格式化日期、字符串截断等。

代码语言:go
复制
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)
	}
}

4. 模板嵌套

html/template 支持模板的嵌套,可以在一个模板中引用其他模板。

代码语言:go
复制
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" 的子模板,并传递了子模板需要的数据。

5. 对比 text/template

html/templatetext/template 都是 Go 语言标准库中用于模板渲染的包,它们有一些相似之处,但也有一些关键的区别。下面是它们的对比:

5.1 安全性
  • html/template: 主要用于 HTML 内容的渲染,会自动对输出进行 HTML 转义,以防止 XSS 攻击等安全问题。对于渲染 HTML 页面或包含用户输入的内容时,推荐使用 html/template
  • text/template: 主要用于纯文本内容的渲染,不会对输出进行 HTML 转义。适用于一般的文本模板,但在渲染包含用户输入的 HTML 内容时需要格外小心。
5.2 转义规则
  • html/template: 默认情况下,会对所有的输出进行 HTML 转义,确保不会解释为 HTML 标签或 JavaScript 代码。可以使用 {{. | safeHTML}} 的方式来指定不进行转义的内容。
  • text/template: 不会默认进行 HTML 转义,而是直接输出内容。可以使用 {{. | html}} 的方式来手动进行 HTML 转义。
5.3 用途
  • html/template: 适用于渲染包含 HTML 内容的模板,例如网页模板。
  • text/template: 适用于渲染纯文本内容的模板,例如配置文件、邮件模板等。
5.4 text/template 示例:
代码语言:go
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 模板定义
  • 2. 安全性
  • 3. 模板函数
  • 4. 模板嵌套
  • 5. 对比 text/template
    • 5.1 安全性
      • 5.2 转义规则
        • 5.3 用途
          • 5.4 text/template 示例:
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
          http://www.vxiaotou.com