Practical WordPress Development

Save Custom Post Meta – Revisited, Refactored, Refined.

About a month ago, I shared a post that discussed the code that’s required to save custom post meta data. Generally speaking, this is a lot of boilerplate that’s required to make sure that the data being saved is permitted and that the author has permissions to do so.

Of course, depending on the nature of your project, the code will vary a little, but for the majority of the cases, it’s all the same.

But thanks to several commenters and contributors, the code has been completely refactored, and I’ve actually been using it in a recent project.

Save Custom Post Meta Data

Save Custom Post Meta Data – Take One!

Clicking on the image above will take you to the original version of the code.

Special thanks to:

For the comments and the contributions.

As it stands now, the final version of the code is as follows:

 * Determines whether or not the current user has the ability to save meta data associated with this post.
 * @param		int		$post_id	The ID of the post being save
 * @param		bool				Whether or not the user has the ability to save this post.
function user_can_save( $post_id, $nonce ) {
    $is_autosave = wp_is_post_autosave( $post_id );
    $is_revision = wp_is_post_revision( $post_id );
    $is_valid_nonce = ( isset( $_POST[ $nonce ] ) && wp_verify_nonce( $_POST[ $nonce ], plugin_basename( __FILE__ ) ) ) ? true : false;
    // Return true if the user is able to save; otherwise, false.
    return ! ( $is_autosave || $is_revision ) && $is_valid_nonce;

} // end user_can_save

Much simpler, huh?

You can check out the updated gist here.

And please, if you happen to see options for further refactoring, then don’t hesitate to comment either here or on the gist!


  1. Justin Sainton

    I suppose if you wanted to simplify even further, you could remove the ternary true : false from the nonce variable, as that is automatically evaluated.

  2. Rafal

    Nice job mate,

    I tried to find an error in your code since the last time I posted here but I ended up failing.

    Just reminding you that I’m still looking for you to make a blunder ;)

    Keep it up,

  3. Jonathan Goldford

    Great function Tom. I’m a little confused why there is no call to current_user_can() within the function. Did you omit it so this could apply more broadly?

    Thanks for posting it.

Leave a Reply

© 2020 Tom McFarlin

Theme by Anders NorenUp ↑