Email 邮件服务(可选)
Template 模板系统
邮件模板引擎与内置模板
Template 模板系统
Email 插件内置 Go html/template 模板引擎,提供开箱即用的邮件模板,同时支持加载外部自定义模板。
内置模板
插件通过 embed.FS 嵌入模板文件,无需额外配置即可使用:
verification — 验证码邮件
用于发送邮箱验证码,包含高亮验证码和过期时间提示。
模板数据:
| 字段 | 类型 | 说明 |
|---|---|---|
Code | string | 验证码 |
Expire | string | 过期时间描述(如 "5 分钟") |
使用示例:
err := emailClient.SendTemplate(ctx, &xEmail.Message{
To: []string{"user@example.com"},
Subject: "邮箱验证码",
Template: "verification",
TemplateData: map[string]string{
"Code": "836521",
"Expire": "5 分钟",
},
})welcome — 欢迎注册邮件
用户注册成功后发送的欢迎邮件。
模板数据:
| 字段 | 类型 | 说明 |
|---|---|---|
Username | string | 用户名 |
使用示例:
err := emailClient.SendTemplate(ctx, &xEmail.Message{
To: []string{"user@example.com"},
Subject: "欢迎加入",
Template: "welcome",
TemplateData: map[string]string{
"Username": "筱锋",
},
})reset_password — 重置密码邮件
密码重置请求邮件,包含重置链接和安全提示。
模板数据:
| 字段 | 类型 | 说明 |
|---|---|---|
ResetURL | string | 密码重置链接 |
Expire | string | 链接过期时间描述(如 "30 分钟") |
使用示例:
err := emailClient.SendTemplate(ctx, &xEmail.Message{
To: []string{"user@example.com"},
Subject: "重置密码",
Template: "reset_password",
TemplateData: map[string]string{
"ResetURL": "https://example.com/reset?token=abc123",
"Expire": "30 分钟",
},
})模板架构
内置模板采用 基础布局 + 内容块 的架构:
_base.html ← 基础布局(页头、页脚、样式)
└── {{template "content" .}}
├── verification.html ← {{define "verification"}} 验证码
├── welcome.html ← {{define "welcome"}} 欢迎
└── reset_password.html ← {{define "reset_password"}} 重置密码_base.html提供统一的邮件外观(品牌标题、页脚声明、背景样式)- 每个具体模板通过
{{define "模板名"}}定义内容块,模板名须与文件名一致(不含.html后缀) - 渲染时通过
Lookup查找指定模板,将内容注入base布局的"content"槽位后输出
TemplateManager API
Render — 渲染模板
渲染指定模板并返回 HTML 字符串。
func (t *TemplateManager) Render(name string, data any) (string, error)参数:
name— 模板名称(不含.html后缀),如"verification"data— 模板数据,传入模板变量
示例:
html, err := emailClient.tmpl.Render("verification", map[string]string{
"Code": "123456",
"Expire": "5 分钟",
})
Render通常不需要直接调用,使用SendTemplate会自动渲染并发送。
ListTemplates — 列出模板
返回当前所有可用的模板名称。
func (t *TemplateManager) ListTemplates() []string示例:
names := emailClient.ListTemplates()
// ["verification", "welcome", "reset_password"]AddDir — 添加外部模板目录
加载外部目录中的 HTML 模板文件,同名模板覆盖内置模板。
func (t *TemplateManager) AddDir(dir string) error示例:
err := emailClient.AddTemplateDir("/path/to/custom/templates")自定义模板
方式一:环境变量指定外部模板目录
通过 EMAIL_TEMPLATE_DIR 环境变量指定外部模板目录,InitClient 时自动加载:
EMAIL_TEMPLATE_DIR=/path/to/custom/templates方式二:运行时动态添加
emailClient := xCtxUtil.MustGetEmailClient(ctx)
err := emailClient.AddTemplateDir("/path/to/custom/templates")编写自定义模板
在外部模板目录中创建 HTML 文件,文件名即为模板名称:
{{define "order_confirm"}}
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-bottom: 24px;">
<h2 style="margin: 0 0 16px; font-size: 20px; font-weight: 600; color: #1a1a1a;">
订单确认
</h2>
<p style="margin: 0; font-size: 15px; color: #555555; line-height: 1.6;">
您的订单 <strong style="color: #1a1a1a;">{{.OrderID}}</strong> 已确认。
</p>
<p style="margin: 16px 0 0; font-size: 15px; color: #555555; line-height: 1.6;">
金额: <strong style="color: #4f7cff;">¥{{.Amount}}</strong>
</p>
</td>
</tr>
</table>
{{end}}使用自定义模板:
err := emailClient.SendTemplate(ctx, &xEmail.Message{
To: []string{"user@example.com"},
Subject: "订单确认",
Template: "order_confirm",
TemplateData: map[string]any{
"OrderID": "ORD-20260503-001",
"Amount": "299.00",
},
})覆盖内置模板
在外部模板目录中创建与内置模板同名的文件即可覆盖:
custom/templates/
├── verification.html ← 覆盖内置验证码模板
└── order_confirm.html ← 新增自定义模板注意事项
- 模板名称: 模板名称不含
.html后缀和template/前缀,直接使用如"verification"。 _base.html不可覆盖: 基础布局模板名称为_base,不会出现在ListTemplates结果中。- 文件格式: 外部模板必须是
.html后缀的文件,且使用{{define "模板名"}}定义内容块。define名称须与文件名一致(不含.html后缀),例如order_confirm.html中应为{{define "order_confirm"}}。 - 数据传递:
TemplateData支持map[string]any或自定义结构体,模板中通过{{.FieldName}}访问字段。