ローカライゼーション
イントロダクション
デフォルトでは、Laravelアプリケーションスケルトンにはlangディレクトリは含まれていません。Laravelの言語ファイルをカスタマイズしたい場合は、lang:publish Artisanコマンドを介して公開できます。
Laravelのローカライゼーション機能は、さまざまな言語の文字列を取得する便利な方法を提供し、アプリケーション内で複数言語を簡単にサポートできるようにします。
Laravelは、翻訳文字列を管理する2つの方法を提供しています。まず、言語文字列はアプリケーションのlangディレクトリ内のファイルに保存します。このディレクトリ内には、アプリケーションでサポートする各言語のサブディレクトリが存在する場合があります。これは、Laravelがバリデーションエラーメッセージなどの組み込み機能の翻訳文字列を管理するために使用するアプローチです。
1/lang2 /en3 messages.php4 /es5 messages.php
または、翻訳文字列はlangディレクトリ内に配置されるJSONファイル内で定義します。このアプローチを取る場合、アプリケーションでサポートする各言語は、このディレクトリ内に対応するJSONファイルを持つことになります。このアプローチは、翻訳可能な文字列が多数あるアプリケーションに推奨します。
1/lang2 en.json3 es.json
このドキュメントでは、翻訳文字列を管理する各アプローチについて説明します。
言語ファイルの公開
デフォルトでは、Laravelアプリケーションのスケルトンにlangディレクトリは含まれていません。Laravelの言語ファイルをカスタマイズしたり、独自の言語ファイルを作成したりする場合は、lang:publish Artisanコマンドでlangディレクトリを生成する必要があります。lang:publishコマンドは、アプリケーションにlangディレクトリを作成し、Laravelが使用するデフォルトの言語ファイル群を公開します。
1php artisan lang:publish
ロケールの設定
アプリケーションのデフォルト言語は、config/app.php設定ファイルのlocale設定オプションに保存されており、通常はAPP_LOCALE環境変数を使用して設定します。この値は、アプリケーションのニーズに合わせて自由に変更できます。
デフォルトの言語に特定の翻訳文字列が含まれていない場合に使用される「フォールバック言語」を設定することもできます。デフォルト言語と同様に、フォールバック言語もconfig/app.php設定ファイルで設定し、その値は通常APP_FALLBACK_LOCALE環境変数を使用して設定します。
Appファサードが提供するsetLocaleメソッドを使用して、単一のHTTPリクエストのデフォルト言語をランタイム時に変更できます。
1use Illuminate\Support\Facades\App; 2 3Route::get('/greeting/{locale}', function (string $locale) { 4 if (! in_array($locale, ['en', 'es', 'fr'])) { 5 abort(400); 6 } 7 8 App::setLocale($locale); 9 10 // ...11});
現在のロケールの判別
AppファサードのcurrentLocaleメソッドとisLocaleメソッドを使用して、現在のロケールを判別したり、ロケールが特定の値であるかを確認したりできます。
1use Illuminate\Support\Facades\App;2 3$locale = App::currentLocale();4 5if (App::isLocale('en')) {6 // ...7}
複数形化の言語
Eloquentやフレームワークの他の部分で、単数形の文字列を複数形の文字列に変換するために使用されるLaravelの「複数形変換機能(pluralizer)」に、英語以外の言語を使用するように指示できます。これを行うには、アプリケーションのサービスプロバイダの1つで、bootメソッド内でuseLanguageメソッドを呼び出します。複数形変換機能が現在サポートしている言語は、french、norwegian-bokmal、portuguese、spanish、turkishです。
1use Illuminate\Support\Pluralizer; 2 3/** 4 * Bootstrap any application services. 5 */ 6public function boot(): void 7{ 8 Pluralizer::useLanguage('spanish'); 9 10 // ...11}
複数形変換機能の言語をカスタマイズする場合は、Eloquentモデルのテーブル名を明示的に定義する必要があります。
翻訳文字列の定義
短縮キーの使用
通常、翻訳文字列はlangディレクトリ内のファイルに保存します。このディレクトリ内には、アプリケーションでサポートされる各言語のサブディレクトリを配置する必要があります。これは、Laravelがバリデーションエラーメッセージなどの組み込みLaravel機能の翻訳文字列を管理するために使用するアプローチです。
1/lang2 /en3 messages.php4 /es5 messages.php
すべての言語ファイルは、キー付けされた文字列の配列を返します。例:
1<?php2 3// lang/en/messages.php4 5return [6 'welcome' => 'Welcome to our application!',7];
地域によって言語が異なる場合は、ISO 15897に従って言語ディレクトリに名前を付ける必要があります。たとえば、イギリス英語には「en-gb」ではなく「en_GB」を使用する必要があります。
翻訳文字列をキーとして使用
翻訳可能な文字列が多数あるアプリケーションでは、「短縮キー」ですべての文字列を定義すると、ビューでキーを参照するときに混乱する可能性があり、アプリケーションでサポートされているすべての翻訳文字列のキーを常に考え出すのは面倒です。
このため、Laravelでは文字列の「デフォルト」の翻訳をキーとして使用して翻訳文字列を定義する機能もサポートしています。翻訳文字列をキーとして使用する言語ファイルは、langディレクトリにJSONファイルとして保存します。たとえば、アプリケーションにスペイン語の翻訳がある場合は、lang/es.jsonファイルを作成する必要があります。
1{2 "I love programming.": "Me encanta programar."3}
キーとファイルの競合
他の翻訳ファイル名と競合する翻訳文字列キーを定義してはいけません。たとえば、「NL」ロケールで__('Action')を翻訳する際に、nl.jsonファイルが存在せず、nl/action.phpファイルが存在する場合、トランスレータはnl/action.phpの全内容を返してしまいます。
翻訳文字列の取得
言語ファイルから翻訳文字列を取得するには、__ヘルパ関数を使用します。「短縮キー」を使用して翻訳文字列を定義している場合は、「ドット」記法を使用して、キーを含むファイルとそのキー自体を__関数に渡す必要があります。たとえば、lang/en/messages.php言語ファイルからwelcome翻訳文字列を取得してみましょう。
1echo __('messages.welcome');
指定した翻訳文字列が存在しない場合、__関数は翻訳文字列のキーを返します。したがって、上記の例を使用すると、翻訳文字列が存在しない場合、__関数はmessages.welcomeを返します。
デフォルトの翻訳文字列を翻訳キーとして使用している場合は、文字列のデフォルトの翻訳を__関数に渡す必要があります。
1echo __('I love programming.');
繰り返しになりますが、翻訳文字列が存在しない場合、__関数は渡された翻訳文字列キーをそのまま返します。
Bladeテンプレートエンジンを使用している場合は、{{ }}エコー構文を使用して翻訳文字列を表示できます。
1{{ __('messages.welcome') }}
翻訳文字列のパラメータ置換
必要に応じて、翻訳文字列にプレースホルダを定義できます。すべてのプレースホルダには:のプレフィックスを付けます。たとえば、プレースホルダ名を含むウェルカムメッセージを定義できます。
1'welcome' => 'Welcome, :name',
翻訳文字列を取得する際にプレースホルダを置き換えるには、__関数の第2引数として置換の配列を渡します。
1echo __('messages.welcome', ['name' => 'dayle']);
プレースホルダがすべて大文字であるか、最初の文字だけが大文字である場合、翻訳された値もそれに応じて大文字になります。
1'welcome' => 'Welcome, :NAME', // Welcome, DAYLE2'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle
オブジェクト置換のフォーマット
翻訳プレースホルダとしてオブジェクトを提供しようとすると、そのオブジェクトの__toStringメソッドが呼び出されます。__toStringメソッドは、PHPの組み込み「マジックメソッド」の1つです。しかし、操作しているクラスがサードパーティのライブラリに属している場合など、特定のクラスの__toStringメソッドを制御できない場合があります。
このような場合、Laravelではその特定のオブジェクトタイプに対してカスタムフォーマットハンドラを登録できます。これを実現するには、トランスレータのstringableメソッドを呼び出します。stringableメソッドはクロージャを受け入れ、そのクロージャはフォーマットを担当するオブジェクトのタイプをタイプヒントで指定する必要があります。通常、stringableメソッドは、アプリケーションのAppServiceProviderクラスのbootメソッド内で呼び出す必要があります。
1use Illuminate\Support\Facades\Lang; 2use Money\Money; 3 4/** 5 * Bootstrap any application services. 6 */ 7public function boot(): void 8{ 9 Lang::stringable(function (Money $money) {10 return $money->formatTo('en_GB');11 });12}
複数形化
複数形化は複雑な問題です。言語によってさまざまな複雑な複数形化のルールがあるためです。しかし、Laravelは、定義した複数形化のルールに基づいて文字列をさまざまに翻訳するのに役立ちます。|文字を使用して、文字列の単数形と複数形を区別できます。
1'apples' => 'There is one apple|There are many apples',
もちろん、翻訳文字列をキーとして使用する場合でも、複数形化はサポートされています。
1{2 "There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas"3}
複数の値の範囲に対して翻訳文字列を指定する、より複雑な複数形化のルールを作成することもできます。
1'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',
複数形化のオプションを持つ翻訳文字列を定義した後、trans_choice関数を使用して、特定の「数」の行を取得できます。この例では、数が1より大きいため、翻訳文字列の複数形が返されます。
1echo trans_choice('messages.apples', 10);
複数形化文字列にプレースホルダ属性を定義することもできます。これらのプレースホルダは、trans_choice関数の第3引数として配列を渡すことで置き換えられます。
1'minutes_ago' => '{1} :value minute ago|[2,*] :value minutes ago',2 3echo trans_choice('time.minutes_ago', 5, ['value' => 5]);
trans_choice関数に渡された整数値を表示したい場合は、組み込みの:countプレースホルダを使用できます。
1'apples' => '{0} There are none|{1} There is one|[2,*] There are :count',
パッケージ言語ファイルの上書き
一部のパッケージには、独自の言語ファイルが付属している場合があります。これらの行を調整するためにパッケージのコアファイルを変更する代わりに、lang/vendor/{package}/{locale}ディレクトリにファイルを配置することで、それらを上書きできます。
たとえば、skyrim/hearthfireという名前のパッケージのmessages.phpにある英語の翻訳文字列を上書きする必要がある場合は、lang/vendor/hearthfire/en/messages.phpに言語ファイルを配置する必要があります。このファイル内では、上書きしたい翻訳文字列のみを定義します。上書きしない翻訳文字列は、引き続きパッケージの元の言語ファイルからロードされます。