Mailversand mit Inky und TYPO3

Es kann ziemlich langwierig und nervenaufreibend sein, responsive HTML-Mails zu stylen, da auf den meisten E-Mail-Clients nur ein sehr eingeschränkter CSS Support vorhanden ist. Eine mehr oder weniger kurze Übersicht gibt’s auf campaignmonitor.com. Foundation für Emails hilf dabei, E-Mails zu gestalten, die auf den meisten Clients funktionieren. Inky ist die hauseigene Templating-Language, die es ermöglicht, komplexe Table-Layouts mittels bereitgestellter Tags „generieren“ zu lassen.

Nachdem wir keine Lust mehr haben, unzählige HTML-Tabellen zu verschachteln, verwenden wir jetzt Inky v2. Ein einfacher Aufbau eines Containers mit einer Zeile und Spalte sieht in Inky etwa so aus:

<container>   <row>      <columns>Put content in me!</columns>   </row></container>

Um Inky auch mit PHP nutzen zu können, haben wir uns auf die Suche nach einer PHP-Implementierung begeben und sind mit dem inky-premailer fündig geworden. Dieser kombiniert die Inky-Templating-Language mit einem CSS-Inliner, welcher alle Styles einer übergebenen CSS-Datei in Inline-Styles umwandelt. Die Installation erfolgt einfach über Composer.

EmailUtility

Wir verwalten den Versand unserer Mails über eine eigene EmailUtility, welche z.B. in einer projektspezifischen Erweiterung eingesetzt werden kann. Getestet wurde mit Typo3 Version 7.6.18. Die Utility schaut im Grundaufbau wie folg aus:

namespace Varioous\VaMail\Utility; use Dreamvention\InkyPremailer\InkyPremailer; class EmailUtility {   ...   public static function sendEmail(array $recipient, $subject, $text) {      $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');      $configurationManager = $objectManager->get('TYPO3\\CMS\Extbase\\Configuration\\ConfigurationManager');      $emailView = $objectManager->get('TYPO3\\CMS\\Fluid\\View\\StandaloneView');       // get template path      $extbaseFrameworkConfiguration = $configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, 'VaMailtest', 'TxVaMailtest');       // set template      $emailView->setTemplateRootPaths($extbaseFrameworkConfiguration['view']['templateRootPaths']);      $emailView->setLayoutRootPaths($extbaseFrameworkConfiguration['view']['layoutRootPaths']);      $emailView->setPartialRootPaths($extbaseFrameworkConfiguration['view']['partialRootPaths']);      $emailView->setTemplate("Email/MailTemplate");             // set template variables      $mailTextDataVariable = array(         'mail_text' => $text,         'mail_subject' => $subject      );      $emailView->assignMultiple($mailTextDataVariable);             // get the rendered fluid template code      $emailBodyRendered = $emailView->render();             // to use german umlauts      $subject = '=?utf-8?B?' . base64_encode($subject) . '?=';       // set up the mail message      $message = $objectManager->get('TYPO3\\CMS\\Core\\Mail\\MailMessage');      $message->setTo($recipient)         ->setFrom(array($extbaseFrameworkConfiguration['settings']['mailSenderAddress'] => $extbaseFrameworkConfiguration['settings']['mailSenderName']))         ->setSubject($subject);             // new inky-premailer instance      $inkyPremailer = new InkyPremailer();       // get contents of style sheet      $styles = file_get_contents(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('va_mailtest') . 'Resources/Private/Templates/Email/css/app.css'));             // render the template with inky and parse the styles inline      $emailBody = $inkyPremailer->render(htmlspecialchars_decode($emailBodyRendered), array(), $styles);       // set html and send      $message->addPart($emailBody, 'text/html');      $message->send();       return $message->isSent();   }   ...}

Wir benutzen hier eine StandaloneView (nähere Infos in den Links unten), holen uns unser E-Mail-Template, setzen die benötigten Variablen. Dies ist hier zum einen der Mail-Text (HTML-Code) und zum anderen noch der Betreff der Mail, den wir ebenfalls übergeben. Danach rendern wir das Template, um den fertig generierten HTML-Code unseres Fluid-Templates zu erhalten. Näheres hierzu folgt noch. Erst nachdem der komplette Code zurückgeliefert wurde, befreien wir den Kraken ;-)

In Zeile 35 lesen wir unsere CSS-Datei ein und übergeben diese, gemeinsam mit dem fertigen HTML-Code, an den inky-premailer in Zeile 37. Den nun doppelt gerenderten HTML-Code (Fluid, Inky) setzen wir nur mehr und senden die Mail raus – et voilà.

Fluid-Template

Wie oben schon erwähnt, sind wir noch das Fluid-Template schuldig. Hier bauen wir den gesamten HTML-Code, welcher per Mail verschickt werden soll, auf:

{namespace ce=TYPO3\CMS\FluidStyledContent\ViewHelpers}{namespace v=FluidTYPO3\Vhs\ViewHelpers}<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de"><head>   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   <meta name="viewport" content="width=device-width" />   <!-- <style> -->   <style>      @font-face {         font-family: 'test-font';         font-style: normal;         font-weight: 400;         src: local('test-font'),         local('Test Font'),         url("https://absoluter/pfad/zur/font.woff2") format("woff2"),         url("https://absoluter/pfad/zur/font.woff") format("woff"),         url("https://absoluter/pfad/zur/font.ttf") format("truetype");         mso-font-alt: 'Arial';      }      @media only screen and (max-width:630px){         .small-float-center{            margin:0 auto!important;            float:none!important;            text-align:center!important         }      }      ...   </style></head><body>   <table class="body">      <tr>         <td class="center" align="center" valign="top">            <center>               <container class="preline">                  <spacer size="4"></spacer>                  <row>                     <columns large="8" small="6">                        <p class="text-left">{mail_subject}<</p>                     </columns>                     <columns large="4" small="6">                        <p class="text-right"><f:format.date format="d.m.Y">now</f:format.date></p>                     </columns>                  </row>                  <spacer size="4"></spacer>               </container>               <container class="content">                  <spacer size="60"></spacer>                  <row>                     <columns>                        <div><f:format.html>{mail_text}</f:format.html></div>                     </columns>                  </row>                  <spacer size="60"></spacer>               </container>               ...            </center>         </td>      </tr>   </table></body></html>

Auf der Foundation Website lassen sich E-Mail-Templates runter laden. Wir benutzen hier den Grundaufbau eines Templates und haben ihn entsprechend unserer Bedürfnisse umgebaut. Zusätzlich zu der in der Utility angegeben CSS-Datei setzen wir hier im head-Bereich noch weitere Stylings.

Zum Beispiel binden wir hier eine Font ein. Diese werden online gehostet. Auf campaignmonitor.com sehen wir, welche Clients die Einbindung von Fonts ermöglichen. Für MS Outlook verwenden wir zusätzlich noch eine Angabe mso-font-alt, damit hier nicht auf die Standard-Font Times New Roman zurückgegriffen wird.

Media-Queries können vom CSS-Inliner nicht verarbeitet und als Inline-Styles in das Template gerendert werden, daher geben wir diese auch hier im head Bereich an. Wie die Media-Queries aussehen, das seht ihr in den Template-Vorlagen von Foundation.

Und so kann ein fertiges Ergebnis aussehen:

Mailversand mit Inky und TYPO3