You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改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页面,导致博客、作者等归档路径被误匹配。修复步骤如下:

  1. 修改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');
    
  2. 调整重写规则优先级
    移除原有冲突规则,添加优先级更高的分类归档规则,确保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');
    
  3. 更新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 );
    
  4. 刷新重写规则
    进入WordPress后台「设置」→「固定链接」页面,无需修改任何设置,直接点击「保存更改」按钮,刷新系统重写规则。

关键说明

  • 将分类归档规则优先级设为最高,确保不会被CPT单页规则覆盖;
  • CPT使用固定基础slugresource,但通过重写规则隐藏,实现目标URL结构;
  • 保留了原有分类归档和CPT归档的URL结构,同时解决了其他归档页面的404问题。

内容的提问来源于stack exchange,提问作者Dudley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:09:53