§使用訊息進行國際化
§指定應用程式支援的語言
使用語言標籤為應用程式指定語言,語言標籤是特別格式化的字串,用於識別特定語言。語言標籤可以指定簡單的語言,例如「en」代表英文,語言的特定區域方言(例如「en-AU」代表澳洲使用的英文),語言和文字系統(例如「az-Latn」代表以拉丁文字系統書寫的亞塞拜然語),或結合上述多種(例如「zh-cmn-Hans-CN」代表中國使用的中文、普通話、簡體字)。
首先,您需要在 conf/application.conf
檔案中指定應用程式支援的語言
play.i18n.langs = [ "en", "en-US", "fr" ]
這些語言標籤將用於建立 play.i18n.Lang
實例。若要存取應用程式支援的語言,您可以將 play.i18n.Langs
元件注入到您的類別中
import play.i18n.Langs;
import play.i18n.Messages;
import play.i18n.MessagesApi;
import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
public class MyService {
private final Langs langs;
@Inject
public MyService(Langs langs) {
this.langs = langs;
}
}
個別的 play.i18n.Lang
可以使用 lang.toLocale()
方法轉換為 java.util.Locale
物件
java.util.Locale locale = lang.toLocale();
§將訊息外部分類
您可以在 conf/messages.xxx
檔案中將訊息外部分類。
預設的 conf/messages
檔案符合所有語言。您可以指定其他語言訊息檔案,例如 conf/messages.fr
或 conf/messages.en-US
。
訊息可透過 MessagesApi
實例取得,此實例可透過注入新增。然後,您可以使用 play.i18n.Messages
物件擷取訊息
class SomeService {
private final play.i18n.MessagesApi messagesApi;
@Inject
SomeService(MessagesApi messagesApi) {
this.messagesApi = messagesApi;
}
public void message() {
Collection<Lang> candidates = Collections.singletonList(new Lang(Locale.US));
Messages messages = messagesApi.preferred(candidates);
String message = messages.at("home.title");
}
}
如果您不想使用 preferred(...)
來擷取 Messages
物件,您可以透過明確指定訊息的語言來直接取得訊息字串
String title = messagesApi.get(Lang.forCode("fr"), "hello");
請注意,您應使用 依賴注入 來注入 play.i18n.MessagesApi
類別。例如,使用 Guice 時,您會執行下列動作
public class MyClass {
private final play.i18n.MessagesApi messagesApi;
@Inject
public MyClass(MessagesApi messagesApi) {
this.messagesApi = messagesApi;
}
}
§在控制器中使用
如果您在控制器中,您可以透過目前的 Http.Request
取得 Messages
實例
public Result index(Http.Request request) {
Messages messages = this.messagesApi.preferred(request);
String hello = messages.at("hello");
return ok(hellotemplate.render(messages));
}
MessagesApi.preferred(request)
會透過以下方式來判斷語言
- 查看
Request
是否有暫時語言,方法是檢查其transientLang()
方法。 - 在要求中尋找
PLAY_LANG
Cookie。 - 查看要求的
Accept-Language
標頭。 - 使用應用程式的預設語言。
若要將 Messages
用於表單處理的一部分,請參閱 處理表單提交。
§在範本中使用
取得 Messages 物件後,您可以將它傳遞到範本中
@(messages: play.i18n.Messages)
@messages.at("hello")
還有一個較短的形式與 messages.at
相等,許多人覺得它很有用。
@(messages: play.i18n.Messages)
@messages("hello")
使用 messages.at(...)
或單純使用 messages(...)
的在地化範本會像一般一樣被呼叫
public Result index(Http.Request request) {
Messages messages = this.messagesApi.preferred(request);
return ok(hellotemplate.render(messages));
}
§變更語言
如果您想變更目前要求的語言(但不是未來的要求),請使用 Request.withTransientLang(lang)
,它會設定目前要求的暫時語言。
如同 上方 所說明,在呼叫 MessagesApi.preferred(request)
時,會考量要求的暫時語言。這對於變更範本的語言很有用。
public Result index(Http.Request request) {
Lang lang = Lang.forCode("en-US");
Messages messages = this.messagesApi.preferred(request.withTransientLang(lang));
return ok(hellotemplate.render(messages));
}
如果您想要永久變更語言,您可以呼叫 Result
上的 withLang
來執行此動作。這會設定一個 PLAY_LANG
cookie 供將來的要求使用,因此會在後續的要求中呼叫 MessagesApi.preferred(request)
時使用(如 上方 所示)。
public Result index(Http.Request request) {
Lang lang = Lang.forCode("fr");
Messages messages = this.messagesApi.preferred(request.withTransientLang(lang));
return ok(hellotemplate.render(messages)).withLang(lang, messagesApi);
}
§格式化訊息
訊息使用 java.text.MessageFormat
函式庫進行格式化。例如,如果您已定義類似這樣的訊息
files.summary=The disk {1} contains {0} file(s).
您接著可以指定參數如下
Messages.get("files.summary", d.files.length, d.name)
§關於撇號的注意事項
由於訊息使用 java.text.MessageFormat
,請注意單引號用作轉譯參數替換的元字元。
例如,如果您已定義下列訊息
info.error=You aren''t logged in!
example.formatting=When using MessageFormat, '''{0}''' is replaced with the first parameter.
您應該會預期下列結果
String errorMessage = messages.at("info.error");
Boolean areEqual = errorMessage.equals("You aren't logged in!");
String errorMessage = messages.at("example.formatting");
Boolean areEqual =
errorMessage.equals(
"When using MessageFormat, '{0}' is replaced with the first parameter.");
§從 HTTP 要求中擷取支援的語言
您可以擷取特定 HTTP 要求的支援語言
public Result index(Http.Request request) {
List<Lang> langs = request.acceptLanguages();
String codes = langs.stream().map(Lang::code).collect(joining(","));
return ok(codes);
}
§使用明確的 MessagesApi
MessagesApi
的預設實作由 DefaultMessagesApi
實例支援,而這是一個 Scala API。但您可以實例化 DefaultMessagesApi
,並手動將其注入 MessagesApi
中,如下所示
private MessagesApi explicitMessagesApi() {
return new play.i18n.MessagesApi(
new play.api.i18n.DefaultMessagesApi(
Collections.singletonMap(
Lang.defaultLang().code(), Collections.singletonMap("foo", "bar")),
new play.api.i18n.DefaultLangs().asJava()));
}
如果您需要一個 MessagesApi
實例來進行單元測試,您也可以使用 play.test.Helpers.stubMessagesApi()
。請參閱 測試您的應用程式 以取得更多詳細資料。
下一步:相依性注入
在此文件發現錯誤?此頁面的原始程式碼可在 此處 找到。在閱讀 文件指南 後,請隨時提交拉取請求。有問題或建議要分享嗎?請前往 我們的社群論壇 與社群展開對話。