カテゴリ: Play Framework 更新日: 2026/02/09

Play Frameworkで多言語対応(i18n)を徹底解説!Twirlテンプレートでの使い方

多言語対応(i18n)をビューで行う方法
多言語対応(i18n)をビューで行う方法

先生と生徒の会話形式で理解しよう

生徒

「Play Frameworkで作ったWebサイトを、日本語だけじゃなくて英語でも表示したいんです。ページごとにHTMLを分ける必要があるんでしょうか?」

先生

「いいえ、HTMLファイルを分ける必要はありませんよ。Play Frameworkには『i18n』という多言語対応の仕組みがあって、メッセージファイルを用意するだけで表示を切り替えられるんです。」

生徒

「i18n…?難しそうですが、Twirlテンプレート(ビュー)の中で簡単に呼び出せるんですか?」

先生

「使い方はとてもシンプルです。設定方法からビューでの表示方法まで、ステップバイステップで見ていきましょう!」

1. 多言語対応(i18n)の基本概念と準備

1. 多言語対応(i18n)の基本概念と準備
1. 多言語対応(i18n)の基本概念と準備

Webアプリケーションにおける多言語対応は、一般的に「i18n」と呼ばれます。これは「internationalization(国際化)」の先頭の「i」と末尾の「n」の間に18文字あることに由来しています。Play Frameworkでは、この国際化の仕組みが標準で備わっており、ユーザーのブラウザ設定や特定の言語指定に合わせて、表示するテキストを動的に切り替えることができます。

まず最初に行うべき準備は、プロジェクトの conf/application.conf ファイルで、アプリケーションがサポートする言語を定義することです。


// conf/application.conf の設定例
play.i18n.langs = [ "en", "ja" ]

このように記述することで、英語(en)と日本語(ja)の二ヶ国語をサポートすることをPlay Frameworkに伝えます。この設定を忘れると、いくらメッセージファイルを用意しても正しく認識されないため、必ず最初に確認しましょう。

2. メッセージファイルの作成方法

2. メッセージファイルの作成方法
2. メッセージファイルの作成方法

次に、各言語に対応するテキストを定義する「メッセージファイル」を作成します。これらのファイルはプロジェクトの conf ディレクトリ内に配置します。ファイル名の規則は messages.言語コード となります。

例えば、デフォルトのメッセージファイルとして messages、日本語用として messages.ja、英語用として messages.en を作成します。

conf/messages.ja の内容:


home.title=ホーム画面へようこそ
home.welcome=こんにちは、{0}さん!
login.button=ログイン

conf/messages.en の内容:


home.title=Welcome to Home
home.welcome=Hello, {0}!
login.button=Login

ここで {0} という記述がありますが、これは「プレースホルダ」と呼ばれるものです。ビューから値を渡すことで、動的に名前などを埋め込むことができます。キー(home.titleなど)は共通にして、右側の値だけを各言語で翻訳するのがポイントです。

3. Twirlテンプレートでメッセージを表示する

3. Twirlテンプレートでメッセージを表示する
3. Twirlテンプレートでメッセージを表示する

メッセージファイルの準備ができたら、いよいよTwirlテンプレート(ビュー)でこれらを表示させます。Play Frameworkのビューで多言語メッセージを取得するには、暗黙の引数として MessagesProvider(または Messages オブジェクト)が必要です。

通常、コントローラから MessagesApi を介して渡される情報を利用しますが、Twirl内では非常に簡潔に記述できます。


@* views/index.scala.html *@
@(user: String)(implicit messages: Messages)

<!DOCTYPE html>
<html>
    <head>
        <title>@messages("home.title")</title>
    </head>
    <body>
        <h1>@messages("home.title")</h1>
        <p>@messages("home.welcome", user)</p>
        <button class="btn btn-primary">@messages("login.button")</button>
    </body>
</html>

@messages("キー名") と書くだけで、現在のユーザーの言語設定に合わせたテキストが自動的に選択されます。引数がある場合は、@messages("home.welcome", user) のように、キーの後に続けて渡すだけです。

4. コントローラからビューへのMessagesの渡し方

4. コントローラからビューへのMessagesの渡し方
4. コントローラからビューへのMessagesの渡し方

ビューで implicit messages: Messages を受け取るためには、コントローラ側で適切に処理を行う必要があります。Java版のPlay Frameworkでは、MessagesApi をインジェクションして使用するのが一般的です。

以下のコードは、現在のリクエストから適切な言語を判断し、ビューに渡すためのコントローラの例です。


package controllers;

import play.mvc.*;
import play.i18n.MessagesApi;
import play.i18n.HttpMessagesApi;
import javax.inject.Inject;

public class HomeController extends Controller {

    private final HttpMessagesApi httpMessagesApi;

    @Inject
    public HomeController(HttpMessagesApi httpMessagesApi) {
        this.httpMessagesApi = httpMessagesApi;
    }

    public Result index(Http.Request request) {
        // リクエストに基づいたMessagesオブジェクトを取得
        var messages = this.httpMessagesApi.preferred(request);
        String userName = "太郎";
        
        // renderメソッドで引数として渡す
        return ok(views.html.index.render(userName, messages));
    }
}

このコントローラでは、HttpMessagesApi を使ってユーザーの優先言語(ブラウザの Accept-Language ヘッダーなど)に基づいた Messages インスタンスを生成しています。これを render メソッドの引数に含めることで、ビュー側で多言語テキストが表示可能になります。

5. デフォルト言語とフォールバックの仕組み

5. デフォルト言語とフォールバックの仕組み
5. デフォルト言語とフォールバックの仕組み

