Messages

词汇表

  • Locale(语言环境): 包含 语言区域两个部分,指示用户的语言偏好,例如 。
  • Language(语言): locale 的语言部分, 例如 en。 语言标识符请参考 。
  • Region(区域): locale 的区域部分, 例如 US。 区域标识符请参考 ISO 3166-1 alpha-2 codes

Revel 处理消息文件和国际化的方法与其他框架类似。如果你想立马上手, 可以参考示例程序 revel/samples/i18n,里面包含所有的基础知识。

国际化消息在消息文件中定义。这些消息在渲染视图模板(或程序的其他地方)时使用。当创建新的消息文件时,需要遵循几个规则:

  • 所有的消息文件应存放在应用程序根目录的messages目录中。
  • 消息文件应该是 UTF-8 编码。虽然不是强制规定, 最好还是遵循这个约定。
  • 消息文件必须是 支持多有的 goconfig 特性

消息文件的文件名​​没有任何限制; 只要扩展名合法就行。每种语言的文件数量也没有限制。当应用程序启动时,Revel会解析messages语言目录中所有的扩展名合法的消息文件,并根据语言将它们合并。这意味着你可以自由组织你的消息文件。

例如,您可能希望采取传统的方法,在一个文件中定义所有的:

或者是为每种语言创建多个文件,并根据分类组织他们:

  1. /app
  2. /messages
  3. labels.en
  4. warnings.en
  5. labels.fr
  6. warnings.fr
  7. ...

重要注意事项: 在同一语言的多个文件中,虽然技术上可以定义相同的消息key,但是这将导致不可预知的行为。当每种语言定义了多个文件时,请注意保持您的key唯一,这样文件合并后,key将不会被覆盖!

消息 key 和 值

消息文件是一个 。这意味着,消息应按照key-value格式定义:

  1. key=value

举个栗子:

  1. greeting=Hello
  2. greeting.name=Rob
  3. greeting.suffix=, welcome to Revel!

goconfig 文件被分成多个 sections. 默认的段 总是存在, 并且包含未指定段时定义的消息。例如:

key=value 消息消息被隐式放置在默认段中,因为它没有定义在一个指定的段中。

注意: 段是 goconfig 功能.

特定区域的消息应当在相同的段中定义。Region-specific messages should be defined in sections with the same name. 例如,假设我们要对所有讲英语的用户显示 "Hello", 对英国用户显示 "Hey" ,对讲美国用户显示 "Howdy"。 为了做到这一点,我们可以定义下面的消息文件 greeting.en:

  1. [GB]
  2. greeting=Hey
  3. [US]
  4. greeting=Howdy

对于定义了英语 (en) 作为他们的首选语言时,Revel 会将greeting 解析成 Hello。只有在用户的区域被明确定义的情况下,比如en-GBen-US ,Revel 才会用对应段中的消息去解析 greeting

重要提示: 如果定义了一个不合法的区域,技术上是允许的,但是它们永远不会被解析。

引用 和 参数

引用

文件中的消息也可以引用其他消息。这使得用户可以从一个或多个其它的消息组成一个单一的消息。引用消息的语法是 %(key)s. 例如:

  1. greeting=Hello
  2. greeting.suffix=, welcome to Revel!
  3. greeting.full=%(greeting)s %(greeting.name)s%(greeting.suffix)s

注意:

  • 引用是 goconfig 的功能.
  • 因为消息文件可以合并,多以只要它们被定义为同一种语言,就可以引用其他文件中的消息。

参数

消息支持一个或多个参数。在消息中参数使用与 fmt 包相同的规则去解析。 例如:

  1. greeting.name_arg=Hello %s!

参数按照给定的顺序进行解析,参考 解析消息.

为了找出用户喜欢的语言环境,Revel会在以下地方查找一个可用的语言环境:

  • 语言 cookie

对于每次请求,框架会查找应用程序配置 (i18n.cookie)。如果找到了,它的值被假定为当前的语言环境。当一个cookie已经发现,所有其他解析方法将被跳过。

  • Accept-Language HTTP 头

更多信息请参考 .

  • 默认语言

当以上所有方法都没有找到可用的客户端语言环境时,框架将使用配置文件中定义的默认语言i18n.default_language

如果有的消息解析失败,则返回一个包含原始消息名的特殊格式的字符串。

注意: Accept-Language 头信息 总是 被解析并保存到当前 Request中, 即使它已经存在。在这种情况下,头信息中的值即使从未被消息解析功能使用,但是仍可以在需要他们的时候使用。

检查当前语言环境

应用程序可以从Request内部使用 Request.Locale 属性访问当前语言环境。例如:

在模板中, 就可以从 renderArgs 中的 currentLocale 变量中访问当前语言环境。 例如:

  1. <p>Current preferred locale: {{.currentLocale}}</p>

如果程序需要访问 Accept-Language HTTP 头信息, 可以从 Controller 实例的 Request中获取。 AcceptLanguages 字段(AcceptLanguage实例的切片)包含所有从各自的头信息中解析的值, 最合适的值是切片中的第一个。例如:

  1. func (c App) Index() revel.Result {
  2. // 获取所有解析到的AcceptLanguage的字符串表示形式
  3. c.RenderArgs["acceptLanguageHeaderParsed"] = c.Request.AcceptLanguages.String()
  4. // 返回最合适AcceptLanguage实例
  5. c.RenderArgs["acceptLanguageHeaderMostQualified"] = c.Request.AcceptLanguages[0]
  6.  
  7. c.Render()
  8. }

更多信息请参考 .

消息可以在 控制器模板中解析。

控制器

控制器中使用 Message(message string, args …interface{}) 函数使用当前语言环境解析消息:

  1. func (c App) Index() revel.Result {
  2. c.RenderArgs["controllerGreeting"] = c.Message("greeting")
  3. c.Render()
  4. }

模板

注意: msg 函数的签名是 msg . "message name" "argument" "argument". 如果没有参数, 可以忽略。