5

I created a custom form (adding some additional fields) using the Contact module from the core of Drupal 8.

When I submit the form is sent an email containing all values, but it is really bad formatted. The email only contains form's values without any field label and it is unreadable.

How can I customize the template of the email sent on the form's submit?


What I already tried

hook_mail_alter

I found some answer about the same problem for Drupal 7 suggesting to implement a custom hook_mail_alter function (for example: 1, 2).

So I created a custom module with my function:

/**
 * Implements hook_mail_alter().
 */
function mymodule_mail_alter(&$message) {

  // Process only 'contact_page_mail' messages
  if ($message['id'] != 'contact_page_mail') {
    return;
  }

  $params = $message['params'];

  // Body
  $message['body'] = [];
  $message['body'][] = t('Some custom message');

  // I don't know what should I do here?
  // How can I access values of all fields in the form?
  // ...

  return;
}

The function is correctly triggered before the email is sent, but I can't access field's values so I'm not able to build a custom email.

Also I can't get the form's id (only a generic 'contact_page_mail' valid on all contact forms) so I'm not able to handle different contact forms in this function.

Swift Mailer

As suggested in this other similar question, I tried with the Swift Mailer module.

After some effort, I'm able to get it working and now I have a swiftmailer.html.twig template file with this content:

<div>

  {{ body }}

</div>

But as for the hook_mail_alter solution, I don't know how to access form's field values so I can't customize the email format.

Moreover, the Swift Mailer module currently is an alpha version (8.x-1.0-alpha1) and the Mailsystem module (required to get things working) is a beta version. So I would like to avoid to install unstable modules on a production website (anyway this can be the last solution, if no other works).


EDIT

Thanks to @Berdir, now within the hook_mail_alter function I can access field values with:

$contactMessage = $message['params']['contact_message'];

// Value of 'field_my_field_name'
$contactMessage->get('field_my_field_name')->getString();

So I can put them inside the $message['body'].

Quite complicated, but it works.

Is there a way to get field values within the Swift Mailer template? I tried with {{ params.contact_message.field_work_with_us_name }} but it doesn't works.

What happen if I have two or more contact forms? The function hook_mail_alter will be triggered on all of them. Is there a way to have a specific function for each contact form?

  • @Berdir I edited my question. The question you pointed out is very similar and I tried to be more specific (showing what I already tried). Also, none of those solutions answer my question. – Andrea May 1 '16 at 8:11
  • 1
    $message['params]['contact_message'] contains the entity. You can also try hook_contact_message_view(), that's similar to hook_node_view() and you should be able to set a custom #theme there and/or alter the formatted fields. – Berdir May 1 '16 at 8:14
  • 1
    Also, if you are using Drupal 8 now, I doubt there is a way around using beta modules at the moment. I'm using both in production for more than a year now. And I maintain mailsystem and plan to do a stable release soon. – Berdir May 1 '16 at 8:15
  • Thank you @Berdir. Please, take a look to my last edit. Do you know if is there a way to have a specific hook_mail_alter function for different contact forms? – Andrea May 1 '16 at 9:30
  • 1
    The bundle() of the message entity is the form – Berdir May 1 '16 at 9:45
2

Putting together an answer based on the comments/discussion there so this can be accepted/closed.

  • General instructions on how to theme a mail can be found in this existing answer: How can I theme the outgoing contact mail?

  • You might want to watch https://www.drupal.org/node/2680731, once resolved, you can rely on that instead of your own custom code to send the mail as HTML.

  • To use a custom template for the inner parts of the mail, you can set a custom template in hook_contact_message_view(). Or use field templates for specific fields.

  • To check for a specific contact form, you can use the bundle() method of the contact message entity, which you can find in $message['params]['contact_message'] in hook_mail_alter(). Make sure you combine this with a check that it is there and an entity object, otherwise you could have fatal errors for other mails.

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