🦓

[Laravel]国際化について

2023/11/19に公開

はじめに

Laravelの国際化についてまとめてみました。

Laravelローカライゼーション

tl;dr

  1. アプリの言語を設定する
  2. localeファイルを公開する
  3. localeファイルを作成する
  4. ビューから呼び出す
  5. ${locale}を使って動的にlocaleを変える
  6. middlewareを作成する
  7. 言語を切り替える

アプリのデフォルト言語を設定する

app.php内にある言語に関する設定を変えます。

web/app.php
    /*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */
    
    // デフォルトの言語
    'locale' => 'en',

    /*
    |--------------------------------------------------------------------------
    | Application Fallback Locale
    |--------------------------------------------------------------------------
    |
    | The fallback locale determines the locale to use when the current one
    | is not available. You may change the value to correspond to any of
    | the language folders that are provided through your application.
    |
    */
    
    // デフォルトの言語が見つからない時に代わりに使う言語
    'fallback_locale' => 'en',

    /*
    |--------------------------------------------------------------------------
    | Faker Locale
    |--------------------------------------------------------------------------
    |
    | This locale will be used by the Faker PHP library when generating fake
    | data for your database seeds. For example, this will be used to get
    | localized telephone numbers, street address information and more.
    |
    */

   // fakerの言語
    'faker_locale' => 'en_US',
routes/web.php
Route::get('/', function(){
   return redirect('/' . app()->getLocale());
});

ルート / にアクセスされたときに、アプリの現在のロケールにリダイレクトさせます。
app()->getLocale() は現在のロケールを取得するメソッドです。
このように変更すると、/ にアクセスされた場合に現在のロケールを含んだ URL にリダイレクトされるようになります。

localeファイルを公開する

php artisan lang:publish

   INFO  Language files published successfully.  

四つのファイルが作成されました。
lang:publishコマンドは、アプリケーションにlangディレクトリを作成し、Laravelで使用される言語ファイルのデフォルトセットを公開します。

localeファイルを作成する

lang/es,lang/jaのように言語ごとにlocaleディレクトリを作成する必要があります。

/lang
    /en
        messages.php
    /ja
        messages.php

キーと値のペアを作成します。

lang/en/pagination.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Pagination Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used by the paginator library to build
    | the simple pagination links. You are free to change them to anything
    | you want to customize your views to better match your application.
    |
    */

    'previous' => '&laquo; Previous',
    'next' => 'Next &raquo;',

];
lang/ja/pagination.php
<?php

return [

    /* メッセージの内容がご自身のアプリに適さない場合には、必要に応じて修正願います */

    'previous' => '&laquo; 前',
    'next' => '次 &raquo;',

];

ビューから呼び出します。

Bladeシンタック
<span>@lang('pagination.previous')</span>
PHPシンタックス
<span>{{ __('pagination.previous') }}</span>
<span>{{ trans('pagination.previous') }}</span>

// htmlタグをエスケープする
<span>{!! __('pagination.previous') !!}</span>

${locale}を使って動的にlocaleを変える

www.apple.com/jp/や``のように、URLに${locale}の値を埋め込んで動的に言語を表示させていきます。

routes/web.php
<?php

use Illuminate\Support\Facades\App;

Route::get('/{locale}', function (string $locale) {
    // サポートされている言語のみ受け入れる
    if (! in_array($locale, ['en', 'jp'])) {
        abort(400);
    }
    
    // アプリケーションのロケールを設定
    App::setLocale($locale);
    
    return view('welcome');
});

URL内の{locale}パラメータに基づいてアプリケーションのロケールを変更するようになります。

続いて、lang/ディレクトリに言語ごとのファイルを作成します。

lang/en/welcome.php
return [
    'welcome' => 'Welcome!',
];
lang/jp/greetings.php

return [
    'welcome' => 'ようこそ!',
];

resources/views/welcome.blade.phpでメッセージを表示します。

resources/views/welcome.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>

<h1>{{ $welcome }}</h1>

</body>
</html>

/jpへアクセスし、ようこそが表示されていることを確認します。

middlewareを作成する

言語切り替えのために {locale} をすべての URL に追加すると扱いづらいので Middleware を作成します。

ミドルウェアを使用してプリフィックス(接頭辞)を作成し、特定のルートグループやコントローラーに対してプリフィックスが適用されるようになります。

  1. ミドルウェアの作成:
