1. 基础用法
1.1 创建简单模板函数
package main
import (
"html/template"
"os"
)
func main() {
// 创建自定义函数映射
funcmap := template.funcmap{
"upper": strings.toupper,
"lower": strings.tolower,
}
// 创建模板并添加函数
tmpl := template.new("test").funcs(funcmap)
// 解析模板内容
tmpl, err := tmpl.parse(`
原始字符串: {{.}}
大写: {{upper .}}
小写: {{lower .}}
`)
if err != nil {
panic(err)
}
// 执行模板
err = tmpl.execute(os.stdout, "hello, world!")
}
1.2 带参数的模板函数
package main
import (
"html/template"
"os"
)
func main() {
funcmap := template.funcmap{
"add": func(a, b int) int {
return a + b
},
"multiply": func(a, b int) int {
return a * b
},
}
tmpl := template.new("calc").funcs(funcmap)
tmpl, err := tmpl.parse(`
{{add 5 3}} = 8
{{multiply 4 6}} = 24
`)
if err != nil {
panic(err)
}
err = tmpl.execute(os.stdout, nil)
}
2. 高级用法
2.1 条件判断函数
package main
import (
"html/template"
"os"
)
func main() {
funcmap := template.funcmap{
"iseven": func(n int) bool {
return n%2 == 0
},
"ifthenelse": func(condition bool, a, b interface{}) interface{} {
if condition {
return a
}
return b
},
}
tmpl := template.new("conditions").funcs(funcmap)
tmpl, err := tmpl.parse(`
{{range $i := .}}
数字 {{$i}} 是: {{if iseven $i}}偶数{{else}}奇数{{end}}
另一种写法: {{ifthenelse (iseven $i) "偶数" "奇数"}}
{{end}}
`)
if err != nil {
panic(err)
}
numbers := []int{1, 2, 3, 4, 5}
err = tmpl.execute(os.stdout, numbers)
}
2.2 格式化函数
package main
import (
"fmt"
"html/template"
"os"
"time"
)
func main() {
funcmap := template.funcmap{
"formatdate": func(t time.time) string {
return t.format("2006-01-02 15:04:05")
},
"formatprice": func(price float64) string {
return fmt.sprintf("¥%.2f", price)
},
}
tmpl := template.new("format").funcs(funcmap)
tmpl, err := tmpl.parse(`
当前时间: {{formatdate .time}}
商品价格: {{formatprice .price}}
`)
if err != nil {
panic(err)
}
data := struct {
time time.time
price float64
}{
time: time.now(),
price: 99.99,
}
err = tmpl.execute(os.stdout, data)
}
2.3 切片操作函数
package main
import (
"html/template"
"os"
)
func main() {
funcmap := template.funcmap{
"first": func(x []interface{}) interface{} {
if len(x) > 0 {
return x[0]
}
return nil
},
"last": func(x []interface{}) interface{} {
if len(x) > 0 {
return x[len(x)-1]
}
return nil
},
"slice": func(x []interface{}, start, end int) []interface{} {
if start < 0 {
start = 0
}
if end > len(x) {
end = len(x)
}
return x[start:end]
},
}
tmpl := template.new("slice").funcs(funcmap)
tmpl, err := tmpl.parse(`
完整切片: {{.}}
第一个元素: {{first .}}
最后一个元素: {{last .}}
切片[1:3]: {{slice . 1 3}}
`)
if err != nil {
panic(err)
}
data := []interface{}{1, 2, 3, 4, 5}
err = tmpl.execute(os.stdout, data)
}
3. 实用示例
3.1 html 安全转义
package main
import (
"html/template"
"os"
)
func main() {
funcmap := template.funcmap{
"safe": func(s string) template.html {
return template.html(s)
},
"safeattr": func(s string) template.htmlattr {
return template.htmlattr(s)
},
}
tmpl := template.new("safe").funcs(funcmap)
tmpl, err := tmpl.parse(`
普通文本: {{.text}}
html内容: {{safe .html}}
属性值: <div {{safeattr .attr}}></div>
`)
if err != nil {
panic(err)
}
data := struct {
text string
html string
attr string
}{
text: "<b>文本</b>",
html: "<b>html</b>",
attr: `style="color: red"`,
}
err = tmpl.execute(os.stdout, data)
}
3.2 数据过滤和转换
package main
import (
"html/template"
"os"
"strings"
)
func main() {
funcmap := template.funcmap{
"join": strings.join,
"split": strings.split,
"title": strings.title,
"filter": func(arr []string, f func(string) bool) []string {
var result []string
for _, v := range arr {
if f(v) {
result = append(result, v)
}
}
return result
},
}
tmpl := template.new("filter").funcs(funcmap)
tmpl, err := tmpl.parse(`
原始数组: {{.}}
join结果: {{join . ","}}
split结果: {{split "a,b,c" ","}}
title结果: {{title "hello world"}}
filter结果: {{filter . (lambda "len" "gt" 3)}}
`)
if err != nil {
panic(err)
}
data := []string{"apple", "banana", "orange", "pear"}
err = tmpl.execute(os.stdout, data)
}
4. 最佳实践
4.1 模板函数组织
// template_funcs.go
package template
import "html/template"
// 创建全局函数映射
var globalfuncmap = template.funcmap{
// 字符串操作
"upper": strings.toupper,
"lower": strings.tolower,
"title": strings.title,
// 数值操作
"add": func(a, b int) int { return a + b },
"subtract": func(a, b int) int { return a - b },
"multiply": func(a, b int) int { return a * b },
"divide": func(a, b int) float64 { return float64(a) / float64(b) },
// 日期操作
"formatdate": func(t time.time, layout string) string { return t.format(layout) },
"now": time.now,
// 切片操作
"first": first,
"last": last,
"slice": slice,
// 条件操作
"iseven": iseven,
"ifthenelse": ifthenelse,
}
// 在应用中使用
func main() {
tmpl := template.new("page").funcs(globalfuncmap)
// ... 其他操作
}
4.2 错误处理
package main
import (
"html/template"
"os"
)
func main() {
funcmap := template.funcmap{
"divide": func(a, b int) (string, error) {
if b == 0 {
return "", fmt.errorf("除数不能为零")
}
return fmt.sprintf("%.2f", float64(a)/float64(b)), nil
},
}
tmpl := template.new("error").funcs(funcmap)
tmpl, err := tmpl.parse(`
{{with $result := divide 10 2}}
结果: {{$result}}
{{else}}
计算出错
{{end}}
`)
if err != nil {
panic(err)
}
err = tmpl.execute(os.stdout, nil)
}
总结
1.基本原则
- 保持函数简单明确
- 注意类型安全
- 适当处理错误
- 避免过度复杂的逻辑
2.常见用途
- 文本格式化
- 数据转换
- 条件判断
- 集合操作
- html 安全处理
3.性能考虑
- 缓存模板
- 避免重复解析
- 合理使用内存
到此这篇关于golang template实现自定义函数的操作指南的文章就介绍到这了,更多相关go template自定义函数内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论