Our code base has a ton of logic that executes as the post is inserted/created. However, some of that logic depends on custom post meta. The only way I know of to add post meta to a new post is like so:

$post_id = wp_insert_post($post_obj);
add_post_meta($post_id, 'key', "value");

However, this means that the post meta is not present when hooks on post insertion happen.

Is there any way to set up or include post meta as part of $post_obj?

I tried making up new properties of the post object with $post_obj->custom_key = 'value' but it didn't seem to actually end up in the database. The only thing I can think of is to hijack an existing property of the post object that I'm not using, like menu_order, and store some information there. That's an ugly hack.

2 Answers 2


You can hook your function to the wp_insert_post action hook:

add_action( 'wp_insert_post', 'wpse128767_add_meta' );
function wpse128767_add_meta( $post_id ) {
    add_post_meta( $post_id, 'key', 'value' );

To make sure your metadata has been added before any other insert hooks run, give it a higher priority:

add_action( 'wp_insert_post', 'wpse128767_add_meta', 1 );

By default add_action() uses a priority of 10; the lower the number, the earlier it runs.

  • The problem is that the post meta needs to be added conditionally, not every time we add a post. wp_insert_post() is being triggered from a dashboard widget, and in that case we need this metadata. When wp_insert_post() is called normally from other places, we don't want that metadata. Is there any way to sort of pass logic to an action like wpse128767_add_meta?
    – tobek
    Commented Jan 6, 2014 at 21:56
  • 1
    Hmm. Is there anything in the existing post data to indicate that the source of the insert is the dashboard widget? It might be helpful if you could edit your question to include the relevant code from the widget.
    – Pat J
    Commented Jan 6, 2014 at 22:13
  • Nevermind, this is the correct answer. The key, of course, is to not call add_action() in functions.php or some other globally loaded file, but only call it from the same piece of code that needs this functionality. For a moment I was thinking that add_action() would somehow save it globally and be called on every wp_insert_post action in our entire WordPress installation, which of course is not how it works.
    – tobek
    Commented Jan 7, 2014 at 19:20

Here is a solution.

//Your args to Gather post data.
$args = array(
    'post_title'    => 'My post',
    'post_content'  => 'This is my post.',
    'post_status'   => 'publish',
    'post_author'   => 1,

//Retrieve Id back after new post is made.
$post_id = wp_insert_post( $args, true );

//Check for errors, before updating meta fields
 if (is_wp_error($post_id)):
        $errors = $post_id->get_error_messages();
        foreach ($errors as $error):
            //log errors
            echo $error;

   //If updating WP meta
   update_post_meta( $post_id, meta_key1, 'add this');
   update_post_meta( $post_id, meta_key2, 'add something');

   //if updating ACF meta
   //update_field( 'meta_key1', 'add this', $post_id );
   //update_field( 'meta_key2', 'add something', $post_id );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.