I want to render twig when sending email (if it is possible) or include a template.

My code is like so:

 * Implements hook_mail().
function reg_email_mail($key, &$message, $params) {
  $options = array(
    'langcode' => $message['langcode'],

  switch ($key) {
    case 'new_user':
      $message['from'] = \Drupal::config('system.site')->get('mail');
      $message['subject'] = t('User created: @title', array('@title' => $params['title']), $options);
      $message['body'][] = \Drupal\Core\Mail\MailFormatHelper::htmlToText($params['message']);

I'd like to change $params['message'] or part of this with twig. Is it possible?

  • You do not have to set FROM value. If it is empty the site mail will be used automatically. – user21641 Dec 12 '15 at 12:02
$body_data = [
  '#theme' => 'something',
  '#somearg1' => 'somevalue1',
  '#somearg2' => 'somevalue2',
$body_content = \Drupal::service('renderer')->render($body_data);
$message['body'] = explode("\n", $body_content);
|improve this answer|||||
  • with <h1>foo</h1> I received ========foo===== – monkeyUser Dec 14 '15 at 14:13
  • I guess you will need something like drupal.org/project/mimemail for d8 or maybe try to alter the headers and declare that yo uare sending html and not plain text. – user21641 Dec 14 '15 at 14:53
  • I tried to change $message['headers']['Content-Type'] = "Content-Type: text/html; charset=utf-8"; but I have the same problem – monkeyUser Dec 14 '15 at 15:29
  • See cgit.drupalcode.org/mimemail/tree/mimemail.inc#n376 – user21641 Dec 14 '15 at 18:10

It's possible, but if you want to keep the HTML output from Twig, you need to use a mail plugin that doesn't replace the HTML tags with other strings, or implement it and let Drupal use that plugin instead of the default one.

The code you are showing already replaces HTML tags with other strings, since it's calling \Drupal\Core\Mail\MailFormatHelper::htmlToText(), which as you see, replaces HTML tags with other strings. That is also the reason why you see ======== instead of <hi> and </h1>.
Even if you would remove that method call, the default implementation of the mail plugin uses the following code, in PhpMail::format().

  // Join the body array into one string.
  $message['body'] = implode("\n\n", $message['body']);

  // Convert any HTML to plain-text.
  $message['body'] = MailFormatHelper::htmlToText($message['body']);
  // Wrap the mail body for sending.
  $message['body'] = MailFormatHelper::wrapMail($message['body']); 

It doesn't check the headers set for the email message; it always converts HTML to plain text.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.