如何为WordPress自定义文章类型实现层级化友好搜索URL?
WordPress 自定义搜索URL与分类筛选实现方案
一、注册重写规则与查询变量
将以下代码添加到主题的functions.php文件中:
function cosmetic_search_rewrite_rules() { // 注册重写规则,匹配 /search/ 开头的URL结构 add_rewrite_rule( '^search/([^/]+)/?(.*)?$', 'index.php?cosmetic_type=$matches[1]&cosmetic_region_path=$matches[2]', 'top' ); // 添加自定义查询变量,让WordPress识别我们的参数 add_rewrite_tag('%cosmetic_type%', '([^/]+)'); add_rewrite_tag('%cosmetic_region_path%', '(.*)'); } add_action('init', 'cosmetic_search_rewrite_rules');
这段代码会匹配三种目标URL结构:
/search/all→ 对应cosmetic_type=all,cosmetic_region_path为空/search/manicure/north/city1→ 对应cosmetic_type=manicure,cosmetic_region_path=north/city1/search/all/north→ 对应cosmetic_type=all,cosmetic_region_path=north
二、修改主查询,筛选自定义文章类型与分类
通过pre_get_posts钩子调整查询逻辑,确保只返回cosmetic类型文章,并根据URL参数筛选分类:
function cosmetic_search_modify_query($query) { // 仅处理前台主查询,避免影响后台及其他查询 if (!is_admin() && $query->is_main_query()) { $cosmetic_type = get_query_var('cosmetic_type'); $region_path = get_query_var('cosmetic_region_path'); if ($cosmetic_type) { // 强制查询cosmetic自定义文章类型 $query->set('post_type', 'cosmetic'); $tax_query = array('relation' => 'AND'); // 处理cosmetic_type筛选:非all时添加分类条件 if ($cosmetic_type !== 'all') { $tax_query[] = array( 'taxonomy' => 'cosmetic_type', 'field' => 'slug', 'terms' => $cosmetic_type, ); } // 处理cosmetic_region筛选:解析层级路径,取最底层术语 if (!empty($region_path)) { $region_slugs = explode('/', $region_path); $last_slug = end($region_slugs); $region_term = get_term_by('slug', $last_slug, 'cosmetic_region'); if ($region_term && !is_wp_error($region_term)) { $tax_query[] = array( 'taxonomy' => 'cosmetic_region', 'field' => 'term_id', 'terms' => $region_term->term_id, 'include_children' => false, // 需包含子术语则改为true ); } } // 应用分类查询条件 if (!empty($tax_query)) { $query->set('tax_query', $tax_query); } // 清空原生搜索关键词,避免冲突 $query->set('s', ''); } } } add_action('pre_get_posts', 'cosmetic_search_modify_query');
三、创建搜索结果模板
在主题目录下创建page-search.php,用于展示筛选后的文章,基础框架示例:
<?php get_header(); ?> <main id="primary" class="site-main"> <?php if (have_posts()) : ?> <header class="page-header"> <h1 class="page-title"> <?php $type = get_query_var('cosmetic_type'); $region_path = get_query_var('cosmetic_region_path'); echo $type === 'all' ? '所有美妆产品' : (get_term_by('slug', $type, 'cosmetic_type')->name ?? '美妆产品'); if ($region_path) { $last_slug = end(explode('/', $region_path)); $region_term = get_term_by('slug', $last_slug, 'cosmetic_region'); echo $region_term ? ' - ' . $region_term->name : ''; } ?> </h1> </header> <?php while (have_posts()) : the_post(); ?> <?php get_template_part('template-parts/content', 'cosmetic'); ?> <?php endwhile; ?> <?php the_posts_navigation(); ?> <?php else : ?> <?php get_template_part('template-parts/content', 'none'); ?> <?php endif; ?> </main> <?php get_sidebar(); ?> <?php get_footer(); ?>
如果已有archive-cosmetic.php且满足展示需求,可在pre_get_posts函数中添加一行代码复用模板:
$query->set('template', 'archive-cosmetic.php');
四、刷新重写规则
完成代码添加后,登录WordPress后台:
- 进入「设置」→「固定链接」
- 直接点击「保存更改」,系统会自动刷新重写规则
测试验证
现在可验证三个需求场景:
- 访问
yourdomain.com/search/all→ 展示所有cosmetic类型文章 - 访问
yourdomain.com/search/manicure/north/city1→ 展示属于manicure类型且关联city1区域的文章 - 访问
yourdomain.com/search/all/north→ 展示关联north区域的所有cosmetic文章
内容的提问来源于stack exchange,提问作者Painful Detour
相关产品推荐
相关产品推荐

