I'm using wp_mail() to send an HTML email. But there's quite a lot of HTML code in the email, so rather than including all the code in my wp_mail() function, is it possible to have the code in a separate template and just include this template in the function? Here is what I have:

<?php if ( isset( $_POST['submitted'] )) {
   add_filter('wp_mail_content_type',create_function('', 'return "text/html"; '));
   $emailTo = '[email protected]' ;
   $subject = 'This is the subject';
   $body = get_template_part( 'includes/my_email_template' );
   $headers = 'From: My Name' . "\r\n";
   wp_mail($emailTo, $subject, $body, $headers);

I'd like to be able to put all of my HTML code in 'my_email_template' but when I try this, no email is sent. Am I including the template incorrectly? Thanks in advance for any answers.

  • 1
    Syntax error: $emailTo = [email protected] ; try $emailTo = '[email protected]';.
    – fuxia
    Commented Apr 18, 2013 at 19:42
  • You're calling the template incorrectly - see the codex for get_template_part
    – vancoder
    Commented Apr 18, 2013 at 19:44
  • Thank you both. That syntax error was just poor copy/paste/adjust from me. I can confirm it's correct in my actual template.
    – Xav
    Commented Apr 18, 2013 at 19:53
  • @vancoder I'm not even sure I should be doing get_template_path. The file only contains HTML and a few variables I have set in the file that calls it. Maybe include (TEMPLATEPATH . 'includes/my_email_template.php'); is the correct option?
    – Xav
    Commented Apr 18, 2013 at 19:58
  • Does your template file return a string? If you just include it any HTML or echos will just print to the screen rather than get assigned to $body. I imagine that will cause some errors with wp_mail as well.
    – s_ha_dum
    Commented Apr 18, 2013 at 20:29

3 Answers 3


Per my comment to your question, I believe the problem is that includeing files, whether directly or using get_template_part isn't likely to give you a string to pass to $body and that is going to cause errors in the code, or at the very least unespected behavior.

I would avoid reading files into memory and just create a function that returns your $body content.

function get_email_body_wpse_96357() {
    $body = '<p>Hi</p>';
    return $body;

Then use $body = get_email_body_wpse_96357(); as needed. An advantage of this method is that you can easily pass parameters to the function if you ever decide to do so. You could also use variables in an included file but it can be messy.

If you don't want to load that function all the time, then put it in a file by itself and include that file only when you need the function.


Here is the sample code for using output buffering. You will be able to access all the variables inside the template which are defined above "include line".

WordPress: Include template in the email.

include(get_stylesheet_directory() . '/assets/email-templates/booking-details-template.php');
$email_content = ob_get_contents();
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail($to_email, "Booking details", $email_content, $headers);
  • 1
    This is the easiest way to manage customize wp_mail by far Commented Dec 8, 2019 at 7:22
  • 1
    Used this as well to get the default Woocommerce email header & footer on my custom email sending function by replacing the include line with a do_action of woocommerce_email_header. Thanks!
    – Suika
    Commented Mar 9, 2020 at 1:33

The function get_template_part() doesn't return the HTML but echo it (it uses locate_template() which loads the file - echo).

You can either turn output buffering on using ob_start() and put the buffer in to your variable or you can use file_get_contents().

On your case I think the best solution is this:

$body = file_get_contents(TEMPLATEPATH . 'includes/my_email_template.php');
  • Thanks for your answer ItayXD but I now have it working using the answer above
    – Xav
    Commented Apr 18, 2013 at 21:37
  • 1
    I saw, the answer above is a far inferior IMO. The file_get_contents is exactly what you were looking for, and it is far easier to right html file normally than use the above solution. In fact I just can't see how is it any better, I can see only the down side.
    – ItayXD
    Commented Apr 18, 2013 at 21:43
  • This is cleaner and easier. Much more MVC by having the logic in functions.php and template in its own file.
    – rebellion
    Commented Aug 24, 2014 at 17:48
  • 1
    How to pass the variables to templates?
    – mpsbhat
    Commented Jun 4, 2016 at 1:29
  • 1
    I've seen passing variables done by using str_ireplace as in str_ireplace('[username]',$user_login, $message_template); -- is this ideal/best practice? - From this link: avtex.com/blog/2012/03/14/…
    – ejntaylor
    Commented Dec 30, 2016 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.