beego的i18n模块需显式调用i18n.setmessage("en-us", "conf/locale_en-us.ini")注册utf-8无bom的ini文件,控制器中须在prepare()内设b.lang并确保其与已注册语言码严格一致,否则t()将返回原始key。

Beego 的 i18n 模块能直接支持多语言,但必须手动加载本地化文件、显式设置语言上下文,且不自动 fallback 到默认语言——漏掉任一环节,T() 函数就会返回空字符串或原始 key。
如何正确注册 locale 文件并确保被识别
Beego 不会自动扫描 conf/ 下的 .ini 文件,必须调用 i18n.SetMessage() 显式注册。文件路径需完整(含扩展名),语言 code 必须与参数第一个参数严格一致:
-
i18n.SetMessage("en-US", "conf/locale_en-US.ini")成功;i18n.SetMessage("en", "...")或i18n.SetMessage("en-US", "locale_en-US")都会失败 - 文件编码必须是 UTF-8 无 BOM,否则中文乱码或解析失败(常见于 Windows 记事本保存)
- INI 文件中等号两侧不能有空格:
hi = hello会导致值为空;应写为hi=hello - 若使用
beego.AppConfig.String("lang::types")读取配置,确保app.conf中存在[lang]区段且格式正确:[lang] types = en-US|zh-CN names = English|中文
控制器中怎么拿到当前请求的语言并生效
不能只靠 i18n.Locale 嵌入结构体,它本身不带语言逻辑。必须在 Prepare() 中调用 b.SetLang() 或手动设置 b.Lang 字段,并确保该语言已通过 i18n.SetMessage() 注册过:
- 推荐方式:从 Cookie(如
lang=en-US)、URL 参数(?lang=zh-CN)或Accept-Language头提取语言 code,再调用b.Lang = lang - 若未设置
b.Lang,b.T("hi")默认使用空字符串作为 key 查找,结果为空 -
b.Locale是嵌入字段,仅提供T()方法快捷访问,不参与语言自动推导 - 务必检查
b.Lang是否为空或非法值,避免传入未注册的语言导致静默失败
为什么 T() 总是返回原始 key 而不是翻译文本
这是最常踩的坑,根本原因只有两个:语言未注册,或当前控制器 Lang 字段为空/不匹配。调试时可加一行日志验证:
beego.Debug("current lang:", b.Lang, "has messages for en-US?", i18n.IsExist("en-US", "hi"))
-
i18n.IsExist(lang, key)返回false表示该语言下 key 未定义,说明文件没加载、key 拼错、或语言 code 不一致 -
T()不做 fallback:b.Lang = "ja-JP"但只加载了en-US和zh-CN,则b.T("hi")直接返回"hi",不会退到en-US - 模板中使用
{{.T "hi"}}时,依赖的是 controller 实例的T()方法,所以同样受b.Lang控制
真正的难点不在语法,而在语言生命周期管理:每个请求要独立确定语言、每个语言要提前注册、每个 key 要保证所有语言文件里都存在——少一个环节,翻译就断在看不见的地方。











