Hi is there an action which can be performed while a post is moved to trash .... I tried delete_post and deleted_post. It works but twice for each action ( before and after the action as written in codex ) and the output is shown only when the post is deleted from trash. Example i want to send an email to the author stating that his post has been moved to trash because of some reason, and update some user_meta. if i use

add_action('deleted_post', 'emailUser');


add_action('delete_post', 'emailUser');

it works only when the post is deleted from trash . . .

Update : got it to work for trash posts using

add_action('trash_post', 'emailUser');

but the problem for double execution of function is still there. . .

  • 1
    Write the solution below and mark it as answer
    – Ashfame
    Commented Feb 28, 2011 at 10:59
  • its not the proper answer as the double execution of function is still there... Commented Feb 28, 2011 at 11:01

3 Answers 3


This will do the trick!

function my_trash_post_function($post_id){
        // do stuff

Here we add the function, and to prevent the hook from executing more than once using did_action:


As always, these kinds of hooks take the form {post_status}_{post_type}, so trash_post, trash_page, trash_customposttype, publish_page etc


That action will be called once when the post is moved to the trash, and then again when the trash is emptied.

Your function could check for the presence of an option with the post ID in the name, if the option is not there then it sends the email and then sets the option. If the option is there (e.g. it's being called a second time) you would not send the email.

Remember then to delete the option, so your database doesn't fill up with them!

add_action( 'delete_post', 'emailUser' );

function emailUser( $postid ) {

   if ( ! get_option( 'user_emailed_' . $postid ) ) {
      // send email here
      update_option( 'user_emailed_' . $postid, 'anything' );
   } else {
      delete_option( 'user_emailed_' . $postid );


Let me know if that works!

  • 1
    you can use the Transients API instead of options so you won't need to worry about deleting options from the database codex.wordpress.org/Transients_API
    – Bainternet
    Commented Feb 28, 2011 at 13:25
  • Thanks Simon that works great . . . . dont't know how n why i missed this . . .. Commented Mar 1, 2011 at 5:43
  • Bainternet, i saw the transients and they are pretty similar to get_option in my case and i wud stick with get_option for the delete thing too as the execution would depend on the server performance too and calculation of the code execution time before and after the deletion of post might get difficult. Commented Mar 1, 2011 at 5:57
  • 1
    There's no need at all to start adding/editing option fields or transients, adding extra queries. Instead just call did_action to check if the hook has fired already.
    – Tom J Nowell
    Commented Mar 5, 2012 at 10:50
add_action('trash_post', 'trash_post_function_name');

The above hook didn't work for me in WP 4.7.5.

This is what worked for me

add_action('wp_trash_post', 'trash_post_function_name');

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.