やりたいこと
- Laravelのauthで導入されるログイン機能は便利だけど、パスワードリセットやメール認証のメールが英語なので、日本語にしたい。
- 言語ファイルいじるだけでも日本語化は出来るが、できれば好きなデザイン・内容にしたい。
環境
- Laravel 6.x (執筆時点では6.5.2)
$ php artisan --version
Laravel Framework 6.5.2
- 事前に認証機能の導入を済ませている。
- 具体的に言うと下記コマンドを実行済みで、プロジェクトも作ってある。
$ composer require laravel/ui "^1.0" --dev
$ php artisan ui vue --auth
大雑把な流れ
- Userクラスの通知関数をオーバーライド
- そこで用いるためのNotificationを作成、コーディング
- メール文面を作成
手順(パスワードリセットの場合)
通知クラスの作成
artisanを利用してまずは空で作る。中身は後の手順で書く。
$ php artisan make:notification PasswordResetNotification
Notification created successfully.
これで app/Notifications/PasswordResetNotification.php
が作成される。
Userクラスの通知関数をオーバーライド
既存のUserモデルクラスに対して、以下のオーバーライド処理を追記する。
/**
* Override to send for password reset notification.
*
* @param [type] $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new PasswordResetNotification($token));
}
通知クラスの中身をコーディング
1からNotificationクラスを書いても良いけど、折角なのでデフォルトで導入されて使われている ResetPassword
クラスをパクr……継承して使わせてもらう。
まずは全文がこちら。
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Auth\Notifications\ResetPassword;
class PasswordResetNotification extends ResetPassword
{
use Queueable;
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
return (new MailMessage)
->subject('パスワードリセット通知')
->view('emails.password_reset', [
'reset_url' => url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false))
]);
}
}
順に解説する。
make:notification
時でデフォルトで書かれている内容は割愛するが、以下の関数は不要なので削除してしまう(オーバーライドの必要性がない)。
__construct()
via()
toArray()
次に use
について。
use Illuminate\Auth\Notifications\ResetPassword;
こちらを追加しておく。
今回のカスタマイズをしない場合に使用されるのがこのクラスなので、つまりこれをありがたく流用させてもらうことで、がっつりと手間を省いてしまう。
なので extends
の部分も、
class PasswordResetNotification extends ResetPassword
としておく。
もとは extends Notification
だがここを流用するクラスに変えておく。
あとはメール送信部分である toMail()
だけコーディングしてあげれば良い。
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
return (new MailMessage)
->subject('パスワードリセット通知')
->view('emails.password_reset', [
'reset_url' => url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false))
]);
}
if文部分は流用元そのままなので、そのまま利用。
件名を ->subject()
の引数に入れておき、メールで送りたいViewを ->view()
で指定してあげればOK。
ここでは 'emails.password_reset'
を指定しているので、 resources/views/emails/password_reset.blade.php
がViewとして扱われてメールで送られていく、ということになる。
view()
指定で送るようにすれば、Bladeテンプレートが利用できるのでとても便利。
第2引数にはArrayで変数を送ることもできる。上記の例でリンクURLとして使用するための url(config('app.url').~~
としている部分は、流用元そのままなので深く考えずにコピペで良いと思う。
メール文面の作成
あとは普段通りにViewを作るだけ!
手順(メール認証の場合)
基本的にはパスワード認証と同じ。以下の点が異なるだけ。
- 継承元クラスは
VerifyEmail
になる。-
use Illuminate\Auth\Notifications\VerifyEmail;
になる。
-
-
toMail()
のコードは以下のような感じ。
public function toMail($notifiable)
{
$verificationUrl = $this->verificationUrl($notifiable);
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
}
return (new MailMessage)
->subject('メール認証')
->view('emails.email_verify', [
'verify_url' => $verificationUrl
]);
}
- view側で
verify_url
の変数参照する際は{{ $verify_url }}
ではなく{!! $verify_url !!}
とする。URL内にアンパサンドが入ってくるので。
参考:Framework側のコード
困ったらFramework側のコードを見てしまうと参考になるかも。
このあたり。
-
vendor\laravel\framework\src\Illuminate\Auth\Notifications
- ResetPassword.php
- VerifyEmail.php
-
vendor\laravel\framework\src\Illuminate\Notifications\resources\views
- email.blade.php
単に日本語化するだけであれば、今回のような手間をかけなくても、上記のファイルを見ながら resources\lang\ja.json
にゴリゴリと対訳を書いてしまうだけでも良い。