The title of this particular article is somewhat misleading as it has nothing to do with sending an email upon creating a new post in WordPress, but actually whenever the HTTP `POST` action has occurred.

Additionally, the methodology describing below isn’t relegated to just sending emails – it can be used when any data needs to be managed upon a `POST` request. This includes sending emails, serializing data to the database, evaluating information to be presented on the next page view, or whatever else.

Of course, one of the best ways to actually demonstrate how to do something is to give some practical example, so for all intents and possible, I’m going to show how to structure a project using the event-driven model of WordPress to send an email upon a `POST` request.

Send Data on POST

Before actually showing any code, the motivation for this whole post comes from the fact that I have seen – and written – code that doesn’t necessarily jive well with the way WordPress handles its events.

That is to say that the code works and it does what it’s supposed to, but it’s not clean, and there is not a separation of concerns as far as the logic is concerned. Remember: since WordPress is event-driven, we can hook into certain points of the WordPress lifecycle to make something happen.

Finally, note that this is how I generally picture organizing code in WordPress:

WordPress Code Organization

Functions call into WordPress and provide data for templates to render.

Note that templates serve as views that either call into `functions.php` or that render data that has been managed by functions that are hooked into events in `functions.php`.

How Not To Do It

So let’s say you want to send a custom email whenever a person fills out a form on a custom page template that you’ve created. For example, let’s say that the page is going to `POST` back to itself and then display a message whenever the process has completed.

Okay, so here’s one way to go about actually structuring a page template to send an email whenever the page posts to itself:

<?php get_header(); ?>
<?php my_theme_send_email(); ?>

	<div id="content">
		<form method="post" action="">
			<!-- TODO -->
			<input type="submit" name="submit" value="Send Email" />
			<input type="hidden" name="email-submission" value="1" />
		</form>
	</div><!-- /#content -->

<?php get_footer(); ?>

And then in `functions.php` you may have something like this:

function my_theme_send_email() {

	if ( isset( $_POST['email-submission'] ) && '1' == $_POST['email-submission'] ) {

		// Send the email...

	} // end if

} // end my_theme_send_email

For the most part, the code for sending the email isn’t all that wrong; however, the problem is actually within the page template. Note that right under the `get_header()` call, we’re calling the function `my_theme_send_email()`.

This is one way that I have once written – and seen others write – similar code. And although this works, it’s not really the event-driven way to do things.

Do It With Events

The refactoring for this is actually really simple. Whenever a WordPress-based page loads, it will go down through the normal WordPress page lifecycle which means that we can take advantage of each of the available event that fires as WordPress is loading it’s pages.

To that end, we don’t need to have our page templates call into `functions.php`. Remember: they should primarily be used to display data.

So first, remove the function call in the page template:

<?php get_header(); ?>

	<div id="content">
		<form method="post" action="">
			<!-- TODO -->
			<input type="submit" name="submit" value="Send Email" />
			<input type="hidden" name="email-submission" value="1" />
		</form>
	</div><!-- /#content -->

<?php get_footer(); ?>

Then hook the function for sending the email into an action such as `init` (thanks to the comment by Danny):

function my_theme_send_email() {

	if ( isset( $_POST['email-submission'] ) && '1' == $_POST['email-submission'] ) {

		// Send the email...

	} // end if

} // end my_theme_send_email
add_action( 'init', 'my_theme_send_email' );

Notice that we’ve leaned out the page template, kept the function for sending the email the same, but we’ve hooked it into the `init` action.

This works because if the request is coming from a page other than the template, then the conditional won’t fire. If, however, a `POST` is made from the page template, then the function will fire, the conditional will pass, and then the email will be sent.

It’s All About Structure

The point of sharing all of this isn’t to show how to send an email with WordPress, clearly, nor is it how to build custom page templates.

It’s about how to properly structure projects and applications to take advantage of the design patterns that WordPress implements.

Share:

Leave a Reply