LoginSignup
16
18

More than 3 years have passed since last update.

Laravelで多言語対応いろいろ

Last updated at Posted at 2019-06-12

Bladeを使った多言語対応に関しては以下に乗ってるのでそれ以外に関して
https://readouble.com/laravel/5.8/ja/localization.html

言語切替の実装方法

まずroutes/web.phpに切り替え用のリクエストを実装

routes/web.php
+Route::post('lang/{language}', 'ExampleController@language')->name('language');

受け側のコントローラー

app/Http/ExampleController.php
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;

class ExampleController extends Controller
{
...
    public function language(Request $request, $language)
    {
        // セッションに言語コードをセット
        Session::put('language',$languqage);
        // ダミーの戻り値
        return ['result'=>'OK'];
    }
}

呼び出し側

app.js
let lang = [プルダウンの値などを取得]
let params = new URLSearchParams()
let url = '/lang/'+lang // ex. /lang/ja | /lang/enなど
window.axios.post(url,params)
    .then((response)=>{
    })
    .catch((error)=>{
    })

言語切替の利用側
ミドルウェア

$ php artisan make:middleware Language
app/Http/Middleware/Language.php
<?php

namespace App\Http\Middleware;

use App;
use Closure;

class Language
{
    public function handle($request, Closure $next)
    {
        // セッションから言語コードを取り出しロケールにセット
        if(session('language'))
        {
            App::setLocale(session('language'));
        }
        return $next($request);
    }
}

ミドルウェアの登録

app/Http/Kernel.php
protected $routeMiddleware = [
...
+   'language' => \App\Http\Middleware\Language::class,
];

このミドルウェアは各コントローラーで使うのでapp/Http/Controller.phpに処理を定義して継承先でコールするのが望ましいかと思う
__construct()で呼ばないとバリエーションメッセージなどに適応されないなどがあったためここで処理

app/Http/Controller.php
class Controller extends BaseController
{
...
+   public function __construct()
+   {
+       $this->middleware('language');
+   }
}

各コントローラーには以下の様に追記

app/Http/Auth/LoginController.php
    public function __construct()
    {
        // 親クラスのコンストラクタをコール
+       parent::__construct();
        $this->middleware('guest')->except('logout');
    }

ログイン画面のエラー表示はこんな感じ
英語
img_20190612le.png

日本語
img_20190612lj.png

PasswordResetやEmailVerifyで送信される文面の多言語化

文面定義ファイルの用意

resources/lang/en/password_reset.php
<?php
return [
    'greeting' => 'Hello!',
    'salutation' => '',
    'subject' => 'Reset Password Notification',
    'line1' => 'You are receiving this email because we received a password reset request for your account.',
    'line2' => 'This password reset link will expire in :count minutes.',
    'line3' => 'If you did not request a password reset, no further action is required.',
    'action' => 'Reset Password'
];
resources/lang/en/email_verify.php
<?php
return [
    'greeting' => 'Hello!',
    'salutation' => '',
    'subject' => 'Verify Email Address' ,
    'line1' => 'Please click the button below to verify your email address.',
    'line2' => 'If you did not create an account, no further action is required.',
    'action' => 'Verify Email Address'
];
resources/lang/ja/password_reset.php
<?php
return [
    'greeting' => 'ご利用ありがとうございます。',
    'salutation' => '',
    'subject' => 'パスワードリセットリクエストを受け付けました',
    'line1' => 'パスワードリセットのリクエストがありましたのでメッセージを送信しました。',
    'line2' => '本メール発行から :count 分以内に実行しないと上記のリンクは無効となります。',
    'line3' => 'もしこのメールに覚えが無い場合は破棄してください。',
    'action' => 'リセット開始'
];
resources/lang/ja/email_verify.php
<?php
return [
    'greeting' => 'ご登録ありがとうございます。',
    'salutation' => '',
    'subject' => '本登録メール' ,
    'line1' => '以下の認証リンクをクリックして本登録を完了させてください。',
    'line2' => 'もしこのメールに覚えが無い場合は破棄してください。',
    'action' => 'メールアドレスを認証する'
];

文面上書きの定義

$ php artisan make:notification PasswordResetMultiLang
$ php artisan make:notification EmailVerifyMultiLang

ここで自動生成されるコードはNotification継承になってる為元々呼ばれるクラスの継承に差し替えて
toMail()関数のみを上書きする(Notification継承でメソッドを丸々コピーで実装してる人が多いのはなぜだろう?)

※※※Laravel6.x系ではLang::getFromJson()はLang::get()に変更※※※

app/Notifications/PasswordResetMultiLang.php
<?php
namespace App\Notifications;

use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Lang;

class ResetPasswordMultiLang extends ResetPassword
{
    public function toMail($notifiable)
    {
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $this->token);
        }
        $mailMessage = new MailMessage;
        $mailMessage->greeting = Lang::getFromJson('password_reset.greeting');
        return $mailMessage
            ->subject(Lang::getFromJson('password_reset.subject'))
            ->line(Lang::getFromJson('password_reset.line1'))
            ->action(Lang::getFromJson('password_reset.action'), url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
            ->line(Lang::getFromJson('password_reset.line2', ['count' => config('auth.passwords.users.expire')]))
            ->line(Lang::getFromJson('password_reset.line3'));
    }
}
app/Notifications/EmailVerifyMultiLang.php
<?php
namespace App\Notifications;

use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Lang;

class VerifyEmailMultiLang extends VerifyEmail
{
    public function toMail($notifiable)
    {
        $verificationUrl = $this->verificationUrl($notifiable);
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
        }
        $mailMessage = new MailMessage;
        $mailMessage->greeting = Lang::getFromJson('email_verify.greeting');
        return $mailMessage
            ->subject(Lang::getFromJson('email_verify.subject'))
            ->line(Lang::getFromJson('email_verify.line1'))
            ->action(Lang::getFromJson('email_verify.action'), $verificationUrl)
            ->line(Lang::getFromJson('email_verify.line2'));
    }
}

呼び出しの上書き

app/User.php
<?php
namespace App;
...
+use App\Notifications\ResetPasswordMultiLang;
+use App\Notifications\VerifyEmailMultiLang;

class User extends Authenticatable implements MustVerifyEmailContract
{
    ...
+    public function sendEmailVerificationNotification()
+    {
+        $this->notify(new VerifyEmailMultiLang);
+    }
+    public function sendPasswordResetNotification($token)
+    {
+        $this->notify(new ResetPasswordMultiLang($token));
+    }
}

EmailVerifyの有効かに関しては以下を参照
Laravel:Email Verification(メールアドレスの確認)を使う

受信メールのイメージ

パスワードリセット
英語
img_20190612re.png

日本語
img_20190612rj.png

メールアドレス確認
英語
img_20190612ve.png

日本語
img_20190612vj.png

※上記言語設定ファイルのsalutationの項目を書いて$mailMessage->salutationに値を設定すればRegards, Laravelの部分も変えられるけれど改行とか色々面倒だったのでそのままとした

16
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
18