I recently needed to send a create a form that would send an html email with a PDF attachement. Due to some project constraints, using a service like MailChimp (which I do love oh so much) was out of the question, so I had to work a little magic of my own. Let’s go on a little journey, shall we?

Email: code like it’s 1999

Email is still an anomly when it comes to web standards, where the old school way of doing thing still reigns. Be not afraid, however, because are a few tools that make things quite a bit easier.

For starters: HTML Boilerplate

There are a lot of quirks in email markup, and the HTML Email Boilerplate does a great job of setting things up. You get tweaks for the various mail cients, a style reset, and a very basic markup template.

The good stuff: your design

Enjoy implementing your snazzy design here, but be sure to stay within the recommended 550-650px width (Mailchimp recommends 600px, so i’d say that’s a safe bet).

Feel free to write you styles in the <style></style> to make things easier as you design. We’ll use Premailer later on to move them inline.

Images can be hosted on your website, a CDN, or you can attach them to the email with PHPmailer.

Finishing things off: Premailer

Now that we have our beautiful template all tabled up and ready, we want to make sure it plays nicely with as many email clients as possible. The best way that i’ve found is to use Premailer. Premailer will take your lovely html template, work some magic on it, and give you a leaner, friendler version that even picky clients like outlook (and, suprisingly, gmail) will love.

Save the premailer formatted html to a file in your project directory (we’ll need to reference it in our PHP script later on).

Let’s Send this puppy!

We are so close, but… now we actually have to send the thing. Easier said than done.

MIMEs are a pain

The first hurdle is getting the proper MIME headers for the various elements of our email. We could just use PHP’s built in mail() and write our own MIME headers for all the content (which supposes that you know enough to write your own MIME headers – I don’t), but let’s take a look at how much fun that is:

1
2
$body .="Content-Type: text/html; charset=\"iso-8859-1\"";
$body .= "Content-Transfer-Encoding: 8bit";

Now imagine having to set that for your attachments (which you need to open and encode properly), the html email file, and the plain text version of your email. If you get things wrong, it’s up to you to figure out the esoteric error messages of mail() and various email clients. Whooo… no thanks. That’s why we’ll use PHPmailer to do it for us.

PHPMailer to the rescue

PHPMailer is an apache extra that takes a lot of the confusion out of sending emails. Just download it to your project directory, include it in your PHP file and follow the tutorial here or modify my script below:

require_once(includes/phpmail.class) // or wherever you put phpmail.class

body = file_get_contents('email/htmlemail.html'); // include our formatted email

$mail->AltBody = "To view this message please use an HTML compatible email viewer, or visit http://mysite.com/emailcampaign"; // give folks who can't read HTML email something to read
$mail->SetFrom($email,$name);
$address = $email;
$mail->AddAddress($address, $name);
$mail->Subject = "Subject";
$mail->MsgHTML($body);
$mail->addAttachment("email/attachment.pdf"); // just repeat this for multiple attachments

// send statement, followed by error reporting (comment out for production)
if(!$mail->Send()) {
  echo "Mailer Error: " . $mail->ErrorInfo; // for testing
} else {
  echo 'Message sent!'; // for testing
}

The end.

And there we have it, a functional workflow for an html email with some killer attachments. It’s not perfect by any means, but it has made things a lot less easier for me. Suggestions for improvement are more than welcome, just shoot me a comment.

Happy Emailing,
Nick