php artisan make:middleware Localization

   INFO  Middleware [app/Http/Middleware/Localization.php] created successfully.  

Localization.phpという名前のミドルウェアが app/Http/Middleware ディレクトリに作成されます。

  1. ミドルウェアの編集:
app/Http/Middleware/Localization.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;

class Localization
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        app()->setLocale($request->segment(1));
        URL::default(['locale' => $request->segment(1)]);
        return $next($request);
    }
}

app()->setLocale($request->segment(1)); は、リクエストのURLの最初のセグメント({locale})を取得し、それをアプリケーションのロケールとして設定しています。

例えば、URLが /en/route の場合、$request->segment(1)en になります。そして、その言語コードを使用してアプリケーションのロケールを設定します。

URL::default(['locale' => $request->segment(1)]); は、URL::default を使用してデフォルトのURLパラメータを設定しています。これにより、アプリケーション内で生成されるURLのデフォルトの locale パラメータが、ユーザーの指定したロケールになります。

  1. ミドルウェアをルートに適用:

作成したミドルウェアを $middleware プロパティに追加します。

protected $middleware = [
    // ...
    'localization' => \app\Http\Middleware\Localization::class,
];
  1. ミドルウェアのプリフィックスを利用:

ミドルウェアが設定されたプリフィックスをルートやコントローラーで利用できます。

routes/web.php
Route::prefix('{locale}')
->middleware(Localization::class)
->group(function(){

    Route::view('/', 'welcome');
});

{locale} というプレースホルダを持つURLプレフィックスを使用して、アプリ内のルートへのアクセスにロケールを割り当てることができます。

例えば、URLが /en/route の場合、{locale} プレースホルダによって en が抽出され、Localization ミドルウェアによってその言語コードがアプリケーションのロケールに設定されます。

その後、Route::view('/', 'welcome'); によって、トップレベルのURL(/en/jaなど)へのアクセスが welcome ビューにマッピングされます。この welcome ビュー内で、指定された言語に基づいてコンテンツを表示できます。

Middlewareを使用するとクリーンなルートファイルを維持できます。特定のルートやコントローラーに対して locale を制御するための柔軟性が持ち、管理しやすくなります。

言語を切り替える

アプリに複数の言語がある場合言語を切り替えるリンクやボタンを追加することが多いです。

  1. セッションにユーザーのローケル設定を保存する
routes/web.php
Route::get('/{locale}', function($locale){
    app()->setLocale($locale);
    session()->put('localization', $locale);

    return redirect()->back();
})->name('localization');

/{locale} にアクセスされたときに、指定された locale に基づいてアプリケーションのロケールを設定し、セッションにそのロケールを保存してから、元のページにユーザーをリダイレクトします。

/{locale}: ユーザーがアクセスするURLの一部で、locale パラメーターを取り込みます。

app()->setLocale($locale): Laravelの app() ヘルパーを使用して、アプリケーションのロケールを指定された locale に設定します。

session()->put('localization', $locale): セッションに localization キーで指定された locale を保存します。ユーザーの設定が次回のリクエストでも保持されます。

return redirect()->back();: back() メソッドを使用して、ユーザーを前のページにリダイレクトします。ユーザーが言語を変更した後に元のページに戻ります。

->name('localization') は、このルートに名前を付けています。
route() ヘルパーを使用してこのルートに簡単にアクセスできるようになります。
例えば、route('localization', ['locale' => 'ja'])/ja にリダイレクトすることができます。

2. セッションの値を使用する

app/Http/Middleware/Localization.php
if(session()->has('localization')){
    app()->setLocale(session()->get('localization'));
} else {
    app()->setLocale(config('app.locale'));
}

# 一行で書くこともできる
app()->setLocale(session('localization', config('app.locale')));

セッションに保存された値に基づいてアプリケーションのロケール(言語)を設定するか、Laravelの設定で指定されたデフォルトロケールにフォールバックします。

session()->has('localization'):これは、セッションにlocalizationという値が格納されているかどうかをチェックします。

app()->setLocale(...):アプリケーションのロケールを指定した値に設定します。

config('app.locale'):セッションにlocaleの値がない場合、Laravel設定ファイルで指定されたlocaleの値を取得します。

  1. ビューにリンクを追加する
<a href="{{ route('localization', 'jp') }}">JP</a>
<a href="{{ route('localization', 'en') }}">EN</a>

終わりに

Laravelの国際化について簡単いまとめてみました。

Discussion