Go go-i18n 怎样向消息模板传入命名字段
来源:17golang原创
时间:2026-10-30 23:11:51 262浏览 收藏
Go go-i18n 通过 i18n.LocalizeConfig.TemplateData 向消息模板传入命名字段。数据可以是 map,也可以是包含导出字段的结构体;模板用 {{.User}} 这样的表达式读取对应值。字段名必须与模板约定一致,不能把 JSON 标签名自动当成模板字段名。
官方地址:https://github.com/nicksnyder/go-i18n
选择模板数据而非字符串拼接
一个“文件已就绪”通知要包含用户、文件名和工作区。若在业务代码里先拼出前半句、再追加文件名,翻译人员就难以调整不同语言的语序。把整句作为一个消息模板,再传入命名字段,能让中文与英文各自安排字段位置。
这里的目标是稳定的消息数据契约。MessageID 标识消息,TemplateData 提供本次业务值,模板负责语言表达。命名字段适合需要多语言调整语序的句子;不应把普通数据值反过来拼入模板源码。
使用 TemplateData 传入命名字段
下面把两种语言的消息直接加入 Bundle,省去文件加载,让示例聚焦字段绑定。两条消息共享 UploadReady,字段均为 User、File、Workspace。Localizer 选择语言,Localize 执行对应模板。
package main
import (
"fmt"
"github.com/nicksnyder/go-i18n/v2/i18n"
i18ntemplate "github.com/nicksnyder/go-i18n/v2/i18n/template"
"golang.org/x/text/language"
)
func render() error {
bundle := i18n.NewBundle(language.English)
// 英文和简体中文使用相同消息 ID 与字段名,可分别调整字段顺序。
if err := bundle.AddMessages(language.English, &i18n.Message{
ID: "UploadReady",
Other: "{{.User}}: {{.File}} is ready in {{.Workspace}}.",
}); err != nil {
return err
}
if err := bundle.AddMessages(language.SimplifiedChinese, &i18n.Message{
ID: "UploadReady",
Other: "{{.User}},{{.Workspace}}中的文件{{.File}}已就绪。",
}); err != nil {
return err
}
localizer := i18n.NewLocalizer(bundle, "zh-Hans")
message, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: "UploadReady",
TemplateData: map[string]any{
"User": "林岚", "File": "report.csv", "Workspace": "项目资料",
},
// 缺失 map 键时返回模板错误,而不是依赖默认缺键显示。
TemplateParser: &i18ntemplate.TextParser{Option: "missingkey=error"},
})
if err != nil {
return fmt.Errorf("生成文件就绪提示: %w", err)
}
fmt.Println(message)
return nil
}
func main() {
if err := render(); err != nil {
panic(err) // 示例入口停止使用错误或不完整的消息。
}
}
按这段消息文本与字段值,中文提示应包含“林岚”“项目资料”和“report.csv”,它们的位置由中文模板决定。本文未运行程序,不把这段预期描述当作真实输出截图。

TemplateData 只负责执行时的数据,不负责把消息添加到 Bundle。消息不存在、语言发生回退或模板执行失败时,都应处理 Localize 返回的 error,不能只看是否得到非空字符串。接口定义见LocalizeConfig 官方文档。
比较 map 与结构体的数据契约
| 数据形式 | 模板读取 | 适合场景 | 主要注意点 |
|---|---|---|---|
| map[string]any | {{.User}} | 少量灵活字段 | 键名拼错通常只能在运行时发现 |
| 导出字段结构体 | {{.User}} | 消息字段稳定、多个调用点复用 | 字段需导出,模板引用仍是运行时约定 |
| 字符串拼接 | 不提供命名数据 | 仅非常简单且无需翻译重排的文本 | 跨语言语序容易被业务代码锁死 |
例如定义含 User、File、Workspace 三个导出字符串字段的结构体,作为 TemplateData 传入后可沿用同一模板。小写 user 属于未导出字段,不能按导出字段方式读取;json:"user" 不会把 {{.User}} 自动变成 {{.user}}。标准模板按自身字段和键访问规则执行,见text/template 文档。
结构体可以约束 Go 调用方的数据形状,但模板文本中的字段名并不由 Go 编译器检查。消息字段改名时,所有语言模板和数据构造点应一起更新。不要将一个语言中的 User 改为 Username,而其他翻译仍保留旧字段。
把 PluralCount 与显示字段分开
PluralCount 决定使用哪种复数形式,TemplateData 则提供要展示的字段。如果模板需要 {{.Count}},可以在 TemplateData 中明确放入 Count,同时把同一个业务数量传给 PluralCount。不要以为配置了 PluralCount 就一定会向你已经提供的 map 自动追加 Count。

当前实现只有在 TemplateData 为 nil 且 PluralCount 非 nil 时,才会构造包含键 PluralCount 的默认数据。因此此时模板使用的是 {{.PluralCount}};显式传入自己的数据后,需要自行保证模板所需字段齐全。相关行为见Localizer 实现。
这两项职责也不能互相替代:只给显示用的 Count 字段,不会自动触发正确的复数形式选择。数量用来选择语言规则时应保持原始数值语义;若需要特殊显示格式,可另提供展示字段。
处理模板错误及输出边界
默认模板解析器使用 text/template,缺少 map 键的默认选项是 missingkey=default。示例显式使用 TextParser{Option:"missingkey=error"},使 {{.User}} 这类直接字段访问缺键时报告错误。不要把默认缺键表现当作业务回退机制;结构体访问不存在字段也需要正确处理执行错误。
在正常请求处理中通常更适合 Localize 并显式处理错误;MustLocalize 遇错会 panic。业务可记录 MessageID 和缺失字段类别,再按既定策略提供提示,不应在日志中输出用户隐私字段的全部内容。
TemplateData 中的字符串会再次当模板执行吗?普通插入值不是新的模板源码。不要为了二次替换而把用户输入接回模板文本。
生成结果可以直接作为 HTML 吗?默认 text/template 不提供 html/template 的上下文自动转义。将结果放入网页时,应在展示层按上下文转义,不要随意转换为可信 HTML;也不要以为命名字段会自动过滤所有标签。
多个请求能共用一张可变 map 吗?不要让并发请求修改同一个模板数据 map。为每次调用准备独立数据或使用明确的同步与不可变约定,避免请求字段串用。
什么时候选结构体?当同一消息的数据由多个调用点构造、字段长期稳定时,可用小型专用结构体表达契约;字段少且变化较灵活时,map 更直接。无论哪种形式,字段名、错误处理和输出转义都要清楚。
-
860 收藏
-
843 收藏
-
826 收藏
-
809 收藏
-
792 收藏
-
330 收藏
-
466 收藏
-
178 收藏
-
434 收藏
-
240 收藏
-
263 收藏
-
173 收藏
-
149 收藏
-
479 收藏
-
136 收藏
-
273 收藏
-
262 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习