Sending a email template via a hook

I’m trying to send an email with a template:

kirby()->email('order', [
    'to' => $to,
    'subject' => 'Thanks for your order: ' . $orderNr,
    'template' => 'ordered',
    'data' => $data
]);

But the email never gets sent, yes there is a template (templates/emails/ordered.html.php) I tried it on an actual page where it worked. When i tried to send it with a body instead:

kirby()->email('order', [
    'to' => $to,
    'subject' => 'Thanks for your order: ' . $orderNr,
    'body' => 'Heya, thanks for your order. Were shipping it right away',
]);

It did work! But this is of course not what I want. How come a template doesn’t work but a body does?

ps. My Kirby version is 3.8.1.1

Does it work in the actual page when you define the template?

Yes it does

i think your data is not correct definded in the hook then.

I looked the data over and it all data returned normal

(
    [0] => tazio2003@gmail.com
    [1] => Invoice #00025
    [2] => Array
        (
            [sum] => 750,
            [page] => OrderPage Object
        )

)

code:

error_log(print_r([$to, $orderNr, $data], true));

out of ideas here. sorry.

No problem! I guess I’ll wait

Do you have a preset order defined?

Is there actually a template called ordered.php or ordered.html.php in /site/templates/emails? And could you please post the code you have in there?

Email object in config

'email' => [
        'transport' => [
            'type' => 'smtp',
            'host' => env('EMAIL_HOST'),
            'port' => 465,
            'security' => true,
            'auth' => true,
            'username' => env('EMAIL_USER'),
            'password' => env('EMAIL_PASS'),
        ],
        'presets' => [
            'order' => [
                'from' => env('EMAIL_USER'),
            ]
        ]
    ],

simplified template:

<?php
/**
 * When a user has ordered items from the webshop a
 * comformation email will be send to the input email.
 *
 * @var OrderPage $page
 * @var float $sum
 */
?>
<body>
  <main class="order container email">
    <div class="grid">
      <h1 data-width="1/1">
        <?= $page->title() ?>
      </h1>
      <p data-width="1/1">
        <strong><?= t('order.date') ?> <?= $page->invoiceDate()->toIntlDate() ?></strong>
      </p>
      <div data-width="1/1">
        <?php snippet('cart', ['cart' => $page->cart()]); ?>
      </div>
      <div class="text" data-width="1/2">
        <h2><?= t('order.payment') ?></h2>
        <p><?= tt('order.payment.text', compact('paymentMethod')) ?></p>
        <?php if ($page->paymentMethod()->toString() === 'prepayment'): ?>
          <?php if ($page->paymentComplete()->toBool() === true): ?>
            <p><?= tt('order.payment.text.paid.date', ['datetime' => $page->paidDate()->toIntlDate()]) ?></p>
        ...
          <?php endif; ?>
        <?php endif; ?>
      </div>
      <div class="text" data-width="1/2">
        <h2><?= t('order.shipping-address') ?></h2>
        <p>
          ...
        </p>
      </div>
    </div>
  </main>
</body>

That is your email template? Looks like a page template to me.

But if that was an email template, the $page variable would be undefined. If you send $data to the email template, that is the data you have available there. And since this template would throw an error, it will not be sent.

Isn’t it given when the data variable is created? Check here for my data variable

For the variable in the data array to work, your $data would have to look like this

$data = [
  'page' => //Page object here,
  'sum'  => 'Some sum here',
];

If what you posted above is the data array, then for one thing you are using an index instead of keys and the relevant part is a nested array.

Yep it does look like that:

$data = [
    'page' => $orderPage,
    'sum' => $sum
];

also the $orderPage object is:

[page] => OrderPage Object
                (
                    [children] => Kirby\Cms\Pages Object
                        (
                        )

                    [content] => Kirby\Cms\Content Object
                        (
                            [email] => tazio2003@gmail.com
                            [name] => Marta Doe
                            [organization] => 
                            [streetaddress] => Milkyway 1
                            [postalcode] => 12345
                            [city] => Ducktown
                            [country] => DE
                            [billingaddressisshippingaddress] => true
                            [shippingname] => 
                            [shippingorganization] => 
                            [shippingstreetaddress] => 
                            [shippingpostalcode] => 
                            [shippingcity] => 
                            [shippingcountry] => 
                            [paymentmethod] => ideal
                            [stripepublishablekey] => xxx
                            [stripepaymentintentid] => 
                            [items] => - 
                                key: 'shop/culturally-motivated/bramble-jacket/white#s=M'
                                id: >
                                    shop/culturally-motivated/bramble-jacket/white
                                quantity: 1
                                size: M
                                price: 159.95
                                tax: 27.759917355372
                                title: Bramble Jacket, White
                                taxrate: 21
                                template: product-variant
                                uid: white
                                sum: 159.95
                                sumtax: "27.759917355372"
                            [redirect] => xxx
                            [paymentdetails] => 
....

Then I don’t know. What if you just send a string in that template?

oh that did work! guess ill check every variable used now :sweat_smile:

Well I found my bug :melting_face: There was no paymentMethod variable. Might there be a better way to debug these types of templates without having to trigger them every time?

One option would be to use Tpl::load() somewhere, e.g. in a page template or a route, like this, while passing an example data array.

Tpl::load(kirby()->root('templates') . '/emails/email.php', ['text' => 'Some text']);

In a route

 'routes' => [
        [
            'pattern' => 'test-email-template',
            'action' => function () {
                return Tpl::load(kirby()->root('templates') . '/emails/email.php', ['text' => 'Some text']);
            }
        ],
  ],
1 Like