Using WP Better Emails with WooCommerce Email Templates

On one site that I run there are several different functions, primarily provided by disparate plugins with custom actions/filters, that send emails both to site administrators and customers. For most emails that are sent from WordPress itself and several of the plugins, the content type is set to plain/text allowing me to use WP Better Emails to wrap content in an easily edited header and footer. WooCommerce on the other hand proved to be a little more tricky – there is the option to send emails via plain/text, but they definitely lack valuable formatting when displaying order information to a customer. This is further compounded if you insert any custom HTML into the content.

Conceptually all that needs to be done is to first remove the WooCommerce email header and footer, and second have WP Better Emails process it even though it has a content type of text/html. After checking out the code for both of the plugins in question, I devised a way to make it work.

Remove WooCommerce Email Headers and Footers

If you view the source of any of the WooCommerce email templates (at least the default ones) you will see a line for <?php do_action( 'woocommerce_email_header', $email_heading ); ?> and <?php do_action( 'woocommerce_email_footer' ); ?> which are the hooks that WooCommerce itself uses to insert the header and footer contents. By setting our own functions to these hooks earlier and later than the WooCommerce priorities, we can capture all of the content and hide it with ob_start() and ob_get_clean() to capture and clean the output buffer contents. We are also setting a filter to return true any time the woocommerce_email_header action is run.

Common sense says that we could just unhook all functions from these actions, however in my testing I found that some other, non-UI, logic was being performed in some of the attached functions. This method allows the code to run, but prevents the output from being inserted into the generated email.

Apply WP Better Emails Template

Next we need to apply the email template that WP Better Emails did not, because the content type was wrong – text/html and not text/plain. This is actually a good thing because we also want to avoid some of the formatting that WP Better Emails applies to the typical plain text email content. We can do this using the global $wp_better_emails and hooking into phpmailer_init after most of the work has been done – priority 20 works fine.

This example uses anonymous function which require PHP 5.3+, however you could also use create_function().

// Determine if it's an email using the WooCommerce email header
add_action( 'woocommerce_email_header', function(){ add_filter( "better_wc_email", "__return_true" ); } );

// Hide the WooCommerce Email header and footer
add_action( 'woocommerce_email_header', function(){ ob_start(); }, 1 );
add_action( 'woocommerce_email_header', function(){ ob_get_clean(); }, 100 );
add_action( 'woocommerce_email_footer', function(){ ob_start(); }, 1 );
add_action( 'woocommerce_email_footer', function(){ ob_get_clean(); }, 100 );

// Selectively apply WPBE template if it's a WooCommerce email
add_action( 'phpmailer_init', 'better_phpmailer_init', 20 );
function better_phpmailer_init( $phpmailer ){
	// this filter will return true if the woocommerce_email_header action has run
	if ( apply_filters( 'better_wc_email', false ) ){
		global $wp_better_emails;

		// Add template to message
		$phpmailer->Body = $wp_better_emails->set_email_template( $phpmailer->Body );

		// Replace variables in email
		$phpmailer->Body = apply_filters( 'wpbe_html_body', $wp_better_emails->template_vars_replacement( $phpmailer->Body ) );


Your WP Better Emails templates should now be applied to your WooCommerce emails.

You may also like...

5 Responses

  1. Nello says:

    Hey Justin,

    thank you for sharing this guide with us! I know that this is kinda old, but i’ve been using your solution till today, when I had to switch from WP Better Emails to WP HTML Mail cause of my new SMTP setup (made with postman).

    Your solution still works with this new plugin, but there’s something weird about woocommerce emails: it’s like paragraphs inside them can’t be 100% wide. This leads them to be cut with some “” tags and the result is an email where most of the text is on the left side of the body.

    Could you help me out with this weird situation?
    Thank you in advance!

    • Nello says:

      inside “” there’s a br tag. I assume i’m able to post html here, so it doesn’t show up

      • User Avatar Justin Silver says:

        Hi Nello,

        I don’t have time to look into WP HTML Mail right now, but my guess is that there is some CSS that is messing with the WooCommerce layout. If you can get to a “preview” or figure out how to just view the email in a browser you should be able to inspect the DOM to see what is throwing it off.

        Good luck!

  2. Audrius says:

    Thanks! Works well with Woocommerce. One small problem remains for my website. After removing email header, email body is not anymore UTF-8 encoded. I tried adding to WP Better Email template but it did not solve my problem. Any ideas?

    • User Avatar Justin Silver says:

      Are the contents no longer UTF-8 encoded or is it just missing the Content-Type meta value? WooCommerce includes the following line in the of the email templates, which gets stripped out by the code in this post. On my site I edited the HTML of the WPBE template to include the same header, but we also don’t require any encoding so I don’t know for sure that it works…

      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >;

Leave a Reply

Your email address will not be published. Required fields are marked *