Golang模板中如何添加自定义函数

Golang模板中如何添加自定义函数 我想在模板中将一个数字除以1000,所以我写了:

fm := template.FuncMap{"divideBy1000": func(a int) float64 {
		return a / 1000
}}

t, err := template.ParseFiles("order.html")
if err != nil {
	panic(err)
}

var processed bytes.Buffer

err = t.ExecuteTemplate(&processed, "page", struct {
		Sender   string
		PushName string
		OLines   global.OrderDetailData
      }{
		Sender:   sender,
		PushName: pushName,
		OLines:   oLines})
if err != nil {
	panic(err)
}

outputPath := "./attachements/index.html"
f, err := os.Create(outputPath)
if err != nil {
	panic(err)
}
w := bufio.NewWriter(f)
w.WriteString(processed.String())
w.Flush()

在我的模板中,我有:

{{define "page"}}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta name="x-apple-disable-message-reformatting">
  <title>{{.Sender}}</title>
</head>
<body style="margin:0;padding:0;">
    User: {{.PushName}}<br>
    Mobiles:{{.Sender}}<br>
    ===========
    <br>
    Order id: {{.OLines.Order.ID}} <br>
    Order date: {{.OLines.Order.CreationTs}}<br>
    Order lines:<br>
    ===========
    <br>
    {{range .OLines.Order.Product}} 
        SKU Code: {{.RetailerID}} <br>
        Name: {{.Name}} <br>
        Qty: {{.Quantity}}
        Price: {{.Price}} <br>
        Currency: {{.Currency}} <br>
        <a href={{.Image.URL}}>Link</a>
        <br><br>
    {{end}}<br>
    =====================<br>
    Approximate value: {{.OLines.Order.Price.Total}}<br>
    Approximate value in Thousands: {{divideBy1000 .OLines.Order.Price.Total}}<br>
</body>
</html>
{{end}}

但我的模板没有执行,因为模板末尾的语句:

{{divideBy1000 .OLines.Order.Price.Total}}

这意味着函数 divideBy1000 未定义,这是正确的,因为我不知道如何将我的函数 fm 附加到模板:

fm := template.FuncMap{"divideBy1000": func(a int) float64 {
        return a / 1000
}}

有什么想法吗?


更多关于Golang模板中如何添加自定义函数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

更多关于Golang模板中如何添加自定义函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go模板中添加自定义函数需要在使用template.New()创建模板时注册函数映射。以下是修改后的代码:

// 定义自定义函数
fm := template.FuncMap{
    "divideBy1000": func(a int) float64 {
        return float64(a) / 1000.0
    },
}

// 创建模板时注册函数
t := template.New("order.html").Funcs(fm)

// 解析模板文件
t, err := t.ParseFiles("order.html")
if err != nil {
    panic(err)
}

var processed bytes.Buffer

// 执行模板
err = t.ExecuteTemplate(&processed, "page", struct {
    Sender   string
    PushName string
    OLines   global.OrderDetailData
}{
    Sender:   sender,
    PushName: pushName,
    OLines:   oLines,
})
if err != nil {
    panic(err)
}

outputPath := "./attachements/index.html"
f, err := os.Create(outputPath)
if err != nil {
    panic(err)
}
defer f.Close()

w := bufio.NewWriter(f)
w.WriteString(processed.String())
w.Flush()

另外,你的函数定义需要修正整数除法问题。当前函数返回的是整数除法结果,应该改为浮点数除法:

fm := template.FuncMap{
    "divideBy1000": func(a int) float64 {
        return float64(a) / 1000.0
    },
}

如果Total字段是其他数值类型(如float64),可以这样定义更通用的函数:

fm := template.FuncMap{
    "divideBy1000": func(a interface{}) float64 {
        switch v := a.(type) {
        case int:
            return float64(v) / 1000.0
        case float64:
            return v / 1000.0
        case float32:
            return float64(v) / 1000.0
        default:
            return 0
        }
    },
}

这样修改后,模板中的{{divideBy1000 .OLines.Order.Price.Total}}就能正确调用自定义函数了。

回到顶部