搜尋特定的category
直接限制前台搜尋只查某個 category
在 functions.php 加:
PHP
function my_search_only_in_category($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$query->set('cat', 12); // 只搜尋 category ID = 12
}
}
add_action('pre_get_posts', 'my_search_only_in_category');這樣前台搜尋結果就只會出現在 分類 ID 12 裡的文章。
只在某個 category 與其子分類中搜尋
cat 通常會包含該分類底下文章;若想更明確控制,也可以先抓子分類 ID 再指定:
PHP
function my_search_only_in_category_tree($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$parent_cat_id = 12;
$child_ids = get_terms([
'taxonomy' => 'category',
'hide_empty' => false,
'child_of' => $parent_cat_id,
'fields' => 'ids',
]);
$cat_ids = array_merge([$parent_cat_id], $child_ids);
$query->set('category__in', $cat_ids);
}
}
add_action('pre_get_posts', 'my_search_only_in_category_tree');這樣會限定在:
- 主分類
- 子分類
- 孫分類
內搜尋。
讓使用者從搜尋表單指定 category

如果不是想「全站搜尋都固定只查某分類」,而是想做成搜尋表單帶 category,可以這樣:
PHP
//搜尋表單
<form role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
<input type="search" name="s" placeholder="搜尋文章">
<input type="hidden" name="cat" value="12">
<button type="submit">搜尋</button>
</form>這樣送出後就只查 category 12。
指定分類 slug,再轉成 ID
若比較習慣用 slug:
PHP
function my_search_only_in_specific_category($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$category = get_category_by_slug('business-supplies');
if ($category) {
$query->set('cat', $category->term_id);
}
}
}
add_action('pre_get_posts', 'my_search_only_in_specific_category');如果搜尋的是 自訂文章類型
那還要補:
PHP
$query->set('post_type', 'post');
或是
$query->set('post_type', ['post']);不然搜尋結果可能混到 page 或其他 post type。
指定多個分類 slug
指定多個分類 slug 最乾脆的方式是先把 slug 轉成 term ID,再塞進 category__in。
PHP
function my_search_only_in_multiple_categories($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$slugs = ['business-supplies', 'office', 'stationery'];
$categories = get_terms([
'taxonomy' => 'category',
'hide_empty' => false,
'slug' => $slugs,
'fields' => 'ids',
]);
if (!is_wp_error($categories) && !empty($categories)) {
$query->set('category__in', $categories);
}
}
}
add_action('pre_get_posts', 'my_search_only_in_multiple_categories');包含這些分類底下的子分類、孫分類
那就要把每個 slug 對應的分類,再往下抓全部子孫分類 ID:
PHP
function my_search_only_in_multiple_category_trees($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$slugs = ['business-supplies', 'office', 'stationery'];
$parent_ids = get_terms([
'taxonomy' => 'category',
'hide_empty' => false,
'slug' => $slugs,
'fields' => 'ids',
]);
if (is_wp_error($parent_ids) || empty($parent_ids)) {
return;
}
$all_cat_ids = $parent_ids;
foreach ($parent_ids as $parent_id) {
$child_ids = get_terms([
'taxonomy' => 'category',
'hide_empty' => false,
'child_of' => $parent_id,
'fields' => 'ids',
]);
if (!is_wp_error($child_ids) && !empty($child_ids)) {
$all_cat_ids = array_merge($all_cat_ids, $child_ids);
}
}
$all_cat_ids = array_values(array_unique($all_cat_ids));
$query->set('category__in', $all_cat_ids);
}
}
add_action('pre_get_posts', 'my_search_only_in_multiple_category_trees');URL 傳入多個 slug
例如網址長這樣:
PHP
?s=abc&cats=business-supplies,office,stationery可以這樣寫:
PHP
function my_search_only_in_multiple_categories_from_url($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
if (!empty($_GET['cats'])) {
$slugs = array_map('sanitize_title', explode(',', wp_unslash($_GET['cats'])));
$categories = get_terms([
'taxonomy' => 'category',
'hide_empty' => false,
'slug' => $slugs,
'fields' => 'ids',
]);
if (!is_wp_error($categories) && !empty($categories)) {
$query->set('category__in', $categories);
}
}
}
}
add_action('pre_get_posts', 'my_search_only_in_multiple_categories_from_url');搜尋表單傳送到URL範例
如果要搭配表單
PHP
<form role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
<input type="search" name="s" placeholder="搜尋文章">
<input type="hidden" name="cats" value="business-supplies,office,stationery">
<button type="submit">搜尋</button>
</form>該選哪一種
如果要的是:
- 整個網站搜尋都固定只搜某分類
用pre_get_posts - 某個搜尋框只搜某分類
用表單 hiddencat - 只搜主分類加全部子孫分類
用category__in + get_terms()
設定 search 的結果的 Pagination
在 functions.php 用 pre_get_posts 設定就可以。
PHP
function my_search_posts_per_page($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$query->set('posts_per_page', 8);
}
}
add_action('pre_get_posts', 'my_search_posts_per_page');如果同時還要限制搜尋只查特定多個分類 slug,可以合併成這樣:
PHP
function my_search_filter($query) {
if (!is_admin() && $query->is_main_query() && $query->is_search()) {
$query->set('posts_per_page', 8);
$slugs = ['business-supplies', 'office', 'stationery'];
$category_ids = get_terms([
'taxonomy' => 'category',
'hide_empty' => false,
'slug' => $slugs,
'fields' => 'ids',
]);
if (!is_wp_error($category_ids) && !empty($category_ids)) {
$query->set('category__in', $category_ids);
}
}
}
add_action('pre_get_posts', 'my_search_filter');如果 search.php 有分頁,記得用主查詢的分頁輸出,不要另外 new WP_Query,不然又很容易出現 /page/2/ 的 404 pagination error 錯誤。




