Edited at

Laravelで言語切替実装した時のメモ(多言語化)

More than 1 year has passed since last update.

基本はこのページに書いてある事だけで出来ました。簡単!

https://mydnic.be/post/laravel-5-and-his-fcking-non-persistent-app-setlocale


切替言語のconfig作成

言語の略称と表示名の配列。今回は日本語/英語/タイ語に対応。


config/languages.php


   /**
   * 言語切替
   */

return [
'en' => 'English',
'ja' => '日本語',
'th' => 'ภาษาไทย',
];


言語設定のmiddleware作成

コマンドを実行

$ php artisan make:middleware Language

middlewareファイルを実装


app/Http/Middleware/Language.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Session;

class Language
{
public function handle($request, Closure $next)
{
if (Session::has('applocale') AND array_key_exists(Session::get('applocale'), Config::get('languages'))) {
App::setLocale(Session::get('applocale'));
}
else {
App::setLocale(Config::get('app.fallback_locale'));
}
return $next($request);
}
}


カーネルに追加する。

以下の書き方でroute/web.phpの処理の際に自動適用される。(毎回必ず実行されるため、処理の負荷などを考慮する場合は他の方法を考えた方が良い)


app/Http/Kernel.php

    protected $middlewareGroups = [

'web' => [
                        //(省略)

\App\Http\Middleware\Language::class,

                        //(省略)
],



言語切替のcontroller作成

コマンドを実行

$ php artisan make:controller LanguageController

切替時に呼び出される処理の作成


app/Http/Controllers/LanguageController.php


namespace App\Http\Controllers;

use Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;

class LanguageController extends Controller
{
/**
* 言語切り替え処理
*/

public function switchLang($lang)
{
if (array_key_exists($lang, Config::get('languages'))) {
Session::put('applocale', $lang);
}
return Redirect::back();
}
}



controllerの呼び出しを定義

引数に言語の略称を持ったGETを受けた際に、言語切替処理を呼ぶ。


routes/web.php


/**
* 言語切替
*/

Route::get('lang/{lang}', ['as'=>'lang.switch', 'uses'=>'LanguageController@switchLang']);


view側に呼び出し元を作る

以下は、最初のURL先の内容を元に作った例です。今の言語設定がdropdownの初期表示になり、残りの言語を選べる。


views/layouts/nav.blade.php

<!-- 言語切り替え -->

<li class="dropdown" id="nav-lang">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{ Config::get('languages')[App::getLocale()] }}
<span class="caret"></span></a>
<ul class="dropdown-menu">
@foreach (Config::get('languages') as $lang => $language)
@if ($lang != App::getLocale())
<li>
<a href="{{ route('lang.switch', $lang) }}">{{$language}}</a>
</li>
@endif
@endforeach
</ul>
</li>


実際の言語ファイルを作る

resources/lang以下に「en」,「ja」,「th」を作る。

英語


resources/lang/en/messages.php

<?php

return [

/*
|-----------------------------------------------------------------
| resources/views/nav.blade.php
|-----------------------------------------------------------------
*/

'nav_welcome' => 'Welcome, :name',
'nav_lang' => 'Language:',
'nav_time' => 'Timezone:',
];


日本語


resources/lang/ja/messages.php

<?php

return [

/*
|-----------------------------------------------------------------
| resources/views/nav.blade.php
|-----------------------------------------------------------------
*/

'nav_welcome' => 'ようこそ:nameさん',
'nav_lang' => '言語:',
'nav_time' => 'タイムゾーン:',
];


タイ語


resources/lang/th/messages.php

<?php

return [

/*
|-----------------------------------------------------------------
| resources/views/nav.blade.php
|-----------------------------------------------------------------
*/

'nav_welcome' => 'ยินดีต้อนรับ, :name',
'nav_lang' => 'ภาษา:',
'nav_time' => 'เขตเวลา:',
];



実際のhtmlでの使い方


views/layouts/nav.blade.php

<!--タイムゾーン -->

<p>{{ __('messages.nav_time') }}</p>

<!--ようこそ+(ユーザー名) -->
<p>{{ __('messages.nav_welcome', ['name' => Auth::user()->name]) }}</p>



感想

とてもスムーズに実装できた。middleware便利。

ただ、viewの可読性が著しく下がった。