How should I go about theming the contact form email sent?

I have looked into the Mailsystem and Mime Mail but fail to understand how either of those will help me style the email.

The default e-mail looks like this:
Link to Image

There is no way I can use this horror in an an actual production site. How this thing got through D8 beta is beyond me.

Basically what is making the email such is line 146 in contact.module in /core/modules/contact but I can't very well go and change core files, can I?

Comments

Jeff Burnz’s picture

I want to look into this - can you confirm that you have added custom fields to the contact form? Have you done anything else (such as alter the manage display settings), I just need to know the details so I can reproduce the formatting.

Another thing that might be helpful - attach a text file with the raw source of the email.

gekomees’s picture

You mean this is not normal?

Well, here are my fields:
https://gyazo.com/1c2583c70df08647dfc19e96cf4da0bf
Not sure what qualifies as a custom field though.

I've probably also changed display settings:
https://gyazo.com/264f4b540bd33232b7d3cdbad602a4a4

I've definitely changed altered form display:
https://gyazo.com/2cceac1fb6d54055d277a62d9dd07478

I have some contact form enhancing modules also (you can see it in form display) but the email format was the same even before that.

Here's the source code. I've taken the liberty of erasing the URLs and IP addresses. If this is not what you meant, tell me what I need to post.

Return-path: <henri@artmedia.ee>
Envelope-to: henri@artmedia.ee
Delivery-date: Thu, 02 Jun 2016 16:06:02 +0300
Received: from  ([]: helo=test.lan)
	by delta.alfanet.ee with esmtp (Exim 4.87)
	(envelope-from <henri@artmedia.ee>)
	id 1b8SK2-0006M2-Th
	for henri@artmedia.ee; Thu, 02 Jun 2016 16:06:02 +0300
Received: by test.lan (Postfix, from userid 33)
	id C24645007CD; Thu,  2 Jun 2016 16:06:02 +0300 (EEST)
To: henri@artmedia.ee
Subject: =?UTF-8?B?W1N1dmVrcyB0w7bDtmxlIV0g?=
X-PHP-Originating-Script: 33:PhpMail.php
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed; delsp=yes
Content-Transfer-Encoding: 8Bit
X-Mailer: Drupal
Sender: henri@artmedia.ee
From: Olerex <henri@artmedia.ee>
Reply-to: henri@artmedia.ee
Message-Id: <20160602130602.C24645007CD@test.lan>
Date: Thu,  2 Jun 2016 16:06:02 +0300 (EEST)

admin (http://) sent a message using the
contact form at http://.

Eesnimi
                 henri












       Perekonnanimi
                 lindepuu












       Vanus
                 123












       Telefon
                 123












       E-mail
                 henri@artmedia.ee












       Ametikoht
                 Klienditeenindaja












       Soovitav meeskond
                 Tallinn Harkujärve












       CV faili kujul (.doc, .docx või .pdf)





invoice-483.pdf [1]
















       Kinnitan esitatud andmete tõele vastavust.
                 Kinnitan esitatud andmete tõele vastavust.












       Sõbra nimi
                 123












       Sõbra e-mail aadress
                 13

[1]
http://

Jeff Burnz’s picture

I really want to see the file, basically I want to know if the horizontal new lines are newline chars (probably be just blank lines), I'm not sure if the input format (used here in this forum comments) are converting those to paragraph tags.

No idea if this is "normal" or not, I'm just interested in learning how this all works in D8.

gekomees’s picture

Well, it's just plaintext, so there really are no paragraph tags.

Kodiak’s picture

I have exactly the same issue, here is the mail :
http://files.guillaumeboit.fr/mail.txt

Jeff Burnz’s picture

Good to know, hopefully I'll have some time to look at this later today, cheers.

j29’s picture

I was just curious if anyone had come to any further conclusions on this issue. From everything that I've read, I get the impression that Drupal 8 is treating the contact form module as the answer to all front end, anonymous user forms, instead of the webforms module. My question would be, is this a correct impression?

If this is the case, what is the correct procedure for formatting the email message? Because with the way it is now, any form that has more than a couple extra fields really gets a very long email response. Below is what I pulled off of Gmail with just 3 extra test fields. I have a form that has 20+ fields and the client says they're getting 10 page emails as a response. And by the way, I tested this on a Hotmail account, and Hotmail ignored any HTML and simply returned one line. So 20+ fields would be a nightmare!

If this is NOT the way to handle front end webforms for anonymous users, what is the Drupal 8 way? Thanks for any suggestions!

The sender's name<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; username<br>
<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; The sender's email<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="mailto:email@gmail.com" target="_blank">christopherrowden@gmail.com</a><br>
<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; Subject<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; test subject<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; Message<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Test message<br>
<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; Line 1 test<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Line test 1<br>
<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; Line 2 test<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Line test 2<br>
<br>
<br>
<br>
&nbsp; &nbsp; &nbsp; Line 3 test<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Line test 3<div class="yj6qo"></div><div class="adL"><br>
<br>
owntheweb’s picture

My customer service gurus submitted a ticket for a format change. I would agree that it's not as neat and tidy as Drupal 7 options I'm used to working with or the account-related emails that offer an editing option in configuration settings. I'll dig deeper into this today. Let me know if you know of friendly ways to theme emails resulting from contact forms.

Worlds to explore. Worlds to create.
Blog: http://www.christopherstevens.cc/blog
Twitter: http://www.twitter.com/owntheweb

j29’s picture

I'd be interested to hear if you get any answers!

owntheweb’s picture

I'll post examples and links once/if I get this figured out. I'm seeing lots of clues out there but require a Chipotle burrito first. :D

Worlds to explore. Worlds to create.
Blog: http://www.christopherstevens.cc/blog
Twitter: http://www.twitter.com/owntheweb

owntheweb’s picture

Update: This was moved to Monday. It's hot on my radar.

Worlds to explore. Worlds to create.
Blog: http://www.christopherstevens.cc/blog
Twitter: http://www.twitter.com/owntheweb

Kodiak’s picture

No news, the client's ticket is still sleeping on my side. I believe they could cope... Now I'm back with D7 and it will be a looong time before I come back to D8 :)

