修改WordPress自定义文章类型URL后其他归档页面404的解决
修复WordPress自定义文章类型导致的其他归档404错误
问题背景
我在WordPress中创建了名为Resources的自定义文章类型(CPT)和名为Resource Type的自定义分类法,期望的URL结构如下:
- CPT单页:
site-url/custom-tax/post-title - 分类归档页面:
site-url/resources/custom-tax/ - 文章类型归档页面:
site-url/resources
现有代码能实现目标URL,但博客、作者等其他归档页面出现404错误,排查后确认是自定义文章类型slug设置为%resource-type%导致的,需要修复其他归档页面的访问问题。
现有代码
/* ## Resources ## */ function register_resource_post_type() { $args = array( 'rewrite' => array( 'slug' => '%resource-type%', 'with_front' => false ), ); register_post_type('resource', $args); } add_action('init', 'register_resource_post_type'); /* ## Resource Types ## */ function register_resource_type_taxonomy() { $args = array( 'rewrite' => array( 'slug' => 'resources', 'with_front' => false, ), ); register_taxonomy('resource-type', array('resource'), $args); } add_action('init', 'register_resource_type_taxonomy'); /* # Permalink Rewrite # */ function wpd_taxonomy_pagination_rewrites(){ add_rewrite_rule( 'resource-type/([^/]+)/page/([0-9]+)/?$', 'index.php?resource-type=$matches[1]&paged=$matches[2]', 'top' ); } add_action( 'init', 'wpd_taxonomy_pagination_rewrites' ); function wpd_post_link( $post_link, $id = 0 ){ $post = get_post($id); if ( is_object( $post ) && $post->post_type == 'resource' ){ $terms = wp_get_object_terms( $post->ID, 'resource-type' ); if( $terms ){ foreach( $terms as $term ){ if( 0 == $term->parent ){ return str_replace( '%resource-type%' , $term->slug , $post_link ); } } } else { return str_replace( '%resource-type%' , 'uncategorized', $post_link ); } } return $post_link; } add_filter( 'post_type_link', 'wpd_post_link', 1, 3 );
解决方案
问题根源在于将CPT的slug设为%resource-type%后,WordPress的重写规则会把所有匹配类似分类slug的路径都解析为CPT页面,导致博客、作者等归档路径被误匹配。修复步骤如下:
修改CPT注册参数
不要直接用%resource-type%作为CPT的slug,改用固定基础slug并指定归档路径,避免规则冲突:function register_resource_post_type() { $args = array( 'rewrite' => array( 'slug' => 'resource', // 设置固定基础slug 'with_front' => false ), 'has_archive' => 'resources', // 指定CPT归档页面路径 'public' => true, 'query_var' => true ); register_post_type('resource', $args); } add_action('init', 'register_resource_post_type');调整重写规则优先级
移除原有冲突规则,添加优先级更高的分类归档规则,确保CPT单页规则不会覆盖其他归档路径:function wpd_resource_rewrite_rules() { // 分类归档及分页规则(优先级最高) add_rewrite_rule( '^resources/([^/]+)/page/([0-9]+)/?$', 'index.php?resource-type=$matches[1]&paged=$matches[2]', 'top' ); add_rewrite_rule( '^resources/([^/]+)/?$', 'index.php?resource-type=$matches[1]', 'top' ); // CPT单页规则 add_rewrite_rule( '^([^/]+)/([^/]+)/?$', 'index.php?post_type=resource&name=$matches[2]', 'top' ); } add_action('init', 'wpd_resource_rewrite_rules'); // 移除原有的分页规则函数 remove_action('init', 'wpd_taxonomy_pagination_rewrites');更新CPT链接生成逻辑
修改链接生成函数,直接生成符合目标结构的URL:function wpd_post_link( $post_link, $id = 0 ){ $post = get_post($id); if ( is_object( $post ) && $post->post_type == 'resource' ){ $terms = wp_get_object_terms( $post->ID, 'resource-type' ); if( !empty($terms) ){ foreach( $terms as $term ){ if( $term->parent == 0 ){ return home_url( '/' . $term->slug . '/' . $post->post_name . '/' ); } } } else { return home_url( '/uncategorized/' . $post->post_name . '/' ); } } return $post_link; } add_filter( 'post_type_link', 'wpd_post_link', 10, 3 );刷新重写规则
进入WordPress后台「设置」→「固定链接」页面,无需修改任何设置,直接点击「保存更改」按钮,刷新系统重写规则。
关键说明
- 将分类归档规则优先级设为最高,确保不会被CPT单页规则覆盖;
- CPT使用固定基础slug
resource,但通过重写规则隐藏,实现目标URL结构; - 保留了原有分类归档和CPT归档的URL结构,同时解决了其他归档页面的404问题。
内容的提问来源于stack exchange,提问作者Dudley
相关产品推荐
相关产品推荐

