Email

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 Email
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