Play Framework多言語対応テンプレート完全ガイド!i18nの実装方法を解説
生徒
「Play Frameworkで作った画面の文字を、英語や日本語に自動で切り替えるにはどうすればいいですか?」
先生
「それにはScalaテンプレート内で国際化(i18n)の機能を使います。HTMLの中に直接文字を書くのではなく、特定のメッセージキーを指定する仕組みです。」
生徒
「テンプレート側では、具体的にどのようなコードを書けばいいんでしょうか?」
先生
「それでは、多言語対応の具体的なテンプレート実装方法を順番に学んでいきましょう!」
1. 多言語対応テンプレートの基本構造
Play Frameworkにおいて画面表示を担当するのはScalaテンプレートと呼ばれるファイルです。通常は拡張子が「.scala.html」となっています。多言語対応(i18n)を実現するためには、このテンプレートファイルが「Messages」というオブジェクトを受け取れる状態にする必要があります。
基本的には、テンプレートの先頭で定義する引数リストに、メッセージを処理するための情報を追加します。これにより、テンプレート内のどこからでも多言語翻訳された文字列を呼び出せるようになります。プログラミング未経験の方でも、まずは「テンプレートに翻訳辞書を渡す」というイメージを持てば理解しやすくなります。
2. implicitなMessagesパラメータの定義方法
テンプレートで翻訳機能を使うための最も標準的な方法は、引数部分に implicit Messages messages を定義することです。「implicit」というキーワードを付けることで、テンプレート内のメソッドが自動的にこのメッセージ機能を利用できるようになります。Java側からテンプレートを呼び出す際も、コントローラーが適切な言語設定を自動で引き継いでくれます。
この設定を行うことで、多言語対応の準備が整います。ファイルが日本語設定なら日本語を、英語設定なら英語を、Play Frameworkが賢く判断して表示を切り替えてくれるようになります。具体的なコードの書き方は以下のようになります。
@* 引数部分でMessagesを受け取る設定 *@
@(title: String)(implicit messages: play.i18n.Messages)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
</head>
<body>
@* ここにコンテンツを書く *@
</body>
</html>
3. messages.atメソッドによる文字列の出力
準備ができたら、実際に画面に文字を表示させてみましょう。テンプレート内で翻訳された文字を出すには @messages.at("キー名") という構文を使います。この「キー名」は、あらかじめ「conf/messages」ファイルに定義しておいた識別子のことです。直接「こんにちは」と書くのではなく、キーを指定するのがポイントです。
これにより、同じテンプレートファイルを使い回しながら、中身の言語だけを動的に変更することが可能になります。HTMLのタグの間や、ボタンのラベルなど、あらゆる場所でこのメソッドを使用することができます。初心者の方は、まず簡単な見出しから置き換えてみるのがおすすめです。
@* messagesファイルに定義したキーを呼び出す例 *@
<div class="container">
<h1>@messages.at("home.welcome.title")</h1>
<p>@messages.at("home.description")</p>
<button class="btn btn-success">
@messages.at("button.save")
</button>
</div>
4. 動的な値をメッセージに埋め込む引数の渡し方
単なる固定の文章だけでなく、「田中さん、こんにちは」のようにユーザーの名前などの動的な値を入れたい場合があります。messagesファイル側で {0} のようにプレースホルダーを定義しておけば、テンプレート側からその場所に値を流し込むことができます。やり方は非常に簡単で、at メソッドの第2引数以降に値を渡すだけです。
この機能を使えば、システムから取得した変数や計算結果を翻訳文の中に自然に組み込むことができます。また、数値や日付などもこの方法で埋め込むことが可能です。プログラミングの柔軟性がぐっと高まる便利な手法です。
@* 動的な変数(userName)を翻訳文の中に埋め込む *@
@(userName: String)(implicit messages: play.i18n.Messages)
<div class="alert alert-info">
@* messages.jaに welcome={0}さん、ようこそ! とある場合 *@
<strong>@messages.at("welcome", userName)</strong>
</div>
5. フォーム部品のラベルを多言語化する手順
Webアプリに欠かせないフォーム入力画面でも、多言語対応は重要です。Play Frameworkのヘルパー機能を使って入力項目(input)を作る場合、ラベル部分にメッセージキーを直接指定することができます。これにより、入力フォーム全体を各言語に合わせた表示に一括で切り替えることができます。
Javaのコントローラーでフォーム定義を行う際にも関連しますが、テンプレート側では特に意識せずとも、messagesファイルの設定が優先されるようになっています。ユーザーにとって使いやすい親切なインターフェースを作るためには、このフォームの多言語化が欠かせません。以下に、入力フォームでの実装例を示します。
@* フォームヘルパーと連携した多言語表示 *@
@import helper._
@inputText(
myForm("username"),
'label -> messages.at("form.label.username"),
'placeholder -> messages.at("form.placeholder.username"),
'class -> "form-control"
)
6. JavaコントローラーからMessagesを渡す処理
テンプレートで implicit messages を使うためには、Javaのコントローラー側でその情報を正しく準備して渡してあげる必要があります。最新のPlay Frameworkでは、コントローラーで MessagesApi を利用し、レンダリング時に引数として追加します。この際、リクエストに含まれる言語情報を優先するように設定するのが一般的です。
これにより、ブラウザが「英語優先」と言っていれば英語のMessagesオブジェクトが生成され、テンプレートに渡されます。内部的な仕組みは複雑ですが、コード自体は定型的なものなので、パターンとして覚えてしまえば初心者でも難しくありません。実際のJavaコードでの渡し方を見てみましょう。
public class MyController extends Controller {
@Inject
MessagesApi messagesApi;
public Result index(Http.Request request) {
// リクエストからユーザーの好みの言語を取得してMessagesオブジェクトを作成
Messages messages = messagesApi.preferred(request);
// テンプレートの引数として渡す
return ok(views.html.index.render("マイページ", messages));
}
}
実行した結果、ブラウザの言語設定に応じてテンプレート内のメッセージが適切に変換されます。
(出力結果例)
<h1>ようこそ、ゲストさん!</h1>
<button>保存する</button>
7. レイアウトファイルでの共通メッセージ管理
複数のページで共通して使うヘッダーやフッターがある場合、それらをまとめた「レイアウト用テンプレート」でも多言語対応を行うのが効率的です。各ページのテンプレートからレイアウトに Messages を引き渡すように設計することで、サイト全体の共通語句を一箇所で管理できます。
例えば、メニューの「ホーム」「お問い合わせ」「設定」といった項目をmessagesファイルで管理すれば、新しい言語を追加した際もレイアウトファイルを一切触らずに済みます。保守性の高い、プロフェッショナルなアプリケーション開発には欠かせない考え方です。大規模なサイトになればなるほど、この構造の恩恵を感じることができるでしょう。
8. エラーメッセージの多言語化とバリデーション
ユーザーが入力ミスをした際に表示されるエラーメッセージも、多言語対応の対象です。Play Frameworkのフォームバリデーション機能とmessagesファイルを連携させることで、「この項目は必須です」といった警告文を自動で言語切り替えできます。この場合、あらかじめ決められたエラーキーをmessagesファイルに登録しておく必要があります。
特定の入力チェックに対して独自のメッセージを出したい場合も、キーを指定するだけで簡単にカスタマイズ可能です。初心者の方がアプリを公開する際には、こうした細かいエラー表示まで丁寧に対応することで、ユーザーの信頼を得ることができます。プログラムのロジックと表示を分離するメリットがここで大きく発揮されます。
9. テンプレート内で言語コードを確認する方法
稀に、言語によって表示する画像を変えたり、デザインを微調整したりするために、現在の言語コード("ja"や"en"など)をテンプレート内で直接知りたい場合があります。その場合は、受け取った messages オブジェクトから言語情報を取得することができます。
@messages.lang().code() と記述することで、現在の言語コードを文字列として取得できます。これを利用して、特定の言語の時だけ特別な案内を表示する、といった条件分岐(if文)をテンプレート内に書くことも可能です。多言語対応の応用テクニックとして覚えておくと、表現の幅がより一層広がります。