Use meta_input and tax_input with wp_insert_post() & wp_update_post()

Authored by

We were recently in a situation in a project where we wanted to rebuild/invalidate a cache when a particular post was updated. Some of the key data for the post is stored in postmeta. So we have code that looks like:

$id = wp_insert_post( wp_slash( array(
    'post_title' => 'foo',
) ) );
/* ... */
update_postmeta( $id, 'bar', wp_slash( $bar ) );
update_postmeta( $id, 'baz', wp_slash( $baz ) );
wp_set_object_terms( $id, $tags, 'post_tag' );

The problem here is that we can’t reliably use the save_post action to flush the cache because all of the data is not yet written to the database since this action is fired in wp_insert_post(). In other words, the post writing was not atomic, so we had to an additional ad hoc action like do_action( 'acme_after_update_postmeta', $id ) and hook into that action to flush the cache.

I should have been using this already, but it turns out that all of these update_postmeta() and wp_set_object_terms() calls can be made by wp_insert_post() (and wp_update_post()) by using the meta_input and tax_input args:

@type array $tax_input  Array of taxonomy terms keyed by their taxonomy name. Default empty.
@type array $meta_input Array of post meta values keyed by their post meta key. Default empty.

So the above can be re-written as:

wp_insert_post( wp_slash( array(
    'post_title' => 'foo',
    'meta_input' => array(
        'bar' => $bar,
        'baz' => $baz,
    ),
    'tax_input' => array(
        'post_tag' => $tags,
    ),
) ) );

With this “atomic” call, we can then listen for a single save_post action and be assured that all of the required postmeta will be available.

Not that I am explicitly using wp_slash() in the examples here as a reminder that these functions expect slashed data, aggravatingly (for backwards compatibility since PHP a long time ago used to espouse the use of “magic quotes”).

2 thoughts on “Use meta_input and tax_input with wp_insert_post() & wp_update_post()”

  1. If I remember correctly then using the tax_input works only if it’s being run from a logged-in session. It doesn’t work in CRON tasks, for example.

  2. Nice! I didn’t know about meta_input, very handy. That was just added in 4.4, another nice addition. Kaspars comment tax_input not working without a logged-in session is a bummer but good to know. I tested it and realized the tax_input logic makes a call to current_user_can, which explains it.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.