功能:通过模板使用Go中自定义函数(将邮箱字段的@符号替换为at);
遇见问题:在控制台打印模板输出时字符可以正常替换,但通过浏览器访问渲染模板时无法找到该自定义函数;
模板使用自定义函数步骤:
- 通过 template.New(`PathToHtml`) 分配一个Html模板;
- 调用 template.Funcs(template.FuncMap{"参数名":函数名}) 将实参map的元素添加到模板的函数map中。注意:必须在解析模板之前调用它;
- 解析模板:template.ParseFiles(`PathToHtml`) 注意:template.New() 函数中参数名字要和 template.ParseFiles() 函数的文件名要相同,要不然就会报错:"" is an incomplete template;
- 最后通过 template.ExecuteTemplate(wr io.Writer, name string, data interface{}) error 使用名为name的t关联的模板产生输出;
main.go
package main
type Friend struct {
Fname string
}
type Person struct {
UserName string
Emails []string // 未导出的字段首字母是小写的
Friends []*Friend
}
func EmailDealWith(args ...interface{}) string {
ok := false
var s string
if len(args) == 1 {
s, ok = args[0].(string)
}
if !ok {
s = fmt.Sprint(args...)
}
// find the @ symbol
substrs := strings.Split(s, "@")
if len(substrs) != 2 {
return s
}
// replace the @ by " at "
return (substrs[0] + "at" + substrs[1])
}
func ReplaceMain(w http.ResponseWriter, r *http.Request) {
f1 := Friend{Fname: "刘备"}
f2 := Friend{Fname: "关羽"}
f3 := Friend{Fname: "张飞"}
// 控制台输出模板内容
// t := template.New("fieldname example")
// t = t.Funcs(template.FuncMap{"emailDeal": EmailDealWith})
// t.Parse(`
// hello {{.UserName}}!
// {{range .Emails}}
// an emails {{.|emailDeal}}
// {{end}}
// {{with .Friends}}
// {{range .}}my friend name is {{.Fname}}
// {{end}}
// {{end}}
// `)
// p := Person{
// UserName: "Lisa",
// Emails: []string{"1111@qq.com", "2222@qq.com", "3333@qq.com"},
// Friends: []*Friend{&f1, &f2, &f3},
// }
// 输出
// t.Execute(os.Stdout, &p)
// 浏览器访问模板页
t := template.New(`template/html/replace.html`) // 静态页路径
t = t.Funcs(template.FuncMap{"emailDeal": EmailDealWith})
t, _ = t.ParseFiles(`template/html/replace.html`)
p := Person{
UserName: "Lisa",
Emails: []string{"1111@qq.com", "2222@qq.com", "3333@qq.com"},
Friends: []*Friend{&f1, &f2, &f3},
}
if err := t.ExecuteTemplate(w, "replace.html", p); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
// t.Execute(w, p)
}
func TemplateMain() {
http.HandleFunc("/replace", replace.ReplaceMain)
err := http.ListenAndServe("127.0.0.1:9091", nil)
if err != nil {
fmt.Println("failed to listen! ")
}
}
replace.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>替换</title>
</head>
<body>
{{if .UserName}}
hello, {{.UserName}}<br>
{{else}}
空
{{end}}
{{range .Emails}}
email : {{.|emailDeal}}<br>
{{end}}
{{with .Friends}}
{{range .}}
The name is {{.Fname}}<br>
{{end}}
{{end}}
</body>
</html>
至此,可以通过 template.Funcs(template.FuncMap{}) 设定符合自己需求的函数了!