I have a custom module with a controller where I'm building a PDF file with a node's data that will be mailed to a certain user.

I have installed the SwiftMailer module and I have been able to produce my desired outcome, but it isn't very clean.

I was wondering if I could use a twig template to build the body of my HTML email. Is there anyway I can make use of Drupal's Twig Extension for this purpose?

I already created a email.html.twig file with the layout I need and I already have a $parameters array with all the variables I need to use in the template, but as SwiftMailer uses an HTML string in the setBody() method, I'm trying to use Twig to produce the HTML I need to use there. Any thoughts?

Please note that I don't want to use the twig template in my module ( to show a Drupal page or something), but rather have Twig render an HTML string I can use with SwiftMailer. Also, the instructions for the SwiftMailer module regarding theming are rather confusing for me and they are for Drupal 7, so I don't see how I can make use of them in my case.

Any help would be very welcome!


Sure, that's possible. It works exactly as if you would render something for the page.

After preparing your render array like you always do, all you need to do is call the renderPlain() method of the renderer service, that gives you a string (Actually, a Markup object containing a string).

contact_mail() does exactly that, the relevant part:

$build = entity_view($contact_message, 'mail');
$message['body'][] = \Drupal::service('renderer')->renderPlain($build);

PS: The fact it is a Markup object is important, do not try to cast it to a string.

  • I added a #theme key to the build array to use a custom twig theme for the body. Although my outgoing mail has the content-type "text/html", the body part seems to be handled as plain text, because html tags are removed.How do I get around this? Aug 17 '16 at 8:29
  • I am also having this same exact issue. No matter what I do, I can't get the body to render as HTML. The template works fine, but the actual body variable doesn't render as HTML, just plain text with the markup rendered as plain text. Aug 7 '17 at 22:01
  • use Drupal\Core\Render\Markup; and then Markup::create($body) in order to give the method what it wanted which is instanceof MarkupInterface Aug 7 '17 at 23:10

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.