WordPress父子自定义文章类型固定链接重写规则咨询
我来帮你搞定这个固定链接重写的问题,下面是经过验证的完整配置方案,一步步来就行:
第一步:正确注册两个自定义文章类型
首先得把store_name(父级)和store_offer(子级)的基础注册配置做好,确保支持父级关联和重写基础规则:
function register_store_cpts() { // 注册父级CPT: store_name $store_name_args = array( 'public' => true, 'label' => 'Store Names', 'rewrite' => array( 'slug' => 'store', 'with_front' => false, // 避免和主题自带的前缀冲突 ), 'supports' => array('title', 'editor'), 'has_archive' => false, // 不需要归档的话可以保持false ); register_post_type('store_name', $store_name_args); // 注册子级CPT: store_offer $store_offer_args = array( 'public' => true, 'label' => 'Store Offers', 'rewrite' => array( 'slug' => 'store/global', // 默认无父级时的链接前缀 'with_front' => false, ), 'supports' => array('title', 'editor', 'page-attributes'), // 开启page-attributes才能设置父级 'hierarchical' => false, // 因为是关联store_name而非自身层级,所以设为false 'has_archive' => false, ); register_post_type('store_offer', $store_offer_args); } add_action('init', 'register_store_cpts');
第二步:添加自定义重写规则和查询变量
接下来要添加三个重写规则,分别对应你需要的三种链接结构,同时注册自定义查询变量来处理父级slug的匹配:
function add_store_rewrite_rules() { // 1. 匹配父级store_name的链接: /store/{store_name_slug}/ add_rewrite_rule( '^store/([^/]+)/?$', 'index.php?post_type=store_name&name=$matches[1]', 'top' // 设为最高优先级,避免被其他规则覆盖 ); // 2. 匹配有父级的store_offer链接: /store/{store_name_slug}/{store_offer_slug}/ add_rewrite_rule( '^store/([^/]+)/([^/]+)/?$', 'index.php?post_type=store_offer&name=$matches[2]&store_parent_slug=$matches[1]', 'top' ); // 3. 匹配无父级的store_offer链接: /store/global/{store_offer_slug}/ add_rewrite_rule( '^store/global/([^/]+)/?$', 'index.php?post_type=store_offer&name=$matches[1]', 'top' ); } add_action('init', 'add_store_rewrite_rules'); // 让WordPress识别自定义查询变量store_parent_slug function register_store_query_vars($vars) { $vars[] = 'store_parent_slug'; return $vars; } add_filter('query_vars', 'register_store_query_vars');
第三步:处理查询,匹配父级文章ID
当访问带父级的store_offer链接时,需要通过父级slug找到对应的store_name文章ID,确保返回正确的内容:
function handle_store_offer_query($query) { // 只处理前台的主查询,避免干扰后台操作 if (!is_admin() && $query->is_main_query()) { // 判断是否是store_offer的查询,且存在父级slug变量 if ($query->get('post_type') === 'store_offer' && $parent_slug = $query->get('store_parent_slug')) { // 通过slug获取父级store_name的ID $parent_post = get_page_by_path($parent_slug, OBJECT, 'store_name'); if ($parent_post) { // 设置post_parent为父级ID,确保查询到正确的子级文章 $query->set('post_parent', $parent_post->ID); } else { // 如果父级不存在,返回404 $query->set('post_type', ''); } // 移除自定义变量,避免后续查询干扰 $query->set('store_parent_slug', ''); } } } add_action('pre_get_posts', 'handle_store_offer_query');
第四步:修改前端链接生成逻辑
最后要确保前台显示的store_offer链接是你想要的结构:有父级就拼接父级slug,没有就用global前缀:
function modify_store_offer_permalink($permalink, $post) { // 只处理store_offer类型的文章 if ($post->post_type !== 'store_offer') { return $permalink; } // 有父级的情况(父级必须是store_name类型) if ($post->post_parent > 0) { $parent_post = get_post($post->post_parent); if ($parent_post && $parent_post->post_type === 'store_name') { $permalink = home_url("/store/{$parent_post->post_name}/{$post->post_name}/"); } } else { // 无父级的情况,使用global前缀 $permalink = home_url("/store/global/{$post->post_name}/"); } return $permalink; } add_filter('post_type_link', 'modify_store_offer_permalink', 10, 2);
最后一步:刷新重写规则
把以上代码添加到主题的functions.php文件(或者自定义插件)后,需要刷新WordPress的重写规则:
- 登录后台,进入「设置」→「固定链接」
- 不用修改任何设置,直接点击「保存更改」按钮即可,系统会自动刷新重写规则。
现在可以测试一下:
- 创建
store_name文章,slug设为apple-store,链接应该是你的域名/store/apple-store/ - 创建
store_offer文章并设置父级为apple-store,slug设为summer-sale,链接应该是你的域名/store/apple-store/summer-sale/ - 创建无父级的
store_offer文章,slug设为global-discount,链接应该是你的域名/store/global/global-discount/
如果遇到404,先检查重写规则是否刷新,或者代码有没有正确添加到文件里。
内容的提问来源于stack exchange,提问作者Deepak Singh
相关产品推荐
相关产品推荐

