DeviseのHTMLメールでBootstrapのようなボタンを使いたい

# はじめに
Deviseが送信するメールをBootstrapのボタンを使いたかったので、そのやり方をメモ。結局、BootstrapはGmailでは`Message Clipped`になったので`Foundation for Emails`にした。

# Bootstrap
## 1. Gem install
使った`premailer-rails`Gemは`<head>`に書いたcssファイルをinline cssに変換してくれる。

```ruby:Gemfile
# CSS for HTML mail
gem 'premailer-rails'
```

## 2. Deviseの設定
今回はDeviseのメールアドレス確認メールでBootstrapを使いたいので、`Devise::Mailer`が`app/views/layouts/mailer.html.erb`テンプレートを読み込むようにする。

```ruby:config/initializers/devise.rb
Devise.setup do |config|
途中省略
  # Configure the class responsible to send e-mails.
  # config.mailer = 'Devise::Mailer'
  config.mailer = 'DeviseMailer'
途中省略
end

# deviseのmailer layoutを設定する
Rails.application.config.to_prepare do
  Devise::Mailer.layout 'mailer'
end
```

Deviseメールのタイトルを変更する

```ruby:app/mailers/devise_mailer.rb
class DeviseMailer < Devise::Mailer

  def confirmation_instructions(record, token, opts={})
    logger.info("[LOGGER] DeviseMailer confirmation_instructions started.")
    mail = super
    mail.subject = "HogeHoge " + I18n.t('devise.mailer.confirmation_instructions.subject')
    mail
  end
end
```


## 3. mailerテンプレートのカスタマイズ
mailerテンプレートの`<head>`でBootstrapのCSSを読み込ませる。結果、以下のようになった。

```ruby:app/views/layouts/mailer.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <!-- 必要なメタタグ -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CDN -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <%#= stylesheet_link_tag "mailer/common", media: "all" %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>
```

## 4.さっそく試してみる
Deviseでサインアップして、メールアドレス確認のメールにBootstrapのボタンが使えるか試してみた。i18nで多言語化している。`class: 'btn btn-primary'`を追加している。

```ruby:app/views/devise/mailer/confirmation_instructions.html.erb
<p><%= t('.greeting', recipient: @email) %></p>
<p><%= t('.instruction') %></p>
<p><%= link_to t('.action'), confirmation_url(@resource, confirmation_token: @token), class: 'btn btn-primary' %></p>
```

![スクリーンショット 2020-02-27 午後6.37.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329289/45c9115f-8add-df5e-7d15-2d499ea0e945.png)
Bootstrapのボタンが出ることを確認できた。ただ、Gmailだと`Message Clipped`になってしまう。たぶん、Bootstrapは`bootstrap.min.css`でもCSSが長すぎるからだろうとは思うが、何か対応策があるかは別途調べる事にする。

# Foundation for Emails 2.0
ボタンを使いたいだけであればBootstrapではなくFoundationを試してみる。inkyも試してみたら、Railsの`link_to`をどう書けば良いか分からなかったので使わなかった。

## 1. 変更したファイル

```ruby:Gemfile
# Foundation for Emails
gem 'premailer-rails'
gem 'foundation_emails'
```

```ruby:app/views/layouts/mailer.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width" />

    <%= stylesheet_link_tag "foundation_emails", media: "all" %>
  </head>

  <body>
    <table class="body" data-made-with-foundation>
      <tr>
        <td class="center" align="center" valign="top">
          <center>
            <%= yield %>
          </center>
        </td>
      </tr>
    </table>
  </body>
</html>
```

```ruby:app/assets/stylesheets/foundation_emails.scss
@import "foundation-emails";
```

```ruby:app/assets/stylesheets/application.css.scss
- *= require_tree .　　これをコメントアウトしないとfoundation_emails.scssが読み込まれてしまう
+ * require_tree .
```

```ruby:app/views/devise/mailer/confirmation_instructions.html.erb
<p><%= t('.greeting', recipient: @email) %></p>
<p><%= t('.instruction') %></p>
<table class="button">
  <tr>
    <td>
      <table>
        <tr>
          <td>
            <%= link_to t('.action'), confirmation_url(@resource, confirmation_token: @token) %>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>
```
## 2. 試してみる

![スクリーンショット 2020-02-27 午後8.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329289/2a9ab925-438b-fdb0-a6cf-42437229851a.png)

Foundation for EmailsではGmailでも`Message Clipped`にならずにボタンが表示できた。

ここまで動けば、あとはメールテンプレートを好きなだけカッコよくすれば良い。

## 3. scssが読み込まれない
`mailer/common.css` が無いというエラーが出た場合は[参考記事](https://stackoverflow.com/questions/29180971/how-to-link-scss-file-with-style-sheet-link-tag-in-ruby-on-rails/29182943)にある`config/initializers/assets/assets.rb`に以下を追記すれば良い。

```ruby:config/initializers/assets/assets.rb
Rails.application.config.assets.precompile += %w( mailer/common.css )
```

# 参考記事
[Deviseのmailerでlayoutを適用する](https://www.tom08.net/entry/2017/07/25/100917)
[railsのmailerでcssファイルを使う＆画像も入れ](https://qiita.com/gymnstcs/items/978b7b4afee4d9a989ec)
[RailsでFoundation for Emails 2.0を使ってレスポンシブなHTMLメールを送る](https://qiita.com/masuidrive/items/0e3769ad890c9f21bbcb)
[HTMLメールを作るにあたって知っておきたいこと](https://qiita.com/Altech/items/22e3b1e59f74af4e4067)
[Foundation for Emails Read Me](https://github.com/foundation/foundation-emails)
[Foundation for Emails 2 Migration Guide](https://github.com/foundation/foundation-emails/blob/master/migration.md)
[Foundation for Emails Document](https://get.foundation/emails/docs/index.html)
[How to link scss file with style sheet link tag in Ruby on Rails](https://stackoverflow.com/questions/29180971/how-to-link-scss-file-with-style-sheet-link-tag-in-ruby-on-rails/29182943)