发布于2026-07-19 阅读(0)
扫一扫,手机访问
用Go发邮件,模板渲染是绕不开的一步。标准库text/template就能搞定,无需第三方依赖,但有几个关键点——数据结构、转义处理、错误检查——稍不注意就会踩坑。下面分几个方面来梳理。

模板文件(比如email.txt)写成纯文本或HTML都可以,text/template本身不区分格式,只管替换变量:
Hi {{.Name}},
Your order #{{.OrderID}} has been shipped.
Tracking: {{.TrackingCode}}
Go代码里加载并渲染:
template.Must(template.ParseFiles("email.txt"))加载,它会在解析失败时panic,适合启动时加载。t.Execute(&buf, data)渲染,data必须是map、struct或支持字段访问的类型。Execute的返回error——空字段、类型不匹配、嵌套nil都会在这里报错,不是编译期问题。这个问题其实很常见。text/template默认会对所有输出做HTML转义,这是为了防止XSS攻击。但邮件正文如果是HTML格式,你并不想让<变成。
{{.HTMLBody | safeHTML}}显式标记可信内容(前提是.HTMLBody是template.HTML类型)。template.HTML类型:比如data := struct{ Body template.HTML }{Body: template.HTML(`Hello`)}。strings.ReplaceAll去“手动解码”转义后的字符串——这会破坏其他本该转义的内容,比如用户昵称里的。用{{define}}和{{template}}实现模块化,比拼接字符串更可靠:
{{define "header"}}Welcome!
{{end}}{{define "footer"}}© {{.Year}} Company
{{end}}{{template "header"}}Hi {{.Name}}...{{template "footer" .}}
template.ParseFiles会自动识别所有define块,无需单独注册。{{template "name" .}}中的.表示把当前作用域数据传给子模板;如果子模板需要不同结构,就传具体字段:{{template "footer" dict "Year" 2024}}(需配合template.FuncMap注入dict函数)。ParseGlob("templates/*.txt")一次性加载,避免漏掉define。模板能跑通 ≠ 邮件能正常显示:
\n还是
?纯文本邮件靠\n换行,HTML邮件靠
;别在text/plain部分写HTML标签。style="color:red"可能失效,优先用内联或纯文本方案。Content-Type头设为text/html; charset=utf-8,否则变成乱码——这个不在template控制范围内,是邮件库(如gomail)的配置项。最常被跳过的其实是错误路径:模板字段名写错、结构体字段未导出(首字母小写)、嵌套map键不存在——这些不会编译报错,但Execute会返回error并留空字段。线上环境务必log这个error,而不是只打印“send ok”。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8