Jeff Burnz’s picture

As someone who has used both platforms for some years your comment is akin to being offered the choice between a Ferrari and an old van, and choosing the van because it was easier to change the tyre...

Kodiak’s picture

Exactly my point!

Kosmoseistis’s picture

Is there somebody here that did find a solution on this.

My client is not happy with a email that is more than 1 mile long :-/
So really looking for a good solution.

gekomees’s picture

What I currently do is use the YAML Form module. It has proper email handlers. Sadly it was not available when I first posted this topic.

Kosmoseistis’s picture

Thanks Gekomees for your quick reply and solution!! Can you tell me if this module can work on the existing webforms? Because the website has already 4 long webforms... or will I have to recreate all those forms with the new module?

gekomees’s picture

Most likely you'll have to recreate them. YAML form has been updated since I used it but I don't think form importing has been implemented.

j29’s picture

Getting here a bit late, but just wanted to mention how I handled it.

Knowing that the goal was to collect the data and not really caring about the email, my solution was to use a module by the name of Contact Storage Export (which requires Contact Storage). Regardless of however poorly the email was formatted, this module allowed me to collect the data submitted in an exported .csv file. It ended up being exactly what my client was looking for.

So now, the email merely serves as a reminder to download a submitted form. Not a big deal when there's only 4 fields. Bigger deal when there were 70+. All in all, I know I'm perhaps stretching the intended use of the default forms, but for me it gets the job done. Hope this helps!

paultreny’s picture

