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, 2015 at 12:02

2 Answers 2

$body_data = [
  '#theme' => 'something',
  '#somearg1' => 'somevalue1',
  '#somearg2' => 'somevalue2',
$body_content = \Drupal::service('renderer')->render($body_data);
$message['body'] = explode("\n", $body_content);
  • with <h1>foo</h1> I received ========foo=====
    – monkeyUser
    Dec 14, 2015 at 14:13
  • 1
    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, 2015 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, 2015 at 15:29
  • See cgit.drupalcode.org/mimemail/tree/mimemail.inc#n376
    – user21641
    Dec 14, 2015 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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