Go Revel - i18n(国际化)
Messages
Messages
信息是对内容提供翻译的外部文本片段。revel提供了组织每一种语言文本片段的message文件、自动区域查找、基于cookie覆盖的消息嵌套和参数。
术语表:
Locale: 语言和区域的组合,表示一个用户首选语言, 例如 en-US
Language: 一个区域的语言部分, 例如 en. 预期为 ISO 639-1 编码
Region: 地区, 例如. US. 地区预期为 ISO 3166-1 alpha-2 编码
示例程序
revel处理message文件和国际化和其他的web框架差不多,在revel/samples/i18n
示例中可以了解详尽的使用方法。
Message文件
Messages
被定义在message文件,这些文件的message文本将被用于渲染模板(或程序中其他所期望的地方)。
创建一个新的meesage文件,需要记住一下几点:
1、所有message文件应当存储在程序根目录下的meesages
目录中
2、文件扩展名必须是当前语言的 ISO 639-1 编码
3、message文件应当是UTF-8
编码. 虽然这不是强制要求,但这是最佳实践
4、没一个message文件实际上是goconfig
格式的文件,它支持goconfig
的所有功能
组织Message文件
Message文件对名称没有任何限制,只要具有有效的扩展名。每一种语言也没有限定Message文件的数量。在程序启动时,revel会解析messages
目录中所有的文件,并按它们的语言分别合并到一起。这意味着可以按自己想要的方式来组织message文件。
例如,按传统的方式每一种语言定义单独的message文件:
/app
/messages
messages.en
messages.fr
...
或者另一种方法,同一种语言按类型创建多个不同的message文件:
/app
/messages
labels.en
warnings.en
labels.fr
warnings.fr
...
注意,在同一语言中定义相同键的多个message,这样虽然在技术上是可行的,但会带来不可预知的行为。在同一种语言使用多个message文件时,注意保持键的唯一,免得被后面同名key的值覆盖。
Message键值对
message文件本质上是一个goconfig
文件,这意味着它必须严格的遵守键值对格式:
key=value
例如:
greeting=Hello
greeting.name=Rob
greeting.suffix=, welcome to Revel!
分段
一个 goconfig
文件可以备份为若干段,默认段总是存在并包含没有被定义进任何分段的键值对。例如:
key=value
[SECTION]
key2=value2
Message文件的所有message应被定义进默认分段,除非他们属于这个语言的某个特定Region
地区。
地区
特定区域的message应以相同的名称定义在不同的分段中。假如,要对所有英语用户说"你好",英国用户应为"Hey",美国用户应为"Howdy",为了做到这点,我们定义如下message文件:
greeting=Hello
[GB]
greeting=Hey
[US]
greeting=Howdy
如果用户已经定义了自己的首选语言,revel会自动的使用相应语言来“问好”。
只有在特定情况下,用户的区域被明确定义为en-GB
或en-US
,问候消息才会使用特定的message解决。
如果一个Meesage定义在一个无效的分段里,虽然技术上可行,但是它们永远不会被使用。
引用和参数
引用
Meesage文件中的message,可以引用其他message。这使得用户可以从一个或多个Message组成一个单一的message。引用其他message的语法为%(key)s
。例如:
greeting=Hello
greeting.name=Rob
greeting.suffix=, welcome to Revel!
greeting.full=%(greeting)s %(greeting.name)s%(greeting.suffix)s
注:goconfig文件支持引用,由于message文件支持合并,所以可以从其他相同语言的message文件进行引用。
参数
Message支持一个或多个参数。参数使用go fmt
包中同样的规则解析。例如:
greeting.name_arg=Hello %s!
参数按照给定的顺序来解析。
解析客户端语言环境
为了弄清楚客户端的首选语言,revel会在以下地方寻找:
1、语言cookie
revel会在没一个请求的cookie中寻找程序配置的i18n字段(i18n.cookie
),如果找到,那么这个字段的值就被认为是客户端当前的语言环境。
2、Accept-Language
请求头
revel会自动解析每个请求头中的Accept-Language
, 每个Accept-Language
都会被保存在Request
实例中,用于在以后的各种message函数中确定当前语言环境。
3、默认语言
当上面所有的方法都没有正确查找到客户端的语言环境时,revel会将程序配置文件中定义的i18n.default_language
值作为默认语言。
当请求的message无法得到时,会返回一个包含原始信息的特定字符串。
注:每次请求的Accept-Language
请求头都会被解析并存储在Request
实例中,即使cookie中已经定义了语言。在这种情况下,它的值虽然不会被message解析函数使用,但我们仍然可以在程序中使用它。
获取当前的语言环境
程序可以通过Request.Locale
从当前的请求中获取被设置的语言环境。
例如:
func (c App) Index() revel.Result {
currentLocale := c.Request.Locale
c.Render(currentLocale)
}
在模板中,可以从传入的renderArgs
对象获取当前语言环境:
<p>Current preferred locale: {{.currentLocale}}</p>
解析Accept-Language
HTTP头
如果程序要访问Accept-Language
HTTP请求头,可以通过controller的Request
实例来获得。AcceptLanguages
是一个AcceptLanguage
的切片对象,包含了从相应的头字段中解析出来的值,按其含义的标识价值来排序。
func (c App) Index() revel.Result {
// 获得 AcceptLanguages的字符串表示
c.RenderArgs["acceptLanguageHeaderParsed"] = c.Request.AcceptLanguages.String()
// 获得最有价值的 AcceptLanguage 实例
c.RenderArgs["acceptLanguageHeaderMostQualified"] = c.Request.AcceptLanguages[0]
c.Render()
}
解析Message
Message可以从任意一个controller或view视图模板解析。
Controller
任何控制器都有Message(message string, args ...interface{})
方法来讲message解析为当前语言。如:
func (c App) Index() revel.Result {
c.RenderArgs["controllerGreeting"] = c.Message("greeting")
c.Render()
}
模板
在模板中,可以使用模板函数msg
来讲message解析为当前语言:
<p>Greetings without arguments: {{msg . "greeting"}}</p>
<p>Greetings: {{msg . "greeting.full.name" "Tommy Lee Jones"}}</p>
注:模板函数msg
的签名为 msg . "message name" "argument" "argument"
,如果没有参数,则不会解析任何message。
配置
文件 属性 描述
app.conf i18n.cookie cookie中语言字段的名称. 应当加上revel前缀避免冲突.
app.conf i18n.default_language 在没有任何首选语言的情况下所使用的默认语言.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述