i18n - niubods/playframework-notes GitHub Wiki

国际化

国际化(I18N)是一种让你的应用给不同地区提供不同语言的方法。按照下面的步骤就可以使你的应用启动国际化。

只使用UTF-8!

Play只支持一种编码:UTF-8。因为编码问题可能很诡异并且很难处理,所以我们决定只支持一种编码。UTF-8能显示所有语言的所有字符。

请确定在你的整个应用中坚持使用UTF-8:

  • 使用UTF-8编辑源文件。
  • 在HTTP头信息中定义适当的编码。
  • 设置你的HTML meta标签为UTF-8
  • 如果你使用数据库,配置成使用UTF-8,并且总是使用UTF-8连接。

注意

因为使用UTF-8的缘故,大多数Play配置文件,即使他们都是Java properties文件,也没有命名为 *.properties 。Java强制要求properties文件必须用 ISO-8895-1 编码,而Play配置文件必须是UTF-8,够明白了吧?

外部化你的消息

要支持I18N,你需要将你应用中的所有消息外部化。

在你应用的 conf/ 目录下创建一个名为 messages 的文件。这个文件的真身其实就是一个Java properties文件。

hello=Hello!
back=Back

然后你可以为你应用的每一种语言定义一个特定的 message 文件。只需将ISO语言代码作为后缀名添加进去。

例如,包含相应法语翻译的消息文件就是 conf/messages.fr

hello=Bonjour!
back=Retour

定义应用支持的语言

application.confapplication.langs 项中定义支持的语言列表。

在一个新用户第一次请求时,Play会猜测要使用的默认语言。依据是从HTTP请求中解析出的 Accept-language 头信息。然后它会把选定的语言存入 PLAY_LANG cookie中。于是接下来的请求都会使用同一种语言。

如果你想区分语言的变体,也可以使用语言/国家对。例如en_US和en_GB,或是zh_CN和zh_TW。然而,考虑到用户的Accept-language中可能只有语言而没有国家。基于上述原因,你应该总是提供一个“裸”语言(例如 en)。

举个例子,比如你的大部分用户都来自美国但同时你又想支持英国英语,那么推荐的做法是给美国英语用"en",英国英语用"en_GB"。

通过访问 play.i18n.Lang 对象,你可以从你的应用代码中获取到用户的当前语言。

String lang = Lang.get();

如果你想永久地改变用户的语言,可以使用change()方法:

Lang.change("ja");

新的值会保存到用户语言的cookie中。

根据你的区域设置定义日期类型

配置application.conf中的 “data.format” 来指定默认的日期格式。

取出本地化消息

消息参数

从应用程序代码中,你可以取出定义在消息文件中的消息,在Java代码中,使用 play.i18n.Message 对象。

public static void hello() {
    renderText(Messages.get("hello"));
}

我们支持标准的 java.util.Formatter “格式化字符串语法”来格式化消息。这样就可以在你的消息中定义动态内容:

hello=Hello %s!

这里的 %s 代表一个会作为 String 输出的消息参数。将额外的(varargs)参数传给 Message.get 来提供消息参数:

public static void hello(String user) {
    renderText(Messages.get("hello", user));
}

模板输出

从模板中你可以使用特定的 &{…} 语法来显示本地化消息:

<h1>&{'hello'}</h1>

或者在消息参数中使用动态内容:

<h1>&{'hello', params.user}</h1>

多参数

你可以定义多个消息参数,比如这条消息就引用了两个‘十进制整数’参数:

guess=Please pick a number between %d and %d

你只需以正确的顺序指定消息参数就可以把它显示出来:

<p>&{'guess', low, high}</p>

参数索引

你也可以使用不同的参数顺序然后明确指定消息参数。举个例子,假设一条英语消息有两个参数:

guess.characteristic=Guess %s’s %s.

像这样输出消息:

<p>&{'guess.characteristic', person.name, 'age'}</p>

法语的本地化中两个消息参数顺序是相反的,所以在法语的本地化中我们指定消息的索引:

guess.characteristic=Devinez %2$s de %1$s.

这里 %2$s第二个 参数作为字符串(译注:原文是“十进制整数”decimal integer,有误)输出。

最后,我们还想把特征名称“age”也本地化,那么我们要使用消息的key persion.age 来输出,然后把消息的定义换成:

guess.characteristic=Guess %s’s &{%s}.
person.age = age

然后

guess.characteristic=Devinez &{%2$s} de %1$s.
person.age = l’age

这里 &{%s} 本身是一个消息的查找,消息值作为消息的key。

⚠️ **GitHub.com Fallback** ⚠️