Laravelの認証メールとパスワードリセットメールを日本語化する方法

目次

認証メールとパスワードリセットメールを日本語化する方法

config/app.phpで日本語を選択

後で用意する日本語テキストを使用するように、まずはLaravelの設定を変更する

config/app.php


// もともとは'en'
'locale' => 'ja',
'fallback_locale' => 'ja',

// ついでにタイムゾーンも変更しておく
'timezone' => 'Asia/Tokyo',

編集後はプロジェクトを再起動。

コマンド


$ php artisan serve

日本語メール作成用のクラスを作成

メールを送るときにテキストを日本語で作成する専用のクラスを作る。

以下のコマンドで”App\Notifications\”の中に新しいファイルができる。

コマンド


# 認証メールを日本語化するためのクラスを作成 
$ php artisan make:notification VerifyMailJP

# パスワードリセットメールを日本語化するためのクラスを作成
$ php artisan make:notification ResetPasswordJP

コードの中身を以下のように変更する。

メールを作成するクラスを継承した上で、メール本文を作成するメソッドをオーバーライドして日本語のメールを作成できるようにしている。

App/Notifications/VerifyEmailJP.php


namespace App\Notifications;

use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;

// オーバーライドに必要
use Illuminate\Support\Facades\Lang;

class VerifyEmailJP extends VerifyEmail
{
    // オーバーライド
    public function toMail($notifiable)
    {
        $verificationUrl = $this->verificationUrl($notifiable);

        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
        }

        return (new MailMessage)
            ->subject(Lang::get('mail.verification.subject'))
            ->line(Lang::get('mail.verification.line_01'))
            ->action(Lang::get('mail.verification.action'), $verificationUrl)
            ->line(Lang::get('mail.verification.line_02'));
    }
}
app/Notifications/ResetPasswordJP.php


namespace App\Notifications;

use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Notifications\Messages\MailMessage;

// オーバーライドに必要
use Illuminate\Support\Facades\Lang;

class ResetPasswordJP extends ResetPassword
{
    // オーバーライド
    public function toMail($notifiable)
    {
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $this->token);
        }

        return (new MailMessage)
            ->subject(Lang::get('mail.password_reset.subject'))
            ->line(Lang::get('mail.password_reset.line_01'))
            ->action(Lang::get('mail.password_reset.action'), url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false)))
            ->line(Lang::get('mail.password_reset.line_02', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
            ->line(Lang::get('mail.password_reset.line_03'));
    }
}

Userモデルを修正

メールを送信するのは”Illuminate\Foundation\Auth\User”を継承したUserモデルなので、メール送信時に上記で作成したクラスを利用するように修正(メール送信メソッドをオーバーライド)する。

app/User.php


// 略

// 日本語のメールを作成するクラス(さっき作ったもの)
use App\Notifications\VerifyEmailJP;
use App\Notifications\ResetPasswordJP as ResetPasswordNotificationJP;

class User extends Authenticatable implements MustVerifyEmail
{
    // 略

    // オーバーライド
    public function sendEmailVerificationNotification()
    {
        // $this->notify(new VerifyEmail);
        $this->notify(new VerifyEmailJP);
    }

    // オーバーライド
    public function sendPasswordResetNotification($token)
    {
        // $this->notify(new ResetPasswordNotification($token));
        $this->notify(new ResetPasswordNotificationJP($token));
    }
}

なお、”ResetPasswordJP”をasで”ResetPasswordNotificationJP”としているのは、もともとのやり方に合わせているから(変更前も”ResetPassword”をasで”ResetPasswordNotification”にしている)。

なので別にやらなくても動く。

MEMO

VerifyEmailはそのままの名前で使っているのに何故かResetPasswordだけお尻にNotificationを付いており統一感がないのが微妙。

個人的にはNotificationが付いている方が分かりやすいと思うが、どちらか一方に合わせた方が良かったのでは。作っている人が違うのか?

メールの日本語化ファイルを用意

メール本文は外部のファイルで日本語化するように記述しているので、それを用意する。

“resources/lang/en”をコピーしてフォルダ名を”ja”にする。

コマンド


