Laravel5で多言語対応サイトの実装をする機会があるかもしれません。
今回の記事では、Laravel5で多言語サイトの実装をする方法について紹介します。
Laravel5の環境構築については、下記のページを参照ください。
今回の記事は、下記の記事を作成時点のアプリケーションに作成しているので、Laravel5の知識がない方は、こちらも合わせて読んだ方がわかりやすいかもしれません。
環境
- CentOS 7.4
- PHP 7.2.7
- MySQL 5.7.22
- Apache 2.4.6
- Laravel 5.5/5.6
Laravel5のローカライゼーション機能
Laravel5のローカライゼーション機能は、様々な言語を扱える様に、言語の文字列はresources/langディレクトリ下のファイルに保存します。このディレクトリの中にアプリケーションでサポートする言語のディレクトリを設置します。
[root@localhost resources]# tree . ├── lang │ ├── en │ │ ├── auth.php │ │ ├── messages.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php │ └── ja │ └── messages.php
今回は、enディレクトリ配下とjaディレクトリ配下にmessages.phpファイルを作成し、中身を下記の様に作成しました。
en/messages.php
<?php return [ 'welcome' => 'Welcome to our application', 'site' => 'This is multi language site.' ];
ja/messages.php
<?php return [ 'welcome' => 'ようこそ!私たちのあぷりけーしょんへ', 'site' => 'このサイトはマルチ言語対応のサイトです' ];
言語のファイルは、シンプルに配列の値をリターンしています。
ロケールの設定
AppファサードのsetLocaleメソッドを使用し、実行時にアクティブな言語を設定することができます。
今回は、/routes/web.phpの一つの行を下記の様に書き換えます。このルーティングは、ログイン後の画面のルーティングなのですが、ここは、環境に応じて、マルチサイト化したいページにより便宜変更してください。このサイトで、ログインのページを作成した方は、同じ環境です。
Route::get('/home/{locale?}', 'HomeController@index')->name('home');
次にコントローラを書き換えます。私の環境では、HomeController@indexのページで多言語サイトを試したいので、
HomeController.phpのindexメソッドに”App::setLocale($locale);”を追加します。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; //use Appを追加 use App; class HomeController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth'); } /** * Show the application dashboard. * * @return \Illuminate\Http\Response */ //Request $requestを下の行に追加 public function index(Request $request) { //下の行を追加 App::setLocale($request->locale); return view('home'); }
また、Laravel5では、デフォルトの言語は、config/app.phpで設定することが出来ます。
それに、現時点のロケールとして指定した言語の翻訳文字列が存在しない場合に使用される、「フォールバック言語」を設定することもできます。デフォルト言語と同様に、フォールバック言語もconfig/app.php設定ファイルで指定されます。
'fallback_locale' => 'en',
現在のローケールの判定
Laravel5では、現在のロケールを取得したり、判別したりするのに、AppファサードのgetLocaleやisLocaleを使います。
//現在のロケールの取得 $locale = App::getLocale(); //ロケールがenかどうか if (App::isLocale('en')) { // }
翻訳文字列のキーの保存
Laravel5では、たくさんの翻訳が必要なアプリケーションでは、全ての文字列に「短いキー」を付けようとすると、ビューで参照する際、すぐにこんがらがってきます。そのため、Laravelでは翻訳文字列を「デフォルト」翻訳の文字列をキーとして利用できます。
翻訳文字列をキーとして使用する翻訳ファイルは、resources/langディレクトリ下にJSONファイルとして保存します。たとえば、アプリケーションにスペイン語の翻訳がある場合、resources/lang/ja.jsonファイルを作成します。
{ "I dont love programming at all.": "ぼくはまったくプログラミングが好きじゃないよ." }
翻訳文字列の取得
言語ファイルから行を取得するには、__ヘルパ関数を使用します。__メソッドは、最初の引数として翻訳文字列のファイル名とキーを指定します。例として、resources/lang/messages.php原語ファイルからwelcome翻訳文字列を取得してみましょう。
echo __('messages.welcome'); echo __('I love programming.');
もちろん、Bladeテンプレートエンジンを使用している場合は、{{ }}記法で翻訳文字列をechoするか、@langディレクティブを使用します。
{{ __('messages.welcome') }}<br /> @lang('messages.site')<br />
上記の内容をビューのテンプレートに書きます。私の環境では、私の環境では、HomeController.phpのindexメソッドで指定しているビューの/resources/views/home.blade.phpです。
・http://192.168.33.1x/home
・http://192.168.33.1x/home/en
・http://192.168.33.1x/ja
にアクセスしてみます。下記の様に日本語と英語に翻訳されたページが表示されていることが確認出来ます。
・英語サイト
・日本語サイト
翻訳中のパラメータの置換
翻訳文字列にプレースホルダを定義できます。全てのプレースホルダは:のプレフィックスが月カス。例として、welcomeメッセージにnameプレースホルダの定義を示します。
'welcome' => 'Welcome, :name',
翻訳文字列を取得する時に、プレースホルダを置き換えるには、__関数の第2引数として、置換文字の配列を渡します。
プレースホルダを全部大文字にするか、最初の一文字を大文字にすると、その方法に合わせて値が大文字に変換されます。
'welcome' => 'Welcome, :NAME', // Welcome, DAYLE 'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle
複数形
複数形化は、異なった言語において多種複雑な複数形化のルールが存在しています。Laravel5では、「パイプ」記号の縦線を使うことで、単数形の文字列と複数形の文字列を分けて処理をします。
'apples' => 'There is one apple|There are many apples',
複数の範囲を翻訳行に指定することで、もっと便利な複数形化のルールも作成できます。
'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',
複数形化オプションの翻訳文字列を定義したら、trans_choice関数に「数」を指定し、行を取得します。以下の例では数が1より大きので、複数形の翻訳行が返されます。
echo trans_choice('messages.apples', 10);
パッケージの言語ファイルのオーバーライド
いくつかのパッケージではそれ自身の言語ファイルが提供されています。出力される文言を調整するためパッケージのコアをハックする代わりに、resources/lang/vendor/{パッケージ}/{ロケールコード}ディレクトリに言語ファイルを設置することで、オーバーライドできます。
たとえばskyrim/hearthfireという名前のパッケージが持っているmessages.phpの英語の翻訳行をオーバーライドする必要があるなら、resources/lang/vendor/hearthfire/en/messages.phpに言語ファイルを設置します。このファイルには置き換えたい翻訳行の定義だけを設置することができます。オーバーライドしなかった翻訳行は、パッケージのオリジナルな言語ファイル中の定義のままロードされます。
Laravel5で実際に簡単な多言語サイトを作成して動かしてみたのですが、比較的簡単に出来ました。
多言語サイトを作成するならLaravel5もいいかもしれません。