A template of the emails you can send using this method

Sending Out An Email When a Post is Published

| 5 Comments

On a recent project, I had created an order tracking system using custom post types, and I needed a way to send out an email to the representative once the order was entered into the system, so that they could then track the order and check for updates at their leisure.

In order to do this, I knew that I needed to hook into the publish_posts action and use the wp_mail function, but I didn’t know quite how to do it, so admittedly I needed a little help from this great article by Smashing Magazine, but I got there in the end. And this is what I came up with.

Firstly, I wanted my emails to be HTML emails, rather than just plain text, so I needed to change that. You can use the change_mail_type filter to do this:

// SET EMAIL TYPE TO HTML

function change_mail_type() {
	return "text/html";
}

add_filter ("wp_mail_content_type", "change_mail_type");

Then I wanted to customize the From name and the From address that the emails generated by WordPress would come from. By default, the From name is WordPress and the From address is wordpress@yourdomain.com, which really didn’t suit this highly customized site. So I used the following function to change it:

// SET EMAIL FROM ADDRESS

function change_mail_from() {
	return "me@mycompany.com";
}

add_filter ("wp_mail_from", "change_mail_from");


// SET EMAIL FROM NAME

function change_from_name() {
	return "My Company, Inc.";
}

add_filter ("wp_mail_from_name", "change_from_name");

Sending out the emails at the right time

Then it was time to write the function that would actually send the email every time an order was created. In my system, I had created a new custom post type called hbos_orders, which is where all the order information was entered, so I needed to make it so that every time a new order was posted, an email was sent to its assigned representative (which I set as the post author).

I wanted to make sure that emails weren’t sent out when a new post or page was published: you can make sure of this by using the action hook for a particular custom post type. For example, publish_posts is the standard action hook for when posts are published (and publish_pages for pages), but if you are using a custom post type, then the action hook becomes publish_custom_post_type (or publish_hbos_orders in this case).

Getting everything needed for wp_mail

wp_mail requires three arguments:

  1. Who the message is going to
  2. What the email subject is
  3. And the content of the message

I’ve already mentioned that I wanted the email to go to the post author, so I retrieved that information with the following snippet:

$post = get_post($post_id);
$author = get_userdata($post->post_author);
$author_email = $author->user_email;

The subject of the email didn’t need to be dynamic (thought it certainly could have been), so I just used:

$email_subject = "New order created for you at My Company";

Then, using an output buffer, I compiled the simple HTML email using the following template. Notice that it pulls in a few of the order details using both the_title and get_post_meta:

ob_start(); ?>

<html>
	<head>
		
	</head>
	<body>
		<p>
			Hi <?php echo $author->user_firstname; ?>,
		</p>
		<p>
			We have created a new order for you in our online tracking system.
		</p>
		<p>
			<strong>Order details:</strong><br />
			Order number: <?php the_title(); ?><br/>
			Authorization number: <?php echo get_post_meta( $post->ID, 'order_auth_number', true ); ?>
		</p>
		<p>
			Log in and <a href="<?php echo get_permalink($post->ID) ?>">track this order</a>.
		</p>
		<p>
			Regards,<br />
			My Company, Inc.
		</p>
	</body>
</html>

<?php

$message = ob_get_contents();

ob_end_clean();

I now have everything I need to use the wp_mail function and send out an email every time an order is created. When I put it all together, I have the following plugin:

<?php

// SET EMAIL TYPE TO HTML

function change_mail_type() {
	return "text/html";
}

add_filter ("change_mail_type", "my_awesome_mail_content_type");


// SET EMAIL FROM ADDRESS

function change_mail_from() {
	return "mw@mycompany.com";
}

add_filter ("wp_mail_from", "change_mail_from");


// SET EMAIL FROM NAME

function change_from_name() {
	return "My Company, Inc.";
}

add_filter ("wp_mail_from_name", "change_from_name");


// SEND EMAIL ONCE ORDER IS CREATED

function notify_rep_new_order($post_id) {
	$post = get_post($post_id);
	$author = get_userdata($post->post_author);
	$author_email = $author->user_email;
	$email_subject = "New order created for you at My Company, Inc.";

	ob_start(); ?>

	<html>
		<head>
			
		</head>
		<body>
			<p>
				Hi <?php echo $author->user_firstname?>,
			</p>
			<p>
				We have created a new order for you in our online tracking system.
			</p>
			<p>
				<strong>Order details:</strong><br />
				Order number: <?php the_title(); ?><br/>
				Authorization number: <?php echo get_post_meta( $post->ID, 'order_auth_number', true ); ?>
			</p>
			<p>
				Log in and <a href="<?php echo get_permalink($post->ID) ?>">track this order</a>.
			</p>
			<p>
				Regards,<br />
				My Company, Inc.
			</p>
		</body>
	</html>

	<?php

	$message = ob_get_contents();

	ob_end_clean();

	wp_mail( $author_email, $email_subject, $message );
}

add_action( 'publish_hbos_orders', 'notify_rep_new_order' );

As you can see in the last four lines of code, I used the wp_mail function to send the email using the data I had already gathered and then I make that function happen every time an hbos_orders post is published by using the publish_hbos_orders hook.

The possibilities with using these simple functions are really quite endless, so it's a good place to start if you're wanting to learn about coding WordPress plugins.

What kind of application did you use this in?

Categories: Code & Snippets | Permalink

What next?

Hire me

If you couldn't quite manage this yourself, find it too intimidating, or just don't have the time to do it, you can always hire Dave to do it. Please get in touch so that we can discuss your needs.

Leave a comment

If you have a question, update, or comment about the tutorial, please leave a comment. I try and respond to every comment, though it may take a few days, so please check back soon.

Keep your site backed up, updated & secure

I provide a service called The WP Butler, which helps you stay on top of the maintenance of your WordPress site. Instead of worrying about whether your site is secure, updated and backed up, The WP Butler handles all that for you on a regular basis, so that you can focus on doing what you do best. If you use coupon DIWW, you'll save 15% on our already-low-prices for all maintenance plans.

Author: Dave Clements

Dave Clements has been building websites for close to a decade and in 2010, he formalised that by starting his own company, The UK Edge. He now works on a variety of web projects, from simple tasks like installing a new WordPress site, to consulting on problems, or redesigning his clients' sites. He also runs Do It With WordPress, a site dedicated to providing free tutorials on WordPress. When he's not building your new website, you can find Dave eating Wheat Thins, spending time with friends and family, watching Indie films, fostering kittens from the local Humane Society, listening to some dubstep, dance and electronic rock, and exploring the world.

5 Comments

  1. Hey Dave,

    Great post. I used it as the starting point for a site where people select a category of posts they are interested in. Then when a new post is created in that category all members who have selected that category get an email notification.

    Your post was a great help in creating that.

  2. Hi Dave, excellent post!

    Question about how visible these posts are? Is it safe to assume that not everyone can see those orders? So if it is only showing in the backend, how have you hidden them from the frontend?

Leave a Reply