イメージ図
本記事では、上記の図のように言語の切り替えを選択すると表示画面が日本語→英語、英語→日本語に切り替えが出来る機能を実装する方法を紹介します。
検証済み Laravelバージョン
Laravel 7系/8系
全体的なフロー
先ずは実装方法の全体象を見ていきましょう。
app/Http/Middleware/SetLocal.phpでURLの値を確認して、Localを切り替えメソッドを作成。
app/Http/Kernel.phpで作成したmiddlewareを使用出来るように設定
routes/web.phpでルートの設定
app/helper.phpで言語切り替えリンクに設置するヘルパー関数を作成
resources\views\demo.blade.phpでフロントに表示させる為のコードを書きます。(デモ用なのでcontrollerファイルは省略します)
resources\lang\en\lang.phpと resources\lang\ja\lang.phpファイルに英語の場合の表示と日本語の場合の表示を記述します。
ざっくりと全体の流れはこんな感じです。 それでは1つ1つ手順追って解説していきます。
middlewareを作成
コマンドを実行
$ php aritsan make:middleware SetLocale
ファイルが作成されるので、そこにメソッドを記述します。
app/Http/Middleware/SetLocale.php
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Route; class SetLocale { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse */ public function handle(Request $request, Closure $next) { // Prefix を判断して言語切替 $route = Route::getCurrentRoute(); $lang = $route->parameter('lang', 'ja'); App::setLocale($lang); return $next($request); } }
解説
route からControllerの間の処理でリクエストをチェックする機能として使用しています。
Route::getCurrentRoute()でルート名を取得して$routeに格納しています。 格納された$routeからパラメータの$langの値を取得します。 第二引数に設定されているのは、もしlangがnullの場合の初期値となります。
AppファサードのsetLocaleメソッド(App::setLocale部分)を使って、実行時にアクティブな言語に切り替えを行うことができます。
Middelewareをrouteで使用が出来るようにKernel.phpに追記します。
app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\SetLocale::class,
],
解説
routeに対して、middlewareを割り当てたいので、middlewareGroupsの中にwebがキーの連想配列に先ほど作成したSetLocal::classを追加します。
Routeを設定
web.phpにrouteの設定を変更します。
routes/web.php
//ユーザー側 Route::prefix('{lang}')->where(['lang' => 'ja|en'])->group(function() { Route::get('demo/{param?}', function(){ return view ('demo'); }); });
解説
prefixメソッドはグループ内の各ルートに対して、指定されたURIのプレフィックスを指定するために使用します。
whereメソッドを使用して、ルートパラメータのフォーマットを制約できます。 langにjaかenしか入らないようにしています。
その他がもし入力された場合は404となります。
※404エラーは、サーバー側から「このURLは存在しない」というエラーの応答を意味します。
もしja若しくはenが無い状態でURLがアクセスされた場合、jaの値が自動で入るように設定しておきます。
routes/web.php
// 404 Not Found Route::fallback(function(Request $request){ $route = Route::getCurrentRoute(); // WEB側画面 if( empty($route->getPrefix()) ){ $fallback = $route->parameter('fallbackPlaceholder'); // 言語用Prefixが存在しない場合、言語を設定してリダイレクトする if( $fallback === null || (strpos($fallback, 'ja') === false && strpos($fallback, 'en') === false) ){ $path = $request->getPathInfo(); return redirect('/ja'.$path); } } return abort(404); });
解説
Routeクラスを使用しているので上部にはuse Illuminate\Http\Request;を追加してください。
2行目の$route = Route::getCurrentRoute()でRouteで設定しているパラメータを配列で取得しています。
その後の処理で言語用のPrefixが存在しない場合は、prefixの部分にjaが入るようにしています。
表示側の切替機能のリンクを作成します。 どのページでもはめれるようにヘルパー関数を作成しておきます。
ヘルパー関数を作成
app/helper.phpを作成
if( ! function_exists('locale_change_url') ){ function locale_change_url() { $lang = request()->route()->parameter('lang'); if( $lang == 'ja' ){ $url = str_replace('/ja/', '/en/', url()->full()); }else { $url = str_replace('/en/', '/ja/', url()->full()); } return $url; } }
解説
1行目の !function_exists('local_change_url')で既に同じ名前の関数が存在しないか、重複を避ける為の記述です。
4行目のrequest()->route()->parameter('lang');で後ほどrouteで設定するlangパラメータを取得して変数$langに格納
5行目のif( $lang == 'ja' ){でjaであった場合には、$url = str_replace('/ja/', '/en/', url()->full()); urlパスをjaからenに変えてurlに格納しておきます!
表示言語の設定
resourcesのlangディレクトリの中を取得します。 localteで設定されている方のファイルを参照します。
英語と日本語の言語ファイルを下記のように記述します。
resources\lang\en\lang.php
<?php return [ 'hello' => 'Hello world', 'site_name' => 'enginiya.com', 'favorite_food' => 'seaweed of the family Spermatochnaceae' ];
resoureces\lang\ja\lang.php
<?php return [ 'hello' => 'こんにちわ', 'site_name' => 'エンジニヤドットコム', 'favorite_food' => 'もずく', ];
フロント側の作成
bladeのファイルに実際に下記のように記述します。
resources\views\demo.blade.php
<a href="{{ locale_change_url() }}">言語切替</a> <br><br> {{ __('lang.hello') }}<br> {{ __('lang.site_name') }}<br> {{ __('lang.favorite_food') }}<br>
以上で最初に紹介したイメージ図通りの機能が完成です。 実際に使用する際はCSSを適用させたり、コントローラを通して他の処理を加えるなどしてください。
お疲れ様でした~~