在建立多語系的系統時,常見透過 subdomain 與 first segment 方式來做為多國區分
例如: subdomain: tw.adon988.com, first segment: www.adon988.com/tw/
在 laravel 的 router 如果要建立 first segment 方式的 router ,官方的範例如下:
<?php
Route::get('welcome/{locale}', function ($locale) {
if (! in_array($locale, ['en', 'es', 'fr'])) {
abort(400);
}
App::setLocale($locale);
//
});
按照這方式定義 router 後,則結構會是以下樣式:
<?php
Route::get('/{locale}/contact', xxxxx);
Route::get('/{locale}/about', xxxxx);
Route::get('/{locale}/user', xxxxx);
如何透過 router group 與 Middleware 將多語系包再一起
我們希望將 {locale} 獨立以 group 方式一次定義,在 group 裡可以分別定義出 router,以下說明作法:
首先,建立 Locale 的 Middleware
php artisan make:middleware Locale
調整 Middleware 判斷 local,在這裡我們判斷第一個 segment 預設定義多語系
locale 是預設的語系
locales 是我們支援的語系
(在這裡已經先把設定寫在 config.app )
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use App;
class Locale
{
/**
* Handle localization
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
$segment = $request->segment(1)??config('app.locale');
if(!in_array($segment, config('app.locales'))){
App::abort(404);
}
app()->setLocale($segment);
return $next($request);
}
}
接著,基礎的動作,把 Middleware 註冊在 app/Http/Kernel.php
protected $routeMiddleware = [
...
'locale' => \App\Http\Middleware\Locale::class,
];
在 router 就可以將預設 prefix locale 透過 middleware 來判斷語系參數,並且 group 來管理。
Router web.php 格式如下
<?php
Route::prefix('{locale?}')->middleware('locale')->group(function() {
Route::get('/', [ArticlesController::class, 'index'])->name('home_lang');
});
接著,說明設定 config ,在 config/app.php 設定 locale 參數,
這裏,把參數透過 env 來管理
<?php return [
..
'locale' => env('LOCALE', 'tw'),
'locales' => explode(',', env('LOCALES', 'tw, cn, en')),
...
完成後,在 .env 加上參數即可
# localization
LOCALE='tw'
LOCALES='tw,cn,en'