当前浏览:首页 / WordPress钩子 / save_post

do_action( 'save_post', int $post_ID, WP_Post $post, bool $update )

一旦文章被保存就触发

postmore...

save


参数

$post_ID

(int) 文章ID

$post

(WP_Post) Post对象

$update

(bool) 这是否是正在更新的现有文章。


更多信息

save_post是一个在创建或更新文章或页面时触发的动作,可以通过导入、文章/页面编辑表单、xmlrpc或通过电子邮件发布。文章的数据存储在$_POST$_GET或全局$post_data,具体取决于文章的编辑方式。例如,快速编辑使用$_POST

由于此动作在post保存后立即触发,因此可以使用get_post($post_id);轻松访问此post对象。

注意:从WP 3.7开始,引入了一个替代动作,该动作用于特定的文章类型:save_post_{post_type}。挂接此动作可防止不必要地触发回调。

避免无限循环

如果调用包含save_post钩子的函数(如wp_update_post),则钩子函数将创建一个无限循环。为了避免这种情况,在调用所需的函数之前先取消钩住函数,然后再重新钩住它。

// this function makes all posts in the default category private

function set_private_categories($post_id) {
	// If this is a revision, get real post ID
	if ( $parent_id = wp_is_post_revision( $post_id ) ) 
		$post_id = $parent_id;

	// Get default category ID from options
	$defaultcat = get_option( 'default_category' );

	// Check if this post is in default category
	if ( in_category( $defaultcat, $post_id ) ) {
		// unhook this function so it doesn't loop infinitely
		remove_action( 'save_post', 'set_private_categories' );

		// update the post, which calls save_post again
		wp_update_post( array( 'ID' => $post_id, 'post_status' => 'private' ) );

		// re-hook this function
		add_action( 'save_post', 'set_private_categories' );
	}
}
add_action( 'save_post', 'set_private_categories' );


源码

查看源码 官方文档


更新日志

版本描述
1.5.0开始引入

使用示例

  • 示例1

    当使用WordPress 3.7或更高版本时,最好使用save_post_{$post->post_type}钩子,以减少代码,并在创建和更新文章时触发更少的钩子。

  • 示例2

    强制新文章具有特定类别分类项(term),

    add_action( 'save_post', 'set_post_default_category', 10,3 );
    
    function set_post_default_category( $post_id, $post, $update ) {
    	// Only want to set if this is a new post!
    	if ( $update ){
    		return;
    	}
    	
    	// Only set for post_type = post!
    	if ( 'post' !== $post->post_type ) {
    		return;
    	}
    	
    	// Get the default term using the slug, its more portable!
    	$term = get_term_by( 'slug', 'my-custom-term', 'category' );
    
    	wp_set_post_terms( $post_id, $term->term_id, 'category', true );
    }
    
  • 示例3

    下面是一个基本示例,它将在您的网站上每次更新文章或页面时发送电子邮件。

    function my_project_updated_send_email( $post_id ) {
    
    	// If this is just a revision, don't send the email.
    	if ( wp_is_post_revision( $post_id ) ) {
    		return;
            }
    
    	$post_title = get_the_title( $post_id );
    	$post_url = get_permalink( $post_id );
    	$subject = 'A post has been updated';
    
    	$message = "A post has been updated on your website:\n\n";
    	$message .= $post_title . ": " . $post_url;
    
    	// Send email to admin.
    	wp_mail( 'admin@example.com', $subject, $message );
    }
    add_action( 'save_post', 'my_project_updated_send_email' );
    
  • 示例4

    save_post_{post_type}钩子在通用save_post钩之前触发,这意味着save_post将覆盖使用save_post_{post_type}进行的任何meta更新。许多插件,如ACF和Pods,都使用了save-post-action钩子,因此如果您试图更新一个meta字段,并且正在使用这些插件中的一个,则必须使用save_post钩子。

    // does not work
    function my_save_meta_function( $post_id, $post, $update )
    {
    	// fires but can be overridden by plugins, regardless of priority number
    	update_post_meta( $post_id, 'address', '123 Test St' );
    }
    add_action( 'save_post_event', 'my_save_meta_function', 99, 3 );
    
    
    // does work
    function my_save_meta_function( $post_id, $post, $update )
    {
    	if ( get_post_type( $post_id ) !== 'event' ) return;
    	update_post_meta( $post_id, 'address', '123 Test St' );
    }
    add_action( 'save_post', 'my_save_meta_function', 99, 3 );
    
  • 示例5

    为了触发特定的文章类型,假设我们有一个文章类型名称“book”

    function wpdocs_book_meta( $post_id ) {
    	// Check the logged in user has permission to edit this post
    	if ( ! current_user_can( 'manage_options' ) ) {
    		return $post_id;
    	}
    
    	if ( isset( $_POST['website'] ) ) {
    		$website = esc_url_raw( $_POST['website'] );
    		update_post_meta( $post_id, 'website', $website );
    	}
    }
    add_action( 'save_post_book', 'wpdocs_book_meta' );
    
  • 示例6

    传递给动作的$post_ID是更新文章时修订版的ID。要查找父文章的ID,请使用wp_get_post_parent_id

    function my_function_on_save_post( $post_id ) {
    
    	// Find parent post_id.
    	if ( $post_parent_id = wp_get_post_parent_id( $post_id ) ) {
    		$post_id = $post_parent_id;
    	}
    
    	// Do something.
    
    }
    add_action( 'save_post', 'my_function_on_save_post' );