Golang中关于带占位符的文本邮件模板的疑问

Golang中关于带占位符的文本邮件模板的疑问 我有以下需求:

  • 需要发送基于文本/HTML的定制化邮件
  • 为每种邮件类型创建包含占位符的模板文件
  • 需要向模板传递映射参数,并返回邮件正文

请注意,我不想遍历映射,而且由于可能存在大量邮件模板,无法为每个模板创建结构体。 以下是需求示例:

模板 - the quick {{. color}} {{. animal1}} jumped over the lazy {{. animal2}} 模板解析器输入 - 键值对映射 - [“color”:“brown”, “animal1”:dog, “animal2”:“fox”] 预期输出 - the quick brown dog jumped over the lazy fox

请建议如何实现此功能。

此致


更多关于Golang中关于带占位符的文本邮件模板的疑问的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你查看过 html/template 的文档吗?https://golang.org/pkg/html/template/

更多关于Golang中关于带占位符的文本邮件模板的疑问的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


可以使用Go标准库中的text/template包来实现带占位符的文本邮件模板功能。以下是一个完整的实现示例:

package main

import (
    "bytes"
    "fmt"
    "text/template"
)

// 邮件模板管理器
type EmailTemplateManager struct {
    templates map[string]*template.Template
}

// 创建新的模板管理器
func NewEmailTemplateManager() *EmailTemplateManager {
    return &EmailTemplateManager{
        templates: make(map[string]*template.Template),
    }
}

// 添加模板
func (etm *EmailTemplateManager) AddTemplate(name, templateString string) error {
    tmpl, err := template.New(name).Parse(templateString)
    if err != nil {
        return err
    }
    etm.templates[name] = tmpl
    return nil
}

// 渲染模板
func (etm *EmailTemplateManager) RenderTemplate(name string, data map[string]interface{}) (string, error) {
    tmpl, exists := etm.templates[name]
    if !exists {
        return "", fmt.Errorf("template '%s' not found", name)
    }
    
    var buf bytes.Buffer
    err := tmpl.Execute(&buf, data)
    if err != nil {
        return "", err
    }
    
    return buf.String(), nil
}

func main() {
    // 创建模板管理器
    templateManager := NewEmailTemplateManager()
    
    // 添加模板
    err := templateManager.AddTemplate("animal_jump", "the quick {{.color}} {{.animal1}} jumped over the lazy {{.animal2}}")
    if err != nil {
        panic(err)
    }
    
    // 准备模板数据
    data := map[string]interface{}{
        "color":   "brown",
        "animal1": "dog",
        "animal2": "fox",
    }
    
    // 渲染模板
    result, err := templateManager.RenderTemplate("animal_jump", data)
    if err != nil {
        panic(err)
    }
    
    fmt.Println(result)
    // 输出: the quick brown dog jumped over the lazy fox
}

对于HTML邮件模板,可以使用html/template包,它提供相同的API但会自动转义HTML内容以防止XSS攻击:

package main

import (
    "bytes"
    "fmt"
    "html/template"
)

type HTMLEmailTemplateManager struct {
    templates map[string]*template.Template
}

func NewHTMLEmailTemplateManager() *HTMLEmailTemplateManager {
    return &HTMLEmailTemplateManager{
        templates: make(map[string]*template.Template),
    }
}

func (hetm *HTMLEmailTemplateManager) AddHTMLTemplate(name, templateString string) error {
    tmpl, err := template.New(name).Parse(templateString)
    if err != nil {
        return err
    }
    hetm.templates[name] = tmpl
    return nil
}

func (hetm *HTMLEmailTemplateManager) RenderHTMLTemplate(name string, data map[string]interface{}) (string, error) {
    tmpl, exists := hetm.templates[name]
    if !exists {
        return "", fmt.Errorf("template '%s' not found", name)
    }
    
    var buf bytes.Buffer
    err := tmpl.Execute(&buf, data)
    if err != nil {
        return "", err
    }
    
    return buf.String(), nil
}

func main() {
    // HTML邮件模板示例
    htmlTemplateManager := NewHTMLEmailTemplateManager()
    
    htmlTemplate := `
<!DOCTYPE html>
<html>
<head>
    <title>邮件通知</title>
</head>
<body>
    <h1>欢迎, {{.name}}!</h1>
    <p>您的订单 {{.orderId}} 已经处理完成。</p>
    <p>总金额: ${{.amount}}</p>
</body>
</html>`
    
    err := htmlTemplateManager.AddHTMLTemplate("order_confirmation", htmlTemplate)
    if err != nil {
        panic(err)
    }
    
    htmlData := map[string]interface{}{
        "name":    "张三",
        "orderId": "ORD-12345",
        "amount":  "99.99",
    }
    
    htmlResult, err := htmlTemplateManager.RenderHTMLTemplate("order_confirmation", htmlData)
    if err != nil {
        panic(err)
    }
    
    fmt.Println(htmlResult)
}

这个实现满足你的所有需求:

  • 支持文本和HTML邮件模板
  • 使用占位符{{.fieldName}}语法
  • 接受映射参数进行模板渲染
  • 不需要为每个模板创建结构体
  • 不需要手动遍历映射

模板语法使用Go标准模板语法,{{.color}}会从传入的映射中查找"color"键对应的值并替换。

回到顶部