自定义Golang模板函数需通过template.FuncMap注册函数,如toUpper;处理复杂数据可用管道访问嵌套字段,如.Address.City;条件判断用{{if}} {{else}} {{end}},循环用{{range}}遍历数据;为防XSS,默认自动转义HTML,可显式使用{{.UserInput | html}};结构体方法若首字母大写,可在模板中直接调用,如{{.FullName}}。

Golang模板函数自定义与渲染技巧:简单来说,就是教你如何扩展Go模板的功能,让它能做更多的事情,以及如何更灵活地使用这些模板。
模板函数自定义与渲染技巧
自定义模板函数,其实就是给
template.FuncMap
FuncMap
举个例子,假设你需要一个函数来把字符串转换成大写。你可以这样:
立即学习“go语言免费学习笔记(深入)”;
package main
import (
"fmt"
"html/template"
"os"
"strings"
)
// 定义一个函数,将字符串转为大写
func toUpper(s string) string {
return strings.ToUpper(s)
}
func main() {
// 创建一个FuncMap,并将自定义函数注册进去
funcMap := template.FuncMap{
"toUpper": toUpper,
}
// 创建一个模板,并使用FuncMap
tmpl, err := template.New("test").Funcs(funcMap).Parse(`
{{ .Name }} 的大写是:{{ toUpper .Name }}
`)
if err != nil {
panic(err)
}
// 定义数据
data := struct {
Name string
}{
Name: "golang",
}
// 渲染模板
err = tmpl.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}这段代码首先定义了一个
toUpper
FuncMap
toUpper
.Funcs(funcMap)
FuncMap
{{ toUpper .Name }}处理复杂数据结构的关键在于理解模板的“管道”概念。管道允许你将一个表达式的结果传递给另一个函数或表达式。这有点像流水线,数据在流水线上一步步处理。
例如,假设你有一个
User
Address
Address
City
package main
import (
"fmt"
"html/template"
"os"
)
type Address struct {
City string
}
type User struct {
Name string
Address Address
}
func main() {
tmpl, err := template.New("test").Parse(`
用户 {{ .Name }} 住在 {{ .Address.City }}
`)
if err != nil {
panic(err)
}
data := User{
Name: "张三",
Address: Address{
City: "北京",
},
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}这里,
.Address.City
条件判断和循环是模板中常用的控制结构。Go模板使用
{{ if ... }}{{ else }}{{ end }}{{ range ... }}{{ end }}比如,你想根据用户的年龄来显示不同的消息:
package main
import (
"fmt"
"html/template"
"os"
)
type User struct {
Name string
Age int
}
func main() {
tmpl, err := template.New("test").Parse(`
{{ .Name }},
{{ if gt .Age 18 }}
你已经成年了。
{{ else }}
你还未成年。
{{ end }}
`)
if err != nil {
panic(err)
}
data := User{
Name: "李四",
Age: 20,
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}这里,
{{ if gt .Age 18 }}gt
循环的例子:
package main
import (
"fmt"
"html/template"
"os"
)
func main() {
tmpl, err := template.New("test").Parse(`
{{ range . }}
{{ . }}
{{ end }}
`)
if err != nil {
panic(err)
}
data := []string{"苹果", "香蕉", "橙子"}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}这个例子循环遍历一个字符串切片,并输出每个元素。
避免XSS攻击的关键在于对用户输入进行适当的转义。Go模板默认会自动转义HTML,防止XSS攻击。但是,在某些情况下,你可能需要手动转义。
Go模板提供了几个转义函数:
html
js
urlquery
例如,如果你的模板中包含用户输入的HTML内容,你需要使用
html
package main
import (
"fmt"
"html/template"
"os"
)
func main() {
tmpl, err := template.New("test").Parse(`
<div>
用户输入:{{ .UserInput | html }}
</div>
`)
if err != nil {
panic(err)
}
data := struct {
UserInput string
}{
UserInput: "<script>alert('XSS')</script>",
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}这里,
{{ .UserInput | html }}html
你可以在模板中直接调用结构体的方法,这使得模板可以更方便地处理结构体数据。 前提是方法要是导出的(首字母大写)。
package main
import (
"fmt"
"html/template"
"os"
)
type User struct {
FirstName string
LastName string
}
// 定义一个结构体方法,返回用户的全名
func (u User) FullName() string {
return u.FirstName + " " + u.LastName
}
func main() {
tmpl, err := template.New("test").Parse(`
{{ .FullName }}
`)
if err != nil {
panic(err)
}
data := User{
FirstName: "张",
LastName: "三",
}
err = tmpl.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}这里,
{{ .FullName }}User
FullName
以上就是Golang模板函数自定义与渲染技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号