Install and use Swift Mailer in Drupal 8 (part 2 : implementation)

In previous article we explained how we installed the Swift Mailer module and its dependencies.

In this second part, let's see how we configure and implement it to use in our modules to send formated HTML mail with attachment.

First you will need to have Mail system module installed already. There is no particular issue or difficulty here.

 

1) Configure Swift Mailer

 

In Swift Mailer configuration (/admin/config/swiftmailer/transport) , we select the following options:

Transport:

Messages:

 

2) Custom module with email attachment

 

In our ERP application, we have a function that handles sharing of stored or online generated document via email.

In this function "mail_attachment()", we have an option to use Swift Mailer when available as module to handle the attachment.

Basically, the function handles the parameters received and prepare them for sending using a twig template.

The parameters used are: a list of email addreses, the uri of the file to attach, a text message and some option data (I.e. site name or logo). The part that is important here is the attachment preparation:

 

            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $attachments = new stdClass();
            $attachments->uri = '/path/to/file';
            $attachments->filename = 'file name';
            $attachments->filemime = finfo_file($finfo, $file);
            $params['files'][] = $attachments;

 

Once we have compiled and formatted all information necessary for our email, we call the Drupal service to send our message with attachment:

 

            Drupal::service('plugin.manager.mail')->mail(
                        'ek_admin',
                        'attachment',
                        name@example.com,
                        \Drupal::languageManager()->getDefaultLanguage(),
                        $params,
                        $currentuserMail,
                        TRUE
             );

 

In this piece of code we notice:

  • The name of the module used ('ek_admin');
  • The name of the key to identify the mail template used ('attachment').

 

In the above referred module, we have a hook_mail() function that handle the message based on the selected key:

 

          function ek_admin_mail($key, &$message, $params) {
              switch($key) {
                  case 'attachment':
                  $message['subject'] = $params['subject'];
                  $message['body'][] = $params['body'];
                  $message['options'] = $params['options'];
                  $message['files'][] = $params['files'];
        
                  break;
              }
          }

 

The above parameters are important to build the message template.

 

3) The twig template

 

The template name format will follow this structure: swiftmailer--[module name]--[key].html.twig

We the create the file swiftmailer--ek_admin--attachment.html following the obove parameters that we used in our module, being the module name and the key.

This twig template can be designed as required with normal html tags to be sent as html mail. Here is a simplified example:

 

          <table width="800px" cellpadding="0" cellspacing="0">
                  <tbody>
                      <tr>
                         <td style='font-size:1.2em;padding:20px;vertical-align: bottom;'>{{ message.options.site }}</td>
                         <td ><img class="img-responsive" style="width:130px;float:right;" src="{{ message.options.logo }}" />
                         </td>
                     </tr>
                </tbody>
         </table>
         <hr/>
          <p>{{ 'Document'|t }} : {{ message.options.filename }}</p>
          <p>{{ 'Document size'|t }} : {{ message.options.size }}</p>

 

Important: the trick here here is that the template has to be copied in the template folder of the theme used which may be a current limitation to the module. In our example, we use bartik theme:

 

4) Configure Mail System

 

In the Mail System configuration (), we select Swift Mailer as default mail handling system and keep the theme as current:

 

 

Now in custom configurations, we tell Mail Systems about our module and key described above and to use Swift Mailer when they are called:

 

 

After saving the configuration, we have our module and key registered:

 

 

5) Send a file

 

For simple example, we will take a file from a project page and email it to a user

 

 

And the result is the email received as follow, according to our Swift Mailer template:

 

 

Feel free to add your comments or own experience with Html email with Drupal 8.

Thank you.

Comments

Submitted byToni (not verified) on Thu, 08/04/2016 - 18:17

Please i'm new to drupal. i want to know the files to put the code above.
Thanks

Submitted byArrea Systems on Thu, 08/04/2016 - 19:34

In reply to by Toni (not verified)

mail_attachment() can be included in main module file , i.e. MyModule.module.

Same goes with function MyModule_mail() (hook_mail function, in our case called ek_admin_mail() ).

Twig template goes under templates folder.

 

tree

 

 

 

 

 

 

 

 

 

Submitted byfeatherbelly (not verified) on Fri, 12/16/2016 - 07:47

Add the following around $params['body'] in hook_mail:-

$message['body'][] = check_markup(nl2br($params['body']), 'full_html');

Submitted bymr.mosquito (not verified) on Wed, 02/01/2017 - 06:38

Hello,

I've followed the steps of your tutorial, thank you for putting it together it has been very helpful. Unfortunately, the twig template I've created for the module is not being used when rendering out the email. Drupal 8 is completely ignoring it even though i've named it following the naming convention they provide in their example http://cgit.drupalcode.org/swiftmailer/tree/templates/swiftmailer.html.twig file.

My module name is MyMsgLogger.module and the twig template I've created is named swiftmailer--MyMsgLogger.html.twig and it never gets called while rendering the email that is sent.

If i then create a swiftmailer.html.twig file template and send an email it renders out using this twig template.

Why would the twig template with my module name not render? Is there something I'm missing? I've cleared cache (drush cr) and even restarted the web server figuring something was caught in the cache but it still doesn't work with my module.

Any suggestions would be greatly appreciated.

cheers,

mosquito

I sure did, I've tried the following names:
swiftmailer--mymsglogger.html.twig
swiftmailer--mymsglogger--mymsgkey.html.twig

yet it still falls back to using the swiftmailer.html.twig template. I also tried clearing all of my caches as well and it still only loads the swiftmailer.html.twig template.

When I rename the swiftmailer.html.twig to swiftmailer.xhtml.twig it then throws a WSOD with a message "Unable to find template "themes/my_theme/templates/mail/swiftmailer.html.twig" in the Drupal theme registry."

Is there any additional steps or config files i need to update with this new twig template name?

Looking at your description, everything seems correct.

Last thing you could verify is hook_mail and ensure it is looking for the right key;

I.e.

function MyMsgLogger_mail($key, &$message, $params) {
              switch($key) {
                  case 'mymsgkey': ....

 

and that swiftmailer formatter configuration for this key is selected accordingly in mailsystem:

mailsystem

 

Everything is configured properly. I even went back through and rebuilt the module to make sure I didn't miss any steps and the result is still the same.

At this point I'm now trying to identify where within either the swiftmailer module or core php code it determines the name of the rendering template to use to see if maybe I've overlooked some other setting or configuration.

thank you for your help.

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.