38

i try to hook when post is updated but all hook i try never executed except updated_post_meta

add_action('updated_post_meta', 'my_function');

function my_function($post_id) {    
    echo 'This is my post ID : '.$post_id;
}

I've tried this add_action('save_post', 'my_function'); but no id was echo out, or maybe this message already echo but never renders because of redirect header is sent.

3
  • 2
    you have a space after save_post, is that a typo here, or was that in your original code? also, enable debugging while developing.
    – Milo
    Commented Feb 14, 2014 at 16:31
  • @Milo sorry typo, but not in original code
    – rusly
    Commented Feb 14, 2014 at 16:38
  • if that's the case, then you should see your output in the top left corner of the screen when creating a new post. saving an existing post happens before a redirect, so you won't see anything unless you have debugging enabled.
    – Milo
    Commented Feb 14, 2014 at 16:42

2 Answers 2

102

When a post is updated there are some hooks that are fired:

  • 'pre_post_update' is an action fired just before the post is updated, the argument passed are 2: $post_ID and $data that is an array of all the other database colums of the post table
  • 'transition_post_status' is an hook fired on update, and pass 3 arguments: $new_post_status, $old_post_status and $post (object).
  • Then, there are other 2 transition hooks fired, but they are dynamic named, it means that the effective action fired depends on the old and the new post status. "{$old_status}_to_{$new_status}" and "{$new_status}_{$post->post_type}". First pass the only the post object as argument, the second pass the post id and the post object. Find documentation here.
  • 'edit_post' that pass 2 arguments: $post_ID and $post (object)
  • 'post_updated' that pass 3 arguments: $post_ID, $post_after (post object after the update), $post_before (post object before the update)
  • Another dynamic hook: "save_post_{$post->post_type}" that depends on post type, e.g. for standard posts is 'save_post_post' and for pages is 'save_post_page', this hook pass 3 arguments: $post_ID, $post (object) and $update that is a boolean (true or false) that is true when you perform an update, in fact this hook is fired also when a post is saved for first time.
  • 'save_post' that is fired both on update and on first saving, and pass the same 3 arguments of the previous hook.
  • 'save_post_{$post_type}' that is fired both on update and on first saving, and pass the same first 2 arguments of the previous hook.
  • Finally you have 'wp_insert_post', that is fired both on update and on first saving, and pass the same 3 arguments of the previous 2 hooks.

These hook are fired every time a post is updated, both via admin pages in backend and via when updated "manually" using wp_update_post or wp_insert_post functions.

When the post is updated using admin pages there are additional hooks fired, an example is 'update_post_redirect' or 'post_updated_messages'. (See this and this WPSE answers for usage examples).

Note that if you want make use of some hooks argument, that isn't the first, one you have to explicitly declare it in add_action call.

E.g. if you want to use the '$update' argument (that is the 3rd) of the 'save_post' hook you need to add 3 as $accepted_args param on add_action (see docs):

// if you don't add 3 as as 4th argument, this will not work as expected
add_action( 'save_post', 'my_save_post_function', 10, 3 );

function my_save_post_function( $post_ID, $post, $update ) {
  $msg = 'Is this un update? ';
  $msg .= $update ? 'Yes.' : 'No.';
  wp_die( $msg );
}

Last note regard timing: you must be sure that add_action is called before the action is triggered, or it will do nothing.

E.g. this code:

wp_update_post( $post );
add_action( 'save_post', 'my_function', 10, 3 );

will do nothing, because the action is added after the hook is fired. Here is simple to recognize it, in real world code isn't always so.

3
  • I think that the 'save_post' action hook is also fired when hitting Add New (Post, Page, CPT) in the dashboard. To see yourself just run this code. function save_post_test( $post_id, $post, $update ) { print ' post_id : '; var_export( $post_id ); print ' post : '; var_export( $post ); print ' update : '; var_export( $update ); wp_die( 'save_post hook runs when you click Add New..' ); } add_action( 'save_post', 'save_post_test', 10, 3 ); Why does the 'save_post' action run on Add New instead of on Publish? To make the auto-draft post I suppose.
    – lowtechsun
    Commented Nov 12, 2018 at 17:52
  • @lowtechsun Like it is said in the A, the hooks are fired every time a post is updated, i.e. saved in DB. When you hit "Add New", close to page loading, WP creates a draft post stored in DB so he hooks are fired.
    – gmazzap
    Commented Nov 13, 2018 at 9:14
  • Thank you for getting back to me. Just found out about this yesterday and thought the concept of this is confusing. Meaning first I open the page to add a new post. At this stage I thought I have not already created a post. Only once I hit Publish I would think the new post is created. Taking this further I hope WP does delete the auto-draft post if I hit Add New but then leave the page without hitting Publish?
    – lowtechsun
    Commented Nov 13, 2018 at 9:18
3

Why not hook in post_updated_messages. That way you can show this message just like the default wordpress post updated.

add_filter('post_updated_messages', 'your_message');

function your_message(){
}

Look for an example here:

http://codex.wordpress.org/Function_Reference/register_post_type

under post_updated_messages

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.