如何无需插件覆盖WordPress自定义文章类型(CPT)默认文章状态
无需插件替换WordPress自定义文章类型(CPT)的默认文章状态
当然可以不用插件实现!我们可以借助WordPress自带的钩子系统,针对特定自定义文章类型(CPT)替换默认的文章状态显示文本,同时保证后台操作逻辑正常。下面分几个场景给出具体实现代码,你可以把这些代码添加到主题的functions.php文件里,或者自己创建一个小的自定义功能插件(推荐后者,避免主题更新丢失代码)。
1. 替换后台文章列表的状态标签
这个钩子会修改CPT列表中显示的状态文本,比如把“Published”换成“Completed”,“Draft”换成“New”,“Pending Review”换成“In Progress”。
add_filter( 'display_post_states', 'custom_cpt_post_states', 10, 2 ); function custom_cpt_post_states( $states, $post ) { // 替换成你的自定义文章类型slug $target_cpt = 'your_cpt_slug'; if ( $post->post_type !== $target_cpt ) { return $states; } // 替换状态文本 if ( isset( $states['publish'] ) ) { $states['publish'] = 'Completed'; } if ( isset( $states['draft'] ) ) { $states['draft'] = 'New'; } if ( isset( $states['pending'] ) ) { $states['pending'] = 'In Progress'; } return $states; }
2. 替换文章编辑页面的状态下拉选项
上面的代码只能修改列表页,编辑页的状态选择下拉框需要单独处理,用下面的钩子替换选项文本:
add_filter( 'wp_dropdown_post_states', 'custom_cpt_dropdown_states', 10, 1 ); function custom_cpt_dropdown_states( $dropdown ) { // 替换成你的自定义文章类型slug $target_cpt = 'your_cpt_slug'; // 只在目标CPT的编辑页生效 global $post; if ( !$post || $post->post_type !== $target_cpt ) { return $dropdown; } // 替换下拉选项中的文本 $dropdown = str_replace( 'Published', 'Completed', $dropdown ); $dropdown = str_replace( 'Draft', 'New', $dropdown ); $dropdown = str_replace( 'Pending Review', 'In Progress', $dropdown ); return $dropdown; }
3. 替换编辑页面顶部的状态提示文本
编辑页面顶部会显示当前状态的提示(比如“Published on...”),我们可以用post_updated_messages钩子修改这部分内容:
add_filter( 'post_updated_messages', 'custom_cpt_updated_messages' ); function custom_cpt_updated_messages( $messages ) { // 替换成你的自定义文章类型slug $target_cpt = 'your_cpt_slug'; $messages[$target_cpt] = array( 0 => '', // 未使用 1 => sprintf( __( '%s updated. <a href="%s">View %s</a>' ), 'Completed', esc_url( get_permalink() ), 'item' ), 2 => __( 'Custom field updated.' ), 3 => __( 'Custom field deleted.' ), 4 => sprintf( __( '%s updated.' ), 'Completed' ), 5 => isset( $_GET['revision'] ) ? sprintf( __( '%s restored to revision from %s' ), 'Completed', wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, 6 => sprintf( __( '%s published. <a href="%s">View %s</a>' ), 'Completed', esc_url( get_permalink() ), 'item' ), 7 => sprintf( __( '%s saved.' ), 'New' ), 8 => sprintf( __( '%s submitted. <a target="_blank" href="%s">Preview %s</a>' ), 'In Progress', esc_url( add_query_arg( 'preview', 'true', get_permalink() ) ), 'item' ), 9 => sprintf( __( '%s scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview %3$s</a>' ), 'Completed', date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink() ), 'item' ), 10 => sprintf( __( '%s draft updated. <a target="_blank" href="%s">Preview %s</a>' ), 'New', esc_url( add_query_arg( 'preview', 'true', get_permalink() ) ), 'item' ), ); return $messages; }
4. (可选)替换前端显示的状态文本
如果你需要在前端模板中显示文章状态时也替换文本,有两种方式可选:
方法一:用钩子全局替换
add_filter( 'get_post_status', 'custom_cpt_frontend_status', 10, 2 ); function custom_cpt_frontend_status( $status, $post ) { // 替换成你的自定义文章类型slug $target_cpt = 'your_cpt_slug'; if ( $post->post_type !== $target_cpt ) { return $status; } switch ( $status ) { case 'publish': return 'Completed'; case 'draft': return 'New'; case 'pending': return 'In Progress'; default: return $status; } }
方法二:模板中直接判断
在你的CPT模板文件(比如single-your_cpt_slug.php或archive-your_cpt_slug.php)中,添加类似代码:
$post_status = get_post_status( get_the_ID() ); switch ( $post_status ) { case 'publish': echo '<span class="post-status">Completed</span>'; break; case 'draft': echo '<span class="post-status">New</span>'; break; case 'pending': echo '<span class="post-status">In Progress</span>'; break; default: echo '<span class="post-status">' . ucfirst( $post_status ) . '</span>'; }
注意事项
- 记得把所有代码中的
your_cpt_slug替换成你实际的自定义文章类型slug(比如如果你的CPT是“project”,就替换成project)。 - 这种方式是替换显示文本,并没有创建新的文章状态,底层还是用WordPress默认的
publish、draft、pending状态,所以不会影响后台的核心逻辑(比如权限、审核流程等),这是最安全的做法。 - 如果需要完全自定义新的文章状态,那会复杂很多,需要处理状态注册、权限、查询等,但根据你的需求,替换文本完全足够。
内容的提问来源于stack exchange,提问作者3pepe3
相关产品推荐
相关产品推荐

