i18n - niubods/playframework-notes GitHub Wiki
国际化(I18N)是一种让你的应用给不同地区提供不同语言的方法。按照下面的步骤就可以使你的应用启动国际化。
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.conf
的 application.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。