如何在Rewrite规则中引入$post内容?替换自定义文章类型Slug
解决自定义文章类型动态Slug的重写规则问题
嘿,这个需求在WordPress里完全可以实现,但得先理清一个关键限制:默认的重写规则是静态注册的,在WordPress初始化(init钩子阶段)的时候,还没有任何请求上下文,$post对象根本不存在,所以没法直接把$post信息传入重写规则函数里。不过我们可以通过「占位符规则+动态解析」的思路来达成你的目标,具体步骤如下:
第一步:注册自定义重写规则与查询变量
先注册一个带占位符的重写规则,匹配你想要的URL结构,同时把占位符作为自定义查询变量传递给后续的处理逻辑:
// 注册重写规则 function custom_procedure_rewrite_rule() { add_rewrite_rule( '^([^/]+)/facelift/?$', // 匹配类似 /xxx/facelift/ 的URL 'index.php?post_type=procedure&custom_slug=$matches[1]', // 把占位符传给custom_slug查询变量 'top' // 优先级设为top,避免被其他规则覆盖 ); } add_action('init', 'custom_procedure_rewrite_rule'); // 注册自定义查询变量 function custom_procedure_query_vars($vars) { $vars[] = 'custom_slug'; return $vars; } add_filter('query_vars', 'custom_procedure_query_vars');
第二步:动态解析查询变量,替换为元键对应的文章
利用template_redirect钩子(这个阶段WordPress已经开始处理请求,能拿到查询变量),根据占位符的值去查找对应元键的文章,然后修正WP查询对象:
function custom_procedure_resolve_slug() { global $wp_query; // 检查是否是我们的自定义请求 if (isset($wp_query->query_vars['custom_slug']) && $wp_query->query_vars['post_type'] === 'procedure') { $target_slug = $wp_query->query_vars['custom_slug']; // 查询元键'slug'等于目标值的发布状态文章 $matched_posts = get_posts([ 'post_type' => 'procedure', 'meta_key' => 'slug', 'meta_value' => $target_slug, 'posts_per_page' => 1, 'post_status' => 'publish' ]); if (!empty($matched_posts)) { $target_post = $matched_posts[0]; // 修正WP查询,指向正确的文章 $wp_query->set('p', $target_post->ID); $wp_query->is_single = true; $wp_query->is_singular = true; $wp_query->is_page = false; $wp_query->rewind_posts(); } else { // 没找到匹配文章,返回404 $wp_query->set_404(); status_header(404); } } } add_action('template_redirect', 'custom_procedure_resolve_slug');
第三步:生成正确的自定义URL
在模板里输出文章链接时,不要用默认的get_permalink(),而是根据元键值构建自定义URL:
// 获取当前文章的元键'slug'值 $custom_slug = get_post_meta(get_the_ID(), 'slug', true); // 生成自定义URL(如果元键值为空, fallback到默认链接) $custom_permalink = $custom_slug ? home_url("/{$custom_slug}/facelift/") : get_permalink(); // 输出链接 echo '<a href="' . esc_url($custom_permalink) . '">' . get_the_title() . '</a>';
重要提醒
写完代码后,一定要去WordPress后台的「设置→固定链接」页面,点击一下「保存更改」,刷新重写规则缓存,否则新的规则不会生效。
简单总结下:因为重写规则是提前注册的静态规则,没法直接用$post,但我们可以先留一个占位符,等请求进来时再动态根据占位符去匹配元键对应的文章,从而实现你想要的URL结构。
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

