Silverstripe EmogrifiedEmail Module
I have been using Silverstripe's newsletter module for years now, and it works well. It includes the ability to use templates, which is great. Use an HTML template, however, and complications arise. The problem is that Silverstripe is built around using HTML and CSS, whereas CSS support in email clients varies wildly.
Given the patchy CSS support, the safest solution is to embed the CSS style codes directly into the HTML tags themselves. Doing this manually is rather tedious. Fortunately, Pelago developed an emogrifier PHP class, and the Silverstripe newsletter-pagesource module, integrates it into Silverstripe. However, the newsletter-pagesource module only applies to newsletters generated from a website page, whereas I was looking for something more generic. Hence the EmogrifiedEmail module was created.
Overview
The EmogrifiedEmail class takes the HTML code being sent, and uses the emogrifier to embed CSS code contained in both external files and style tags directly into the HTML tags. It heavily borrows code from the Silverstripe newsletter-pagesource module, and a little on Mark Guinn's ProcessedEmail class. The following enhancements were added to the original (newsletter-pagesource) code:
- Updated to the latest emogrifier code;
- Turn relative URLs in the CSS code (e.g., background image URLs) to absolute URLs;
- Deletes the unneeded CSS links and style tags from the HTML header; and
- Fixed the final fallback option in the tidy() function so that it wouldn't add additional special characters to the HTML code.
NOTE: This was written on 13 December 2011. The newsletter-pagesource module may have been updated since then.
Installation
The source-code can be found on github at: https://github.com/hdrlab/Silverstripe-EmogrifiedEmail. It can be checked out using Git, or downloaded as a zip file. The module simply needs to be copied into your Silverstripe installation as per any other module and, after rebuilding (using http://yoursite/dev/build), it will be ready for use.
Due to the way that the Email class is designed, it was not possible to seamlessly integrate EmogrifiedEmail into the system without modifying other source-files. So, you will have to change any class that uses or extends the Email class, to use or extend EmogrifiedEmail instead. See how this is done with the newsletter module below. Also take note of a change to Silverstripe's HTTP class, which currently (as at 13 December 2011) is missing handling of list-style-image elements.
Integrating with the Newsletter Module
As said above, there was no 100% clean method of integrating EmogrifiedEmail into the system, so a few source-code adjustments are needed in order to get the newsletter module working with the EmogrifiedEmail module. There is only one essential change: open "code/email/NewsletterEmail.php", and replace the following line (line 8):
class NewsletterEmail extends Email {
with this:
class NewsletterEmail extends EmogrifiedEmail {
That's it; emails sent will now be emogrified. Those using Git can use this patch to make the change.
There is one problem though; if you preview a newsletter, the preview will use the original HTML code. If you wish to see the final email as it will be sent (ignoring the dynamic fields, of-course), then open up "code/NewsletterAdmin.php", and replace the following line (line 175):
return HTTP::absoluteURLs($email->getData()->renderWith($templateName));
with:
$email->setTemplate($templateName);
$email->debug();
return $email->Body();
This code is a bit of a hack, but $email->debug() triggers the emogrification process without sending an email. Once again, those using Git can apply this simple change using this patch.
HTTP Class Patch
This isn't actually needed but the HTTP class' absoluteURLs() (okay, urlRewriter()) function currently (as at 13 December 2011) doesn't handle list-style-image elements. This is described in bug ticket #6798, which includes the necessary patch.
It's a simple patch, which requires adding the following after line 64 in urlRewriter():
$regExps[] = '/(list-style-image:[^;]*url *\()([^)]+)(\))/ie';
Just in case the source-code has changed since writing this, line 64 looks like:
$regExps[] = '/(background:[^;]*url *\()([^)]+)(\))/ie';
Git users can patch their own code using this patch file.
Final Notes
Ideally this functionality would be integrated into Silverstipe's own Email class. In the meantime, this module works nicely. You may find that it doesn't convert all CSS code perfectly. This is a limitation of the emogrifier class. However, it shouldn't take much to adjust the CSS code to get what you want.
Projects » Silverstripe/PHP Projects » Silverstripe EmogrifiedEmail Module