概要
エラーが出る原因は
- ルーティングされるメソッドに
$lang
が定義されていない
からではなく
- ルーティングリンク生成時に
{lang}
が含まれるほうを利用している
- にも関わらず、
["lang" => $lang]
をパラメータに渡していない
が原因かと思われます。
実装方針
ミドルウェアの作成
php
1class LocaleMiddleware
2{
3 protected $possibleLocales = ['ja', 'en', 'cn', 'ru'];
4
5 public function handle(Request $request, Closure $next)
6 {
7 $route = $request->route();
8 $lang = $route->parameter('lang');
9
10 if ($lang !== null) {
11
12 // デフォルトロケールまたは存在しないロケールならフォールバック
13 if (
14 $lang === config('app.fallback_locale')
15 || !in_array($lang, $this->possibleLocales, true)
16 ) {
17 return redirect()->route(substr($route->getName(), 5));
18 }
19
20 // ロケールの設定
21 App::setLocale($lang);
22 }
23
24 return $next($request);
25 }
26}
ルーティング定義
ルーティング定義は以下のようになります。
php
1// デフォルト言語
2Route::namespace('App\Http\Controllers')
3 ->group(base_path('routes/localized.php'));
4
5// 各言語
6Route::namespace('App\Http\Controllers')
7 ->middleware(LocaleMiddleware::class)
8 ->prefix('{lang}')
9 ->as('lang.')
10 ->group(base_path('routes/localized.php'));
アプリケーションの実際の定義は routes/localized.php
に書いてください。
ヘルパー関数の作成
以下のようなヘルパー関数を適当な場所に定義してください。
php
1function route_i18n(string $name, array $params): string
2{
3 $params['lang'] += App::getLocale();
4
5 return route(
6 $params['lang'] === config('app.fallback_locale') ? $name : "lang.$name",
7 $params
8 );
9}
app/helpers.php
を作って composer.json の autoload
の files
に書くのがおすすめです。
{
"autoload": {
"files": ["app/helpers.php"]
}
}
これで route_i18n
を使って定義するのはどうでしょうか?現在表示しているページの言語にあったルーティングを暗黙的に書けます。言語を切り替えるときもそれを $params
に渡せば、引数のほうが優先されるので問題ありません。
中身の多言語化に関しては通常どおり __
関数を使うだけですね。とても簡単です。