It’s quite common when sending an email message to see the following code to set the message body:
$body = "Hi $firstname $lastname, Thank you for you recent order - reference <strong>$order_id</strong> A secure payment for your order of <strong>£$order_value</strong> was successfully processed. The estimated delivery date is <strong>$order_date</strong>. The Admin";
This is quite messy and mixes html and php, which isn’t ideal – ideally, we’d want a php email template for use across our whole site. Additionally, this code is time consuming to update as you need to manually go back to the raw PHP code if you needed to change the email.
A very simple solution is to use a flat file (.txt file for example, although could be a html or .tpl file) to store the basic email content with placeholders to replace various bits of information that change. For example, part of a template may contain:
Hi {firstname} {lastname},
All the information srrounded by the curley brackets (I’m sure they have a proper name) are the parts of the email that will change. All we need to are pass information to each of these using our very very simple email templating system:
Firstly include the path to your template file. If the file doesn’t exist, stop the script immediately:
$tpl_file = 'tpl/email_tpl.txt'; if (!file_exists($tpl_file)) { die('Template file not found!'); exit; }
Next, get the message body. This will the contents of our template file – we simply use PHP’s file_get_contents function to get the contents of email_tpl.txt into a variable called $msg_tmpl:
$msg_tmpl = file_get_contents($tpl_file);
The contents of ’email_tpl.txt’ are as follows:
Hi {firstname} {lastname}, Thank you for you recent order - reference <strong>{order_id}</strong> A secure payment for your order of <strong>£{order_value}</strong> was successfully processed. The estimated delivery date is <strong>{ship_date}</strong>. The Admin
Below, we are simply using a familiar function, str_replace, a slightly different way. Here we are passing the function two arrays. In the sample below we are saying replace all occurances of code surrounded by a curley brackets with dynamic data. For example, where ‘{order_id} is found in the file, this will be replaced by ‘873545’. The $msg variable is now our replaced text and we simply echo this out:
$arr_tpl_vars = array('{firstname}','{lastname}','{order_id}','{order_value}', '{ship_date}'); $arr_tpl_data = array('yada', 'smeg', '873545', '235.45', date('d/m/Y')); $msg = str_replace($arr_tpl_vars, $arr_tpl_data, $msg_tmpl); echo nl2br($e_msg);
For the dat array being passed to the template, $arr_tpl_data, I’ve manually set an array of sample information. In reality, you’d generate this from your database.
The full PHP code:
$tpl_file = 'tpl/gemail_tpl.txt'; if (!file_exists($tpl_file)) { die('Template file not found!'); exit; } $msg_tmpl = file_get_contents($tpl_file); $arr_tpl_vars = array('{firstname}','{lastname}','{order_id}','{order_value}', '{ship_date}'); $arr_tpl_data = array('yada', 'smeg', '873545', '235.45', date('d/m/Y')); $msg = str_replace($arr_tpl_vars, $arr_tpl_data, $msg_tmpl); echo nl2br($msg); //You'd now send an email .....
So, what has been achieved here?
- Our PHP code for the email page is a lot cleaner
- PHP and HTML are not mixed (follows the MVC pattern)
- Updating email templates are now very easy – E.g. a mear designer could change the email content 🙂
- You can fecth the contents of the file and edit it from a CMS. As a nice extra feature to your CMS you could allow certain users to update the contens of emails directly from a webpage. However, you need to do some checking to ensure only validate tags are used.
- The email can be used in multiple places and when sending multiple emails
That’s it, thanks for reading!
Wait a second, isn’t this EXACTLY why one would use a templating system like Smarty – it means would wouldn’t have to write your own and all the work is coded for you!!!!
Yes you’re right 🙂
I’m well aware something like Smarty (which just for the record annoys the crap out of me) is made for. For something as simple of using placeholders in an email Smarty would be total overkill.
However, I personally feel something as large as Smarty isn’t right for all projects and you’ve missed the point of my article a little.
The point of the article was to demonstrate a method that could be used in any sized site to allow for greater flexibility. For instance, I’ve just finished working on a user system that sends out emails automatically using CRON jobs.There are 9 different types of emails all with different content to send depends of a set of business rules.
The site owner can change the content of the email himself via editing a simple text file with several placeholders I have defined for him, via the administration area. My PHP code is also a lot neater, as the contents of the emails are fetched from text files (one line of PHP code). My code now contains several if statements to decide what text file to include, as opposed to a huge wall of html within my code, which would be messy.
Also, you can use the idea I introduced in this article to improve your own systems. For example, I’ve just updated our CMS system at work to use a few short tags – things requested by a lot of clients. For instance, adding *GALLERY-587} to the text editor will add a nice sliding gallery to the page content. Adding {LATEST-NEWS-ASIDES} will list the last 5 added news headlines. What does this mean? Well it means clients can more easily control the content of thier sites, without asking me 🙂
Nice article, very helpful, thanks 😀
thank you, thats exactly what i was looking for!
This is absolutely amazing – and simple to boot. I’m working on a project that uses Postmark to send email but need a way to separate the PHP from the HTML. Nothing worse than having business logic mixed in with presentation code. There are going to be about 20 transactional emails and I need anyone to be able to hop in and edit the emails. Perfect solution, thank you so much for sharing.
It’s very useful, great for beginners or/and small projects.
Yer I guess. I’d recommend anyone use something like Twig nowadays 🙂
In your examples sometimes you show
$msg = str_replace
and other times
$e_msg = str_replace
You should be consistent for future readers! I figured it out pretty quick. BTW i love your code and implemented it into a class on my website with ease.
I found an excellent starter template here: http://leemunroe.github.io/responsive-html-email-template/email.html
And i fixed the e-mail button to work in outlook using this (padding based button) here:
https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design