Magento2 メールテンプレート入門

この記事は[Magento Advent Calendar 2017](https://adventar.org/calendars/2349)の10日目です。

※ご指摘・お叱り等お気軽にコメントで頂けますと幸いです。

Magento2において、オリジナルのメールテンプレートを作成することをゴールとします。

#モジュールの作成
何はなくともまずはモジュールを作成します。
以下、ベンダー名は`Claves`、モジュール名は`EmailTemplate`として進めていきます。

* `/app/code/Claves/EmailTemplate/registration.php`

```php:registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Claves_EmailTemplate',
    __DIR__
);
```

* `/app/code/Claves/EmailTemplate/etc/module.xml`

```xml:module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Claves_EmailTemplate" setup_version="0.0.1">
        <sequence>
            <module name="Magento_Sales"/>
        </sequence>
    </module>
</config>
```

#メールテンプレートの作成
メールテンプレートを作成しMagentoに認識させます。
`Magento_Sales`モジュールにある、`New Order`テンプレートを例にとります。
##メールテンプレート本体とMagentoへの登録

* `magento2/app/code/Claves/EmailTemplate/view/frontend/email/order_new.html`  
こちらはメールテンプレートの初期値として読み込まれる内容です。  
コメント内にある`@subject`以下はメールの件名を、`@vars`以下は"変数の挿入"ボタンを押した際に列挙される変数をそれぞれ定義しています。

```html:order_new.html
<!--
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<!--@subject {{trans "Your %store_name order confirmation" store_name=$store.getFrontendName()}} @-->
<!--@vars {
"var formattedBillingAddress|raw":"Billing Address",
"var order.getEmailCustomerNote()":"Email Order Note",
"var order.increment_id":"Order Id",
"layout handle=\"claves_sales_email_order_items\" order=$order area=\"frontend\"":"Order Items Grid",
"var payment_html|raw":"Payment Details",
"var formattedShippingAddress|raw":"Shipping Address",
"var order.getShippingDescription()":"Shipping Description",
"var shipping_msg":"Shipping message"
} @-->

{{template config_path="design/email/header_template"}}

<table>
    <tr class="email-intro">
        <td>
            <p class="greeting">{{trans "%customer_name," customer_name=$order.getCustomerName()}}</p>
            <p>
                {{trans "Thank you for your order from %store_name." store_name=$store.getFrontendName()}}
                {{trans "Once your package ships we will send you a tracking number."}}
                {{trans 'You can check the status of your order by <a href="%account_url">logging into your account</a>.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
            </p>
            <p>
                {{trans 'If you have questions about your order, you can email us at <a href="mailto:%store_email">%store_email</a>' store_email=$store_email |raw}}{{depend store_phone}} {{trans 'or call us at <a href="tel:%store_phone">%store_phone</a>' store_phone=$store_phone |raw}}{{/depend}}.
                {{depend store_hours}}
                {{trans 'Our hours are <span class="no-link">%store_hours</span>.' store_hours=$store_hours |raw}}
                {{/depend}}
            </p>
        </td>
    </tr>
    <tr class="email-summary">
        <td>
            <h1>{{trans 'Your Order <span class="no-link">#%increment_id</span>' increment_id=$order.increment_id |raw}}</h1>
            <p>{{trans 'Placed on <span class="no-link">%created_at</span>' created_at=$order.getCreatedAtFormatted(2) |raw}}</p>
        </td>
    </tr>
    <tr class="email-information">
        <td>
            {{depend order.getEmailCustomerNote()}}
            <table class="message-info">
                <tr>
                    <td>
                        {{var order.getEmailCustomerNote()|escape|nl2br}}
                    </td>
                </tr>
            </table>
            {{/depend}}
            <table class="order-details">
                <tr>
                    <td class="address-details">
                        <h3>{{trans "Billing Info"}}</h3>
                        <p>{{var formattedBillingAddress|raw}}</p>
                    </td>
                    {{depend order.getIsNotVirtual()}}
                    <td class="address-details">
                        <h3>{{trans "Shipping Info"}}</h3>
                        <p>{{var formattedShippingAddress|raw}}</p>
                    </td>
                    {{/depend}}
                </tr>
                <tr>
                    <td class="method-info">
                        <h3>{{trans "Payment Method"}}</h3>
                        {{var payment_html|raw}}
                    </td>
                    {{depend order.getIsNotVirtual()}}
                    <td class="method-info">
                        <h3>{{trans "Shipping Method"}}</h3>
                        <p>{{var order.getShippingDescription()}}</p>
                        {{if shipping_msg}}
                        <p>{{var shipping_msg}}</p>
                        {{/if}}
                    </td>
                    {{/depend}}
                </tr>
            </table>
            {{layout handle="claves_sales_email_order_items" order=$order area="frontend"}}
        </td>
    </tr>
</table>

{{template config_path="design/email/footer_template"}}

```

* `/app/code/Claves/EmailTemplate/etc/email_templates.xml`  
このファイルでメールテンプレートとしてMagentoに認識してもらいます。  
各属性の内容は次のとおりです。
    * `id="claves_email_template"` …メールテンプレートのID
    * `label="注文完了メール"` …読み込むメールテンプレートを選択する際のラベル
    * `file="order_new.html"` …先程作成したメールテンプレート
    * `type="html"` …`text`でテキストメール、`html`でhtmlメール
    * `module="Claves_EmailTemplate"` …モジュール名
    * `area="frontend"` …テンプレートファイルのあるエリア(今回は`view/frontend`)

```xml:email_templates.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
    <template id="claves_email_template" label="注文完了メール" file="order_new.html" type="html" module="Claves_EmailTemplate" area="frontend"/>
</config>

```


以上の二つのファイルにより、メールテンプレート作成時のテンプレート一覧に表示されるようになりました。  
![](https://qiita-image-store.s3.amazonaws.com/0/221335/2df63ec5-4ef1-9461-8dbb-2978ad6c3269.png)

##テンプレート内からのphtml読み込み
次に、メールテンプレート内で読み込むphtmlファイルの作成をします。
テンプレート内に書ける処理は翻訳(`{{trans ...}}`)、depend(=elseのないif)(`{{depend ...}}{{/depend}}`)、if/else(`{{if...}}{{else}}{{/if}}`)くらいなので、PHPのコードによる処理が必要な場合が多いです。
先程作成した`order_new.html`ファイル内にある`{{layout handle="claves_sales_email_order_items" order=$order area="frontend"}}`の記述がそれにあたります。

* `app/code/Claves/EmailTemplate/view/frontend/templates/email/items.phtml`

```php:items.phtml
<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

?>
<?php $_order = $block->getOrder() ?>
<?php if ($_order): ?>
    <?php $_items = $_order->getAllItems(); ?>
    <table class="email-items">
        <thead>
        <tr>
            <th class="item-info">
                <?= /* @escapeNotVerified */  __('Items'); ?>
            </th>
            <th class="item-qty">
                <?= /* @escapeNotVerified */  __('Qty'); ?>
            </th>
            <th class="item-price">
                <?= /* @escapeNotVerified */  __('Price'); ?>
            </th>
        </tr>
        </thead>
        <?php foreach ($_items as $_item): ?>
            <?php
            if ($_item->getParentItem()) {
                continue;
            }
            ?>
            <tbody>
            <?= $block->getItemHtml($_item) ?>
            </tbody>
        <?php endforeach; ?>
        <tfoot class="order-totals">
        <?= $block->getChildHtml('order_totals') ?>
        </tfoot>
    </table>
    <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order', $_order, $_order->getStore()) && $_order->getGiftMessageId()): ?>
        <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessage($_order->getGiftMessageId()); ?>
        <?php if ($_giftMessage): ?>
            <br />
            <table class="message-gift">
                <tr>
                    <td>
                        <h3><?= /* @escapeNotVerified */  __('Gift Message for this Order') ?></h3>
                        <strong><?= /* @escapeNotVerified */  __('From:'); ?></strong> <?= $block->escapeHtml($_giftMessage->getSender()) ?>
                        <br /><strong><?= /* @escapeNotVerified */  __('To:'); ?></strong> <?= $block->escapeHtml($_giftMessage->getRecipient()) ?>
                        <br /><strong><?= /* @escapeNotVerified */  __('Message:'); ?></strong>
                        <br /><?= $block->escapeHtml($_giftMessage->getMessage()) ?>
                    </td>
                </tr>
            </table>
        <?php endif; ?>
    <?php endif; ?>
<?php endif; ?>
```

* `/app/code/Claves/EmailTemplate/Block/Order/Email/Items.php`  
Blockクラスを作成します。  
もちろんここでデータの整形など独自の処理を書くこともできます。

```php:Items.php
<?php
namespace Claves\EmailTemplate\Block\Order\Email;

class Items extends \Magento\Sales\Block\Items\AbstractItems
{
}
```


* `/app/code/Claves/EmailTemplate/view/frontend/layout/claves_sales_email_order_items.xml`  
phtmlテンプレートとBlockクラスを定義します。

```xml:claves_sales_email_order_items.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" label="Email Order Items List" design_abstraction="custom">
    <body>
        <block class="Claves\EmailTemplate\Block\Order\Email\Items" name="items" template="email/items.phtml" cacheable="false"/>
    </body>
</page>
```

#おわりに
以上で簡単ではありますがメールテンプレートの作成ができました。
今回作成したファイルは以下のとおりです。

```
--- EmailTemplate
    |-- Block
    |   `-- Order
    |       `-- Email
    |           `-- Items.php
    |-- etc
    |   |-- email_templates.xml
    |   `-- module.xml
    |-- registration.php
    `-- view
        `-- frontend
            |-- email
            |   `-- order_new.html
            |-- layout
            |   `-- claves_sales_email_order_items.xml
            `-- templates
                `-- email
                    `-- items.phtml
```

ファイル数がわりと多い印象で、スタイルを変更するならlessファイル等も加わってきます。
僕の場合コアのファイルを参考にしながら進め、必要なファイルとそうでないファイルを見極めるのにわりと時間を使ってしまいました。
拙い記事ではありますがどなたかのお役に立てましたら幸いです。

最後まで読んで頂きありがとうございました！

参考：
http://devdocs.magento.com/guides/v2.2/frontend-dev-guide/templates/template-email.html