もし、ユーザーが要求した言語に対応するメッセージファイル(例:フランス語 messages.fr)が存在しない場合はどうなるでしょうか?

Play Frameworkには「フォールバック」という仕組みがあります。

  • まず、言語コードと国コードが一致するファイルを探します(例:ja_JP)。
  • 次に見つからない場合は、言語コードのみのファイルを探します(例:ja)。
  • それも見つからない場合は、最も汎用的な messages ファイル(拡張子なし)の中身を表示します。

このため、共通して使うテキストや、翻訳が間に合っていない言語のための予備として、必ず conf/messages ファイルを作成し、そこにデフォルトの言語(多くの場合は英語など)を記述しておくことが推奨されます。

6. メッセージ内での特殊文字とHTMLエスケープ

6. メッセージ内での特殊文字とHTMLエスケープ
6. メッセージ内での特殊文字とHTMLエスケープ

メッセージファイルの中でHTMLタグを使いたい場合や、シングルクォートなどの特殊文字を扱いたい場合には注意が必要です。通常、Twirlテンプレートで @messages("...") と記述すると、出力される内容は自動的にHTMLエスケープされます。

もしメッセージファイル内にHTMLを含めてそのまま反映させたい場合は、ビュー側で Html クラスを利用します。


@* HTMLとして出力したい場合 *@
<p>@Html(messages("home.announcement"))</p>

ただし、メッセージファイルに直接HTMLを書くことは、保守性の観点からあまり推奨されません。できるだけテキストのみを定義し、デザインに関するHTMLタグはTwirlテンプレート側に記述するようにしましょう。

また、メッセージファイル内でシングルクォート(')を使いたい場合は、二重にする('')必要があることも覚えておくとトラブルを防げます。

7. 言語の動的切り替え(プログラマチックな変更)

7. 言語の動的切り替え(プログラマチックな変更)
7. 言語の動的切り替え(プログラマチックな変更)

ブラウザの設定に任せるだけでなく、サイト上のボタン(「English」「日本語」など)をクリックして言語を切り替えたい場合もあります。Play Frameworkでは、クッキーを使用してユーザーの言語設定を固定することが可能です。

コントローラで withLang メソッドを使用することで、レスポンスに言語設定を保存するクッキーを含めることができます。


public Result changeLanguage(String langCode, Http.Request request) {
    // 新しい言語設定でリダイレクトし、クッキーをセットする
    return redirect(routes.HomeController.index())
            .withLang(play.i18n.Lang.forCode(langCode), messagesApi);
}

このように実装することで、ユーザーが一度言語を選択すれば、次回以降のアクセスでもその言語が優先的に表示されるようになり、利便性が大幅に向上します。

8. 複雑なメッセージ構造とパラメータの活用

8. 複雑なメッセージ構造とパラメータの活用
8. 複雑なメッセージ構造とパラメータの活用

実際の開発では、単純な文字列の置き換えだけでなく、数値や日付のフォーマットも多言語化したい場面が出てきます。メッセージファイルでは、Javaの MessageFormat クラスの構文を利用できるため、高度な記述が可能です。

例えば、項目の個数によってメッセージを出し分けるような「複数形(Plurals)」の制御も工夫次第で実現できます。また、パラメータを複数渡す場合は {0}, {1}, {2} と増やしていくだけです。


# conf/messages.ja
cart.summary={0}個の商品がカートに入っています。合計金額は {1} 円です。

これをビューで呼び出す際は以下のようになります。


<div class="alert alert-info">
    @messages("cart.summary", itemCount, totalPrice)
</div>

このように、Twirlテンプレートとメッセージファイルを組み合わせることで、ロジック(Javaコード)、構造(HTML/Twirl)、表示テキスト(Messages)を綺麗に分離することができ、メンテナンス性の高いWebアプリケーションを構築できます。

カテゴリの一覧へ
新着記事
New1
Jakarta EE
Jakarta EEとクラウドネイティブ開発の相性とは?初心者向けにわかりやすく解説
New2
Jakarta EE
JakartaEE JSPのリクエスト属性とスコープの基本を徹底解説!初心者向け入門ガイド
New3
Play Framework
Play Frameworkのビューテストを徹底解説!Twirlテンプレートの品質を高める方法
New4
Jakarta EE
JakartaEE フィルタで認証と認可を実装する方法を初心者向けに解説!サーブレットのセキュリティ入門
人気記事
No.1
Java&Spring記事人気No1
Jakarta EE
Jakarta EEとSpringの比較|どちらを選ぶべきか?初心者向けに徹底解説!
No.2
Java&Spring記事人気No2
Play Framework
Play Frameworkのビューを共通化!テンプレート間のインクルード方法を徹底解説
No.3
Java&Spring記事人気No3
Play Framework
Play Frameworkプロジェクト作成直後にやるべき初期設定ガイド!初心者でも安心
No.4
Java&Spring記事人気No4
Play Framework
Play Frameworkで多言語対応(i18n)を徹底解説!Twirlテンプレートでの使い方
No.5
Java&Spring記事人気No5
Jakarta EE
Jakarta サーブレットのHttpServletRequestを徹底解説!初心者でもわかる基本操作と使い方
No.6
Java&Spring記事人気No6
Play Framework
Play FrameworkでCSSやJavaScriptを読み込む方法を徹底解説!静的リソースの組み込みガイド
No.7
Java&Spring記事人気No7
Jakarta EE
Jakarta EEの標準仕様とAPI一覧を完全解説!初心者でもわかるエンタープライズJavaの基本
No.8
Java&Spring記事人気No8
Jakarta EE
Jakarta EEとJava EEアプリの互換性を完全解説!移行で困らないための基礎知識