Why does save_post action fire when creating a new post?

I’m surprised by the fact that my function that I’ve tacked onto the save_post action fires when I click the “New Post” link in the Admin Dashboard. Note – this is before I’ve pressed Save or Update, and it fires immediately, not after an elapsed time or auto-update.

On the other hand, when I then type in something and press the Publish or Update or Save Draft buttons, the echo statement I’ve put inside my action handler does not echo out, so it appears that the action is NOT firing at any other time. This may be unrelated.

Here’s my code:

add_action('save_post', 'MyNS\save_event_metabox', 10, 2);
function save_event_metabox($post_id, $post){
  echo "<h1>YES!</h1>";
}

This YES echoes (at the top of the page) when I press the “New Post” link but does NOT echo when I type something and then press Update or Publish or Save Draft. This seems to contradict the documentation on the save_post action and the wp_insert_post() function.

Can anyone clear this up for me?

1

When you click ‘New Post’, you’re simply loading the page wp-admin/post-new.php.

In doing so, WordPress will always create a new post (an ‘Auto Draft’) to ensure all other features (such as media uploads) and plugins work as normal, even before you actually save a draft or publish the post.

And this, in turn, triggers save_post. Hence your echo.

Okay, so why don’t I get an echo when updating or publishing?

In between saving and the following page load, WordPress is actually sending a GET redirect back to the same page, which appears transparent (you can witness this with an HTTP monitor, such as HttpFox).

In other words;

  1. You click Update or Publish
  2. Browser sends data to server
  3. WordPress handles it, and in the process triggers save_post
  4. WordPress sends back a redirection header, and exits, before any browser output occurs (including your echo)*
  5. Browser follows redirection and loads ‘edit post’ page.

The redirect might seem unnecessary (since you could just POST to the same page), but it’s part of a technique known as Post/Redirect/Get in avoiding duplicate form submissions.

If you’re attempting to print out custom messages based on a result of a function hooked to save_post, check out these questions/answers.

*Not strictly true, your echo will in fact occur before the redirect header is sent, but the browser will either discard it, or things happen so quickly it never renders.

Leave a Comment