I ended up just assembling a custom body in a hook_mail_alter() in a helper module, which lets me control exactly what it looks like (as long as you're happy with a plain text email)

/**
 * implements hook_mail_alter()
 * @author Paul Reny
 * Custom format the contact us form, otherwise it's full of nbsp terribleness
 */
function YOUR_MODULE_NAME_mail_alter(&$message) {
  // only alter contact forms
  if (!empty($message['id']) && $message['id'] == 'contact_page_mail') {

    // further restrict mail_alter to machine name of a particular contact form, in this example "contact_us"
    if ($message['params']['contact_form']->id() == 'contact_us') {

      // make it a bit neater to access fields
      $contact_message = $message['params']['contact_message'];

      // reset body
      $message['body'] = [];

      // create simply plain text body for the email
      // you could assemble your body text however you like (from field values, etc)
      $new_body = 'Name:' . PHP_EOL . $contact_message->get('field_name')->value  . PHP_EOL . PHP_EOL .
                 'Email:' . PHP_EOL . $contact_message->get('field_email')->value . PHP_EOL . PHP_EOL .
               'Subject:' . PHP_EOL . $contact_message->get('subject')->value     . PHP_EOL . PHP_EOL .
               'Message:' . PHP_EOL . $contact_message->get('message')->value     . PHP_EOL;

      // add plain text body string into the $message['body'] array
      $message['body'][] = $new_body;
    }
  }
}
kenpeter’s picture

Yes, I think that is the best simple solution. It seems very hard to theme an email template.

heger245’s picture

I needed this to be more dynamic with custom added fields, so i improved it a bit if someone is interested:

/**
 * implements hook_mail_alter()
 * @author Paul Reny
 * @author Christoph Heger
 * Custom format the contact us form, otherwise it's full of nbsp terribleness
 */
function YOUR_MODULE_NAME__mail_alter(&$message) {
    // only alter contact forms
    if (!empty($message['id']) && $message['id'] == 'contact_page_mail') {

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

        $message['body'] = [];

        $fields = $contact_message->getFields();
        $new_body = t('There is a new submission from ' . $contact_message->getContactForm()
                ->toUrl()
                ->toString() . PHP_EOL . PHP_EOL);
        $new_body .= 'Name:' . PHP_EOL . $contact_message->get('name')->value . PHP_EOL . PHP_EOL;
        $new_body .= 'E-Mail:' . PHP_EOL . $contact_message->get('mail')->value . PHP_EOL . PHP_EOL;
        $new_body .= 'Message:' . PHP_EOL . $contact_message->get('message')->value . PHP_EOL . PHP_EOL;

        foreach ($fields as $field_name => $field) {
            if (get_class($field->getFieldDefinition()) == 'Drupal\field\Entity\FieldConfig') {
                $new_body .= $field->getFieldDefinition()->label() . ':' . PHP_EOL .
                    $contact_message->get($field_name)->value . PHP_EOL . PHP_EOL;
            }
        }
        $message['body'][] = $new_body;
    }
}
d.fisher’s picture

Just dropping a comment now so I can come back later with my findings, once I've discussed with colleagues here.

chasep01’s picture

"I ended up just assembling a custom body in a hook_mail_alter() in a helper module" What does that mean exactly? I'm not very familiar with it. Do I need to create a custom file? Where do I place it?

Thanks!

saurabhpatil21’s picture

Hello All,

I have added upload file field in contact form. I can fetch all other fields using,

$contact_message = $message['params']['contact_message'];
$fields = $contact_message->getFields();
foreach ($fields as $field_name => $field) {
$new_body .= $field->getFieldDefinition()->label()." ".
$contact_message->get($field_name)->getString() . PHP_EOL . PHP_EOL;
}

But for file field it giving me some number. Please help me out to show file URL in email.

Thanks.

nno’s picture

Thank you paultreny and heger245.

I've tweaked above code a bit to get links to uploaded files. Not sure if this is best approach but it works for my use case.

function YOUR_MODULE_NAME_mail_alter(&$message) {
  // only alter contact forms
  if (!empty($message['id']) && $message['id'] == 'contact_page_mail') {

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

    $message['body'] = [];

    $fields = $contact_message->getFields();
    $new_body = t('There is a new submission from ' . $contact_message->getContactForm()
            ->toUrl()
            ->toString() . PHP_EOL . PHP_EOL);
    $new_body .= 'Name:' . PHP_EOL . $contact_message->get('name')->value . PHP_EOL . PHP_EOL;
    $new_body .= 'E-Mail:' . PHP_EOL . $contact_message->get('mail')->value . PHP_EOL . PHP_EOL;
    $new_body .= 'Message:' . PHP_EOL . $contact_message->get('message')->value . PHP_EOL . PHP_EOL;

    foreach ($fields as $field_name => $field) {
        if (get_class($field->getFieldDefinition()) == 'Drupal\field\Entity\FieldConfig') {

            $new_body .= $field->getFieldDefinition()->label() . ':' . PHP_EOL;

            if (isset($contact_message->get($field_name)->entity->uri->value)) {
              $uri = $contact_message->get($field_name)->entity->uri->value;
              $url = file_create_url($uri);
              $new_body .=  $url . PHP_EOL . PHP_EOL;

            } else {
              $new_body .= $contact_message->get($field_name)->value . PHP_EOL . PHP_EOL;
            }

        }
    }

    $message['body'][] = $new_body;

  }
}
ferrete’s picture

Thx ! Works fine with me. ;)

aurora.luzzardi’s picture

Hi, are your fields comming in the right order?

Because I need to do basically what you did, but the fields are all out of order based on the Manage Display Weight.

Kind regards,

André

nno’s picture

Hi André,

with above code you will have Name, Email, then all the other fields. Haven't tried but I guess you could order fields with custom display for Token view mode.

aurora.luzzardi’s picture

Sorry, I didn't understand the display for Token view mode, could you gave me an example?

nno’s picture

"Custom display settings" under Manage display.

labboy0276’s picture

I also stumbled across this module Contact Emails which allows a lot of customization to the email body and subject via tokens, etc.  Works great from the couple times I have used it.

John Ouellet
Sales Engineering Manager
https://thinktandem.io/

karoldt’s picture

This module is what i needed to solve the problem stated in the top!

Thank you very much!