LaravelのMailMessageクラスをカスタマイズする

この記事は、`MailMessage`クラスの仕組みとカスタマイズ方法を解説し、HTMLメールとテキストメールをまとめて作って生産性を上げよう！という趣向の記事になっております！

# MailMessageクラスって何？

`php artisan make:notification`で通知のひな型を生成すると`Notification`を継承した以下の様なコードが現れます。
ここで使われている`MailMessage`クラスが本記事の主役です。

```php
public function toMail($notifiable)
{
    return (new MailMessage)
                ->line('The introduction to the notification.')
                ->action('Notification Action', url('/'))
                ->line('Thank you for using our application!');
}
```

このひな型の中では、`MailMessage`クラスを使ってメールの文章が構築されていますが、この`MailMessage`クラスに関するドキュメントがあまりないため、恐らく多くのケースで、まったく別のコードに置き換えるか、雰囲気でカスタマイズしていたりするのではないでしょうか？

以下で、クラスの仕組みとカスタマイズ方法を解説していきます。

# Laravelのバージョン

Laravel 5.7




# 文章の構築

文章の構築は`subject()`, `greeting()`, `line()`などのメソッドを呼び出して行います。
各メソッドがメール上のどこに出力されるかは、以下の図の通りです。
左の画像が構築されるHTMLメールで、右の画像が構築する処理、赤矢印で対応を表しています。

![2019-12-01_21h46_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71575/96b5e78a-dcec-0305-e2d6-8121cd2a14a2.png)


上図の補足ですが、`subject`はメールの件名となります。
①には`.env`の`APP_ENV`の値が出力されます。
②はリンクになっており`action()`の第二引数で指定したURLが出力されます。
また、`level()`の指定により色が変わります。
③はアクションボタンの出力がある場合のみ出力される注意書きです。
英語が出力されている箇所については、`@lang`を通して出力されているので
[Translation Strings](https://laravel.com/docs/5.7/localization#using-translation-strings-as-keys)を使って置き換える事ができます。

テキストメールしか対応していないメールクライアントの場合、以下の様に表示されます。

![2019-12-01_21h43_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71575/0dbfe72d-2d51-af0b-f875-000721dfbad6.png)




# 使用されるbladeについて

デフォルトでは以下のbladeを使用してレンダリングされます。

## HTMLメールの場合
  * ①メール全体のレイアウト
    * [Illuminate/Mail/resources/views/html/layout.blade.php](https://github.com/laravel/framework/blob/v5.7.23/src/Illuminate/Mail/resources/views/html/layout.blade.php)
  * ②本文部分のヘッダー/フッター
    * [Illuminate/Mail/resources/views/html/message.blade.php](https://github.com/laravel/framework/blob/v5.7.23/src/Illuminate/Mail/resources/views/html/message.blade.php)
  * ③本文部分のコンテンツ
    * [Illuminate/Notifications/resources/views/email.blade.php](https://github.com/laravel/framework/blob/v5.7.23/src/Illuminate/Notifications/resources/views/email.blade.php)
    
## テキストメールの場合
  * ④メール全体のレイアウト
    * [Illuminate/Mail/resources/views/markdown/layout.blade.php](https://github.com/laravel/framework/blob/v5.7.23/src/Illuminate/Mail/resources/views/markdown/layout.blade.php)
  * ⑤本文部分のヘッダー/フッター
    * [Illuminate/Mail/resources/views/markdown/message.blade.php](https://github.com/laravel/framework/blob/v5.7.23/src/Illuminate/Mail/resources/views/markdown/message.blade.php)
  * ⑥本文部分のコンテンツ
    * [Illuminate/Notifications/resources/views/email.blade.php](https://github.com/laravel/framework/blob/v5.7.23/src/Illuminate/Notifications/resources/views/email.blade.php)

①の内容を確認すると、本文部分のテキストを`Illuminate\Mail\Markdown::parse()`を通しているためHTMLメールではmarkdown記法が使える様です。
逆に、④では、`Illuminate\Mail\Markdown::parse()`を通していない他、[strip_tags](https://www.php.net/manual/ja/function.strip-tags.php)関数を通してHTMLタグを取り除いている事が分かります。
なお、③と⑥は同じファイルです。

## bladeのカスタマイズ方法

③⑥は`MailMessage`の`markdown('your-blade-name')`で指定したbladeに差し替える事ができます。
①②は`/resources/views/vendor/mail/html`以下に同名のbladeを配置すると、そちらが使われます。
④⑤は`/resources/views/vendor/mail/markdown`以下に同名のbladeを配置すると、そちらが使われます。


# Markdownについて

MailMessageではMarkdown記法が使用でき、パースには[parsedown](https://github.com/erusev/parsedown)が使用されています。（[デモページ](https://parsedown.org/demo)）
使える文法は[GitHub Flavored](https://github.github.com/gfm/)に準拠している様です。

なお、テキストメールには変換前のmarkdownがそのまま出力されます。

# スタイルのカスタマイズについて

HTMLメールで適応されるCSSをthemeと呼んでいる様です。

デフォルトで適応されるCSS(theme)は以下となります。
[Illuminate/Mail/resources/views/html/themes/default.css](https://github.com/laravel/framework/blob/v5.7.23/src/Illuminate/Mail/resources/views/html/themes/default.css)

カスタマイズしたい場合は`/resources/views/vendor/mail/html/themes/default.css`を作成すると、そちらが使われます。

# 改行する方法

デザインの都合上、１つの`line()`の中で改行したいケースがあります。
（改行を含む文字列を入力しても、出力時には取り払われてしまう。brタグも同様。）
その場合は以下の様に書く必要があります。

```php
->line(new HtmlString("１行目のテキスト<br>\n２行目のテキスト"))
```

キモは`<br>`と`\n`を両方書くことです。
これにより、HTMLメールとテキストメールの両方で改行されます。


# 最後に

以上が、MailMessageの仕組みとカスタマイズ方法となります。
お役に立てましたら「いいね」を頂けると嬉しいです！！