Revel中Message("login.title")总返回原始key,是因为未启用I18nFilter或翻译文件未正确加载:需在app.conf设i18n.enabled=true,文件路径为app/messages/{lang}.ini(如zh-CN.ini),且locale标签须与请求头或c.Locale严格匹配,不支持模糊降级。

Revel 的 I18nFilter 默认就支持多语言,但必须正确配置语言标签、加载翻译文件、并在模板/代码中显式调用,否则 Message() 会始终返回 key 或 panic。
为什么 Message("login.title") 总是返回原始 key?
常见原因是没启用 I18nFilter 或翻译文件未加载。Revel 默认已将 I18nFilter 加入全局 filter 链,但前提是:app.conf 中启用了 i18n 配置,且 messages/ 下存在对应语言的 .ini 文件。
-
app.conf必须包含i18n.enabled = true(默认为true,但显式写上更稳妥) - 翻译文件路径必须为
app/messages/{lang}.ini,例如app/messages/zh-CN.ini或app/messages/en-US.ini - 文件名中的语言标签需与浏览器
Accept-Language头或手动设置的c.Request.Header.Set("Accept-Language", "zh-CN")匹配 - 若使用自定义语言解析逻辑(如从 URL path 或 cookie 读取),需在
I18nFilter前插入自定义 filter 并设置c.Locale
app/messages/ 下的 .ini 文件怎么写才有效?
Revel 使用标准 INI 格式,**不支持嵌套节、注释符号分号 ; 会被忽略,等号前后不能有空格**。错误示例:login.title = 登录页面 # 注释 会导致值截断;正确写法:
[en-US] login.title = Login Page login.submit = Sign In <p>[zh-CN] login.title = 登录页面 login.submit = 登录</p>
- 每个语言一个独立文件,文件名即 locale(如
zh-CN.ini),不要放在子目录 - key 名区分大小写,且不能含点号以外的标点(
login.title合法,login-title会解析失败) - 值中若含换行或双引号,需用反斜杠转义,Revel 不支持多行字符串原生语法
模板里用 {{i18n "login.title"}} 没反应?
两个最常被忽略的点:一是模板函数名是 i18n(不是 Message 或 trans),二是它只接受字符串字面量或变量,不支持表达式拼接。
- ✅ 正确:
{{i18n "login.title"}}、{{i18n .TitleKey}} - ❌ 错误:
{{i18n "login." + .Page}}(模板不支持字符串拼接)、{{Message "login.title"}}(函数不存在) - 若需动态 key,先在 controller 中计算好再传入:
c.RenderArgs["titleKey"] = "login." + c.Params.Get("type"),模板中用{{i18n .titleKey}} -
{{i18n}}函数内部会 fallback 到en-US(若存在),再 fallback 到 key 本身 —— 所以没配文件时看到原始 key 是正常行为,不是 bug
如何让 Revel 从 URL 或 cookie 强制切换语言?
Revel 不自动解析 ?lang=zh-CN 或 lang=zh-CN cookie,需要自己写 filter 插入到 I18nFilter 之前,并设置 c.Locale。
- 在
app/init.go的init()函数中注册自定义 filter:revel.InterceptFunc(setLocale, revel.BEFORE) - 实现
setLocale:从c.Params.Get("lang")或c.Cookies["lang"].Value读值,校验是否在白名单内(如[]string{"en-US", "zh-CN"}),然后赋值给c.Locale - 注意顺序:该 filter 必须在
I18nFilter之前执行,否则I18nFilter已根据原始请求头设好 locale,后续覆盖无效 - 设置后记得写回 cookie 或重定向保留状态,否则刷新页面又回到浏览器默认语言
最容易被忽略的是 locale 字符串的精确匹配 —— zh 和 zh-CN 被视为不同语言,I18nFilter 不做模糊匹配或降级查找(比如没有 zh-CN.ini 就不会尝试 zh.ini)。生产环境务必确保文件名、请求头、代码中使用的 locale 字符串三者完全一致。











