Send mail through a configured transport, from raw Latte templates or the mail addon.
On this page
$app->email() returns a Mailer for the email.default transport (a Symfony DSN, see Configuration). $app->email('name') uses email.name.
The Mailer is deliberately plain: you set the addresses, point it at a Latte template and send.
$app->email()
->from('[email protected]', 'Example')
->to($user->email)
->subject('Your invoice')
->html('mail/invoice.latte', ['invoice' => $invoice])
->text("Invoice {$invoice->number}")
->send();
html($view, $data) renders any Latte template as the HTML part. Its variables are the $data you pass plus $mail, the mailer itself. $page and $app are not available. cc(), bcc(), replyTo() and attach($path) work as expected.
Images
Mail clients block or break remote images, and a host that does not serve them yet shows a broken icon. embed($path) sends the file inside the message and returns the cid: URL for it. Latte blocks that scheme in a URL attribute, so print it with |nocheck:
<img
src="{$mail->embed(p('assets')->file('logo.png')->path)|nocheck}"
width="200"
alt="Logo"
>
A file embedded twice travels once. For an SVG or a resized image, embed a variant: $file->variantPath('w=400') is the PNG or resized file on disk, generated first if needed.
The mail addon
The phlat/mail addon holds ready-made templates for complex emails and a Phlat\Mail\Template class that fills them in. Each method takes a Mailer with sender, recipient and subject set, sets the HTML and plain-text parts and returns it.
use Phlat\Mail\Template;
$template = new Template($app);
$template->message(
$app->email()->from('[email protected]')->to($user->email)->subject('Your invitation'),
title: 'You are invited',
body: "Open the link to set a password.\nIt works for a day.",
url: $url,
label: 'Set password',
)->send();
| Method | |
|---|---|
message($mail, $title, $body, $url, $label) |
A title, a text body and an optional button |
newsletter($mail, $data) |
A hero image, image-and-text articles, a button and an unsubscribe line |
receipt($mail, $data) |
An order confirmation with an items table, totals, address and button |
Image values in newsletter() are any src: a URL, or $mail->embed($path).
Templates
The addon's templates use inline styles only, since mail clients drop <style> and external CSS:
| Template | Purpose |
|---|---|
@mail/layout.latte |
The HTML shell, with header, content, footer and legal blocks. Shows the root page title as the brand |
@mail/message.latte, newsletter.latte, receipt.latte |
The content of each method. They extend the layout through {layout $layout} |
Put a file of the same name in site/views/@mail/ and it replaces the default. Each is looked up separately, so overriding only the layout restyles every email and keeps the addon's content templates.
site/views/@mail/layout.latte ← checked first
phlat/addons/mail/views/layout.latte ← addon default