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

如何让WP_Query在标题、描述、分类及标签中搜索关键词?

解决方案:扩展WordPress搜索范围至标题、摘要、分类(含子分类)及标签

修改后的DOM结构(中文适配)

<main>
    <h1>文章</h1>
    <form action="<?php echo get_page_url() ?>" method="get">
        <label for="search">搜索</label>
        <input type="text" name="s" id="search" value="<?php the_search_query(); ?>" />
    </form>
    <?php if ($posts->have_posts()) : ?>
        <div id="wrp-articles">
            <?php while ($posts->have_posts()) : $posts->the_post() ?>
                <article>
                    <div class="wrp-thumb">
                        <a href="<?php echo get_permalink() ?>">
                            <img src="<?php echo get_the_post_thumbnail_url() ?>" alt="<?php echo get_the_title() ?>">
                        </a>
                    </div>
                    <ul class="list-categories">
                        <?php foreach (get_the_category() as $cat) : ?>
                            <li>
                                <a href="<?php echo get_category_link($cat->term_id) ?>"><?php echo $cat->name ?></a>
                            </li>
                        <?php endforeach; ?>
                    </ul>
                    <span class="title"><?php echo get_the_title() ?></span>
                    <p><?php echo get_the_excerpt() ?></p>
                </article>
            <?php endwhile; ?>
        </div>
    <?php endif; ?>
    <div id="pagination">
        <?php echo paginate_links(array(
            'base' => get_site_url() . '%_%',
            'format' => '/page/%#%',
            'total'  => $posts->max_num_pages,
            'current' => max(1, get_query_var('paged'))
        )) ?>
    </div>
</main>

修改后的PHP代码(实现扩展搜索)

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$search_term = '';

$args = array(
    'post_type' => 'post',
    'posts_per_page' => 3,
    'order' => 'desc',
    'paged' => $paged
);

if (!empty($_GET['s'])) {
    $search_term = sanitize_text_field($_GET['s']);
    
    // 获取匹配关键词的分类(含子分类)ID
    $matching_cats = get_terms(array(
        'taxonomy' => 'category',
        'name__like' => $search_term,
        'hide_empty' => false
    ));
    $cat_ids = array();
    foreach ($matching_cats as $cat) {
        $cat_ids[] = $cat->term_id;
        // 追加子分类ID
        $child_cats = get_term_children($cat->term_id, 'category');
        $cat_ids = array_merge($cat_ids, $child_cats);
    }
    $cat_ids = array_unique($cat_ids);
    
    // 获取匹配关键词的标签ID
    $matching_tags = get_terms(array(
        'taxonomy' => 'post_tag',
        'name__like' => $search_term,
        'hide_empty' => false
    ));
    $tag_ids = wp_list_pluck($matching_tags, 'term_id');
    
    // 添加临时过滤器修改查询逻辑
    add_filter('posts_join', function($join) use ($wpdb) {
        // 关联分类/标签关系表
        $join .= " LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id ";
        $join .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id ";
        $join .= " LEFT JOIN {$wpdb->terms} t ON tt.term_id = t.term_id ";
        return $join;
    });
    
    add_filter('posts_where', function($where) use ($wpdb, $search_term, $cat_ids, $tag_ids) {
        // 调整原搜索条件的逻辑连接符为OR
        $where = str_replace('AND (((', 'OR (((', $where);
        
        // 添加分类匹配条件
        if (!empty($cat_ids)) {
            $cat_ids_str = implode(',', array_map('intval', $cat_ids));
            $where .= " OR tt.taxonomy = 'category' AND tt.term_id IN ($cat_ids_str) ";
        }
        
        // 添加标签匹配条件
        if (!empty($tag_ids)) {
            $tag_ids_str = implode(',', array_map('intval', $tag_ids));
            $where .= " OR tt.taxonomy = 'post_tag' AND tt.term_id IN ($tag_ids_str) ";
        }
        
        return $where;
    });
    
    // 添加去重规则,避免同一文章因关联多分类/标签重复显示
    add_filter('posts_distinct', function() {
        return 'DISTINCT';
    });
}

$posts = new WP_Query($args);

// 清理临时过滤器,避免影响后续查询
if (!empty($search_term)) {
    remove_filter('posts_join', '__return_false');
    remove_filter('posts_where', '__return_false');
    remove_filter('posts_distinct', '__return_false');
}
?>

核心逻辑说明

  • 分类与子分类覆盖:通过get_terms搜索匹配关键词的分类,再用get_term_children拉取所有子分类ID,确保包含子分类下的文章。
  • 标签匹配:直接通过get_terms筛选名称含关键词的标签ID。
  • 临时过滤器:
    • posts_join关联分类/标签相关数据表,让查询能读取分类、标签信息;
    • posts_where修改查询逻辑,将标题、摘要、分类、标签的匹配规则用OR连接;
    • posts_distinct避免同一文章因关联多个分类/标签被重复输出。
  • 过滤器清理:查询完成后立即移除临时过滤器,防止干扰页面其他WordPress查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 19:04:52