文件

§使用訊息進行國際化

§指定應用程式支援的語言

使用語言標籤為應用程式指定語言,語言標籤是特別格式化的字串,用於識別特定語言。語言標籤可以指定簡單的語言,例如「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.frconf/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) 會透過以下方式來判斷語言

  1. 查看 Request 是否有暫時語言,方法是檢查其 transientLang() 方法。
  2. 在要求中尋找 PLAY_LANG Cookie。
  3. 查看要求的 Accept-Language 標頭。
  4. 使用應用程式的預設語言。

若要將 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()。請參閱 測試您的應用程式 以取得更多詳細資料。

下一步:相依性注入


在此文件發現錯誤?此頁面的原始程式碼可在 此處 找到。在閱讀 文件指南 後,請隨時提交拉取請求。有問題或建議要分享嗎?請前往 我們的社群論壇 與社群展開對話。