如何用add_rewrite_rule()自定义WooCommerce产品固定链接结构
解决WooCommerce产品固定链接自定义问题
核心思路
要实现包含父/子分类的产品链接,需要两步:构建正确的前端链接和配置对应的重写规则,同时用wp_get_post_terms获取产品分类的层级关系。
修改后的完整代码
// 自定义产品固定链接的前端显示 add_filter('post_type_link', 'custom_product_permalink', 10, 2); function custom_product_permalink($link, $post) { if ($post->post_type !== 'product') { return $link; } // 获取产品关联的产品分类(按层级排序) $terms = wp_get_post_terms($post->ID, 'product_cat', array( 'orderby' => 'parent', 'order' => 'ASC', 'fields' => 'all' )); // 无分类时 fallback 到原有结构 if (empty($terms)) { $sku = get_post_meta($post->ID, '_sku', true); return strtolower(home_url('shop/product/' . $post->post_name . '-' . $sku . '/')); } // 取层级最深的分类(优先子分类) $target_term = end($terms); $category_slugs = array($target_term->slug); // 向上追溯父分类,拼接完整分类路径 while ($target_term->parent !== 0) { $target_term = get_term($target_term->parent, 'product_cat'); array_unshift($category_slugs, $target_term->slug); } $category_path = implode('/', $category_slugs); $sku = get_post_meta($post->ID, '_sku', true); // 处理SKU为空的情况 $sku_suffix = $sku ? '-' . $sku : ''; // 构建最终的小写链接 return strtolower(home_url('shop/' . $category_path . '/' . $post->post_name . $sku_suffix . '/')); } // 注册重写规则 add_action('init', 'custom_product_permalink_rewrite_rules'); function custom_product_permalink_rewrite_rules() { // 匹配多级分类(支持父/子/孙...任意层级) add_rewrite_rule( 'shop/(.+)/([^/]+)-([^/]+)/?$', 'index.php?post_type=product&name=$matches[2]&sku=$matches[3]', 'top' ); // Fallback:无分类的原有结构 add_rewrite_rule( 'shop/product/([^/]+)-([^/]+)/?$', 'index.php?post_type=product&name=$matches[1]&sku=$matches[2]', 'top' ); } // 仅在主题/插件激活时刷新重写规则(避免性能损耗) register_activation_hook(__FILE__, 'flush_custom_rewrite_rules'); function flush_custom_rewrite_rules() { custom_product_permalink_rewrite_rules(); flush_rewrite_rules(); }
关键细节说明
- 分类路径获取:
- 通过
wp_get_post_terms获取产品的product_cat分类,按层级排序后取最深的子分类 - 循环追溯父分类,用
array_unshift把父分类slug放在前面,拼接成parent-cat/child-cat的路径
- 通过
- 重写规则优化:
- 使用
shop/(.+)/([^/]+)-([^/]+)/?$匹配任意层级的分类路径,比固定两级更灵活 - 重写规则只需要传递
post_type、name和sku即可定位产品,分类部分仅作为URL装饰(若需验证分类匹配,可额外添加逻辑)
- 使用
- 性能与容错:
- 移除了
init钩子中每次调用flush_rewrite_rules的操作,改为仅在激活时刷新,避免重复执行影响性能 - 增加了SKU为空的处理,防止出现
product_name-的无效链接 - 无分类产品自动 fallback 到原有链接结构
- 移除了
测试步骤
- 将代码添加到主题的
functions.php或自定义插件中 - 激活主题/插件(触发重写规则刷新),或手动进入设置→固定链接页面点击保存(无需修改设置,仅触发刷新)
- 给产品设置父/子分类,查看产品的固定链接是否符合预期
- 访问新链接,确认能正常打开产品页面
内容的提问来源于stack exchange,提问作者iFixed
相关产品推荐
相关产品推荐

