Sending templated emails with CSS and inline images

Mark Sch edited this page Mar 26, 2018 · 5 revisions

For CakePHP 2.x

When sending templated HTML emails, your layout.ctp or template.ctp contains usually a few images. Those you should transform into inline attachments. You should also try to avoid inline CSS for creating templates, as this is hard to maintain. CSS should be transformed into inline CSS upon sending. Both tasks can be done using a helper and its afterLayout() callback via CakeEmail class.

Additionally you can use the helper to transform any absolute non-protocol URLs to ones with http:// added. So clicking the links from emails will actually work, in case you are using snippets that don't automatically make full URLs. I bet there are more use cases of post-processing generated emails prior to actually delivering them.

Actual work

Ideally, you use a helper and its afterLayout callback to finalize/modify the rendered HTML. Something like that:

App::uses('InlineCssLib', 'Tools.Lib');

class EmailProcessingHelper extends AppHelper {

	 * Process Email HTML content after rendering of the email
	 * @param string $layoutFile The layout file that was rendered.
	 * @return void
	public function afterLayout($layoutFile) {
		$content = $this->_View->Blocks->get('content');
		$content = $this->_prepareHtmlContent($content); // Transforming images/urls

		if (!isset($this->InlineCss)) {
			$this->InlineCss = new InlineCssLib();
		$content = trim($this->InlineCss->process($content)); // Transforming CSS

		$this->_View->Blocks->set('content', $content);


Then add your helper to the Email object:

$this->Email->helpers(array_merge($this->helpers, ['EmailProcessing' => ['email' => $this->Email]]));

See detailed article:

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.