$ xcopy en ja
ja は受け側のファイル名ですか、
またはディレクトリ名ですか
(F= ファイル、D= ディレクトリ)? d
en\auth.php
en\pagination.php
en\passwords.php
en\validation.php
4 個のファイルをコピーしました

“resources/lang/ja”の中にmail.phpを作る。これでメール本文を日本語化できる。

resources/lang/ja/mail.php


 [
        'subject' => 'メールアドレスの認証',
        'line_01' => '下のボタンをクリックしてメールアドレス認証を行うと本登録が完了します。',
        'action'  => 'メールアドレス認証を行う',
        'line_02' => 'もし、当メールに心当たりがない場合はお手数ですが破棄して下さい。',
    ]
    ,
    'password_reset' => [
        'subject' => 'パスワードの再設定',
        'line_01' => '以下のボタンをクリックするとパスワードの再設定を行えます。',
        'action'  => 'パスワードの再設定',
        'line_02' => 'このボタンの有効期限は:count分です。',
        'line_03' => 'もし、パスワードの再設定を行わない場合はお手数ですが当メールは破棄して下さい。',
    ]
];

メールの雛形を日本語化する

以上でメール本文は日本語化できるが、この状態でメールを受け取ると以下のように日本語と英語が入り混じったメールになってしまう。

Laravel メールの日本語化

これはメールの雛形(あいさつやフッター部分など)は別のファイル定義しているから。メール全てを日本語化するためにはメールの雛形も変更する必要がある。

以下のコマンドを打って、”laravel-notifications”の番号を入力する(以下の例だと12)。

コマンド


$ php artisan vendor:publish
 Which provider or tag's files would you like to publish?:
  [0 ] Publish files from all providers and tags listed below
  [1 ] Provider: Facade\Ignition\IgnitionServiceProvider
  [2 ] Provider: Fideloper\Proxy\TrustedProxyServiceProvider
  [3 ] Provider: Illuminate\Foundation\Providers\FoundationServiceProvider
  [4 ] Provider: Illuminate\Mail\MailServiceProvider
  [5 ] Provider: Illuminate\Notifications\NotificationServiceProvider
  [6 ] Provider: Illuminate\Pagination\PaginationServiceProvider
  [7 ] Provider: Laravel\Tinker\TinkerServiceProvider
  [8 ] Tag: flare-config
  [9 ] Tag: ignition-config
  [10] Tag: laravel-errors
  [11] Tag: laravel-mail
  [12] Tag: laravel-notifications ← この番号を入力する
  [13] Tag: laravel-pagination
 > 12

“resources\views\vendor\notifications\email.blade.php”ができるので以下のように修正する。

resources/views/vendor/notifications/email.blade.php


@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('Whoops!')
@else

# @lang('こんにちは')
@endif
@endif

{{-- Intro Lines --}}
@foreach ($introLines as $line)
{{ $line }}

@endforeach

{{-- Action Button --}}
@isset($actionText)

@component('mail::button', ['url' => $actionUrl, 'color' => $color])
{{ $actionText }}
@endcomponent
@endisset

{{-- Outro Lines --}}
@foreach ($outroLines as $line)
{{ $line }}

@endforeach

{{-- Salutation --}}
@if (! empty($salutation))
{{ $salutation }}
@else

{{ config('app.name') }}より
@endif

{{-- Subcopy --}}
@isset($actionText)
@slot('subcopy')
    
@lang(
    "もし、「:actionText」ボタンがうまく機能しない場合は、以下のURLをブラウザのURL欄にコピー&ペーストしてアクセスして下さい。
    [:actionURL](:actionURL)",
    [
        'actionText' => $actionText,
        'actionURL' => $actionUrl,
    ]
)
@endslot
@endisset
@endcomponent

以上でメールの日本語化は完了。

なお、ログイン画面・登録画面・パスワードリセット画面・パスワード確認画面を日本語化する方法は以下を参照。

Laravelのログイン・登録・パスワードリセット・パスワード確認画面を日本語化する方法 Laravelのログイン・登録・パスワードリセット・パスワード確認画面を日本語化する方法

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です