钩子文档

transition_post_status

💡 云策文档标注

概述

transition_post_status 是一个 WordPress Hook,在文章状态发生变化时触发。但需注意,它也会在文章更新但状态未改变时触发,因此使用时需要谨慎处理。

关键要点

  • 触发时机:当文章从一个状态转换到另一个状态时触发,但也会在状态未改变的文章更新时触发。
  • 参数:$new_status(新状态字符串)、$old_status(旧状态字符串)、$post(WP_Post 对象)。
  • 相关函数:wp_transition_post_status() 用于处理状态转换相关的动作。
  • 版本历史:自 WordPress 2.3.0 引入。

代码示例

/**
 * 仅在文章状态实际转换时执行操作。
 *
 * @param string  $new_status 新文章状态。
 * @param string  $old_status 旧文章状态。
 * @param WP_Post $post       文章对象。
 */
function wpdocs_run_on_transition_only( $new_status, $old_status, $post ) {
    if ( $old_status == $new_status )
        return;

    // 执行操作
}
add_action( 'transition_post_status', 'wpdocs_run_on_transition_only', 10, 3 );

注意事项

  • Hook 名称具有误导性:它不仅触发于状态转换,也触发于状态未改变的文章更新。
  • 使用匿名函数需谨慎:在 add_action() 或 add_filter() 中使用匿名函数可能导致代码难以移除,影响插件或主题的维护性。
  • 状态类型:包括 publish、future、draft、pending、private 等,插件可能引入新状态。
  • 替代 Hook:可使用 {$old_status}_to_{$new_status} 格式的 Hook 来针对特定状态转换,例如 draft_to_publish。

📄 原文内容

Fires when a post is transitioned from one status to another.

Parameters

$new_statusstring
New post status.
$old_statusstring
Old post status.
$postWP_Post
Post object.

Source

do_action( 'transition_post_status', $new_status, $old_status, $post );

Changelog

Version Description
2.3.0 Introduced.

User Contributed Notes

  1. Skip to note 6 content

    Please note that the name transition_post_status is misleading. The hook does not only fire on a post status transition but also when a post is updated while the status is not changed from one to another at all.

    So if you wish to really only do stuff on status transition and not on regular post updates, you will need to (at least) start with a basic bailout like this:

    /**
     * Do stuff only when posts are actually transitioned from one status to another.
     *
     * @param string  $new_status New post status.
     * @param string  $old_status Old post status.
     * @param WP_Post $post       Post object.
     */
    function wpdocs_run_on_transition_only( $new_status, $old_status, $post ) {
        if ( $old_status == $new_status )
    		return;
    
    	// do stuff
    }
    add_action( 'transition_post_status', 'wpdocs_run_on_transition_only', 10, 3 );

    For doing stuff when moving in and out (!) of published status only, use

    if ( $old_status == $new_status || $old_status != 'publish' && $new_status != 'publish' )
    	return;
    
    // do stuff

  2. Skip to note 7 content

    Sometimes you only want to fire a callback when a post status is transitioned to ‘publish’, i.e. coming from some other status other than publish (published posts retain the publish status even when updating).

    Only fire a callback when a post status is transitioned to publish

    /**
     * Fire a callback only when my-custom-post-type posts are transitioned to 'publish'.
     *
     * @param string  $new_status New post status.
     * @param string  $old_status Old post status.
     * @param WP_Post $post       Post object.
     */
    function wpdocs_run_on_publish_only( $new_status, $old_status, $post ) {
    	if ( ( 'publish' === $new_status && 'publish' !== $old_status )
    		&& 'my-custom-post-type' === $post->post_type
    	) {
    			// do stuff
    	}
    }
    add_action( 'transition_post_status', 'wpdocs_run_on_publish_only', 10, 3 );

  3. Skip to note 8 content

    Example: Check if someone published a custom post type first time.

    // Check to see if user posted first time.
    add_action( 'transition_post_status', 'some_function', 10, 3 );
    function some_function( $new, $old, $post ) {
        if ( ( $new == 'publish' ) && ( $old != 'publish' ) && ( $post->post_type == 'your_post_type' ) ) {
    		// do stuff
    	} else {
    		return;
    	}
    }

  4. Skip to note 9 content

    If you are looking to hook something on a specific post status change you can also use this hook

    do_action( "{$old_status}_to_{$new_status}", $post );

    This could be used for two specific post status. For example if you are looking to hook something when a draft post is published you can use this hook like this,

     add_action( "draft_to_publish", function( $post ) { //do something here } );

    Of course this opens up a possibility for so many things and you don’t have to keep relying on transition_post_status which runs even when post status are not changed.

  5. Skip to note 10 content

    Status can be one of: publish, future, draft, pending, private