Стандартный поиск WordPress часто не удовлетворяет требованиям сложных проектов, где нужно гибко настраивать результаты и добавлять фильтры по разным параметрам. В этой статье мы подробно рассмотрим, как создать собственный вид поиска (custom search capabilities) в WordPress, чтобы получать более точные и полезные результаты для пользователей.
Почему стандартный поиск WordPress ограничен
По умолчанию WordPress ищет совпадения по заголовкам и содержимому записей, иногда учитывая таксономии и мета-поля, но без тонкой настройки. Это приводит к тому, что пользователь получает много нерелевантных результатов или не может искать по нужным параметрам.
Например, если у вас интернет-магазин на WooCommerce или сайт с большим количеством кастомных типов записей, стандартный поиск не позволит фильтровать по цене, атрибутам или произвольным полям. Для решения таких задач нужны собственные расширения и кастомизация.
Кроме того, стандартный поиск не всегда учитывает вес слов, морфологию и другие нюансы, что ухудшает поиск.
Создание собственного вида поиска: основные подходы
Для реализации кастомного поиска есть несколько вариантов:
- Использовать WP_Query с дополнительными параметрами для фильтрации по мета-полям и таксономиям.
- Расширить функционал с помощью хука
pre_get_postsдля модификации основного запроса поиска. - Использовать сторонние плагины с расширенными возможностями поиска, например, SearchWP, Relevanssi или WPSearch.
- Реализовать свой собственный поиск на базе SQL-запросов или с помощью REST API.
Давайте рассмотрим вариант с использованием pre_get_posts для настройки поиска по кастомным полям и таксономиям, а также рассмотрим пример с плагином SearchWP.
Настройка поиска по кастомным полям и таксономиям через pre_get_posts
Хук pre_get_posts позволяет изменить параметры главного запроса до его выполнения. Это удобно для изменения поведения поиска без создания отдельного шаблона.
Пример функции wpteam_custom_search_filter для добавления поиска по кастомному полю 'product_sku' и фильтрации по таксономии 'product_category':
function wpteam_custom_search_filter($query) {
if ($query->is_search() && !is_admin() && $query->is_main_query()) {
// Ищем по мета-полю 'product_sku'
$meta_query = array(
array(
'key' => 'product_sku',
'value' => $query->get('s'),
'compare' => 'LIKE'
)
);
$query->set('meta_query', $meta_query);
// Фильтрация по таксономии 'product_category', если передан параметр
if (!empty($_GET['product_category'])) {
$tax_query = array(
array(
'taxonomy' => 'product_category',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['product_category'])
)
);
$query->set('tax_query', $tax_query);
}
// Можно настроить сортировку
$query->set('orderby', 'meta_value');
$query->set('meta_key', 'product_sku');
$query->set('order', 'ASC');
}
}
add_action('pre_get_posts', 'wpteam_custom_search_filter');Такой код позволит расширить поиск по артикулу товара и фильтровать результаты по категории, если в URL передан параметр product_category.
Важно: для удобства пользователей можно создать специальную форму поиска с дополнительными полями, которые будут передавать нужные параметры.
Пример формы поиска с фильтром категории:
<form role="search" method="get" id="searchform" action="<?php echo home_url('/'); ?>">
<input type="text" value="<?php echo get_search_query(); ?>" name="s" id="s" placeholder="Поиск..." />
<select name="product_category">
<option value="">Все категории</option>
<?php
$terms = get_terms(array('taxonomy' => 'product_category', 'hide_empty' => false));
foreach ($terms as $term) {
echo '<option value="' . esc_attr($term->slug) . '"' . selected(isset($_GET['product_category']) ? $_GET['product_category'] : '', $term->slug, false) . '>' . esc_html($term->name) . '</option>';
}
?>
</select>
<input type="submit" id="searchsubmit" value="Искать" />
</form>Использование плагина SearchWP для расширенного поиска
Если хочется получить быстрый и мощный поиск без глубокого кодирования, советуем обратить внимание на плагин SearchWP. Он позволяет:
- Индексировать произвольные поля, таксономии, контент в PDF и других форматах.
- Настраивать вес слов для повышения релевантности.
- Добавлять собственные правила поиска через интерфейс.
- Интегрироваться с WooCommerce и другими популярными плагинами.
После установки и активации плагина можно создать несколько поисковых движков (engines) и настроить их для разных типов контента. Благодаря этому пользователь получит максимально точные результаты.
Как интегрировать SearchWP с формой поиска
SearchWP автоматически заменяет стандартный поиск WordPress, поэтому достаточно иметь стандартную форму поиска. Для тонкой настройки можно использовать фильтры плагина, описанные в его документации.
Оптимизация и кеширование результатов поиска
Если у вас большой сайт, расширенный поиск может замедлить загрузку страниц. Здесь помогут следующие приемы:
- Использование ABC Pagination или других плагинов для постраничной навигации, чтобы не выводить сразу все результаты.
- Кеширование результатов поиска через Transients API. Например, сохранять результаты сложного запроса на 10-15 минут.
- Использование внешних сервисов поиска, если нагрузка очень высокая.
Пример кеширования результатов с помощью Transients API:
function wpteam_get_search_results_with_cache($search_term) {
$cache_key = 'wpteam_search_' . md5($search_term);
$results = get_transient($cache_key);
if ($results === false) {
$args = array(
's' => $search_term,
'post_type' => 'product',
'posts_per_page' => 10
);
$query = new WP_Query($args);
$results = $query->posts;
set_transient($cache_key, $results, 15 * MINUTE_IN_SECONDS);
}
return $results;
}Вывод результатов поиска с кастомным шаблоном
Для более гибкого отображения результатов можно создать отдельный шаблон search.php в вашей теме. В нем с помощью стандартного цикла WordPress выводите результаты, учитывая кастомные поля и таксономии.
Пример блока вывода с показом артикула товара (мета-поля product_sku):
if (have_posts()) :
while (have_posts()) : the_post();
$sku = get_post_meta(get_the_ID(), 'product_sku', true);
echo '<h2><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
if ($sku) {
echo '<p>Артикул: ' . esc_html($sku) . '</p>';
}
the_excerpt();
endwhile;
else :
echo '<p>Ничего не найдено</p>';
endif;Выводы и рекомендации
Создание собственного вида возможностей для поиска в WordPress — задача, которая требует понимания внутреннего устройства WP_Query, метаполей и таксономий. Использование хука pre_get_posts позволяет гибко модифицировать поиск без создания нового шаблона.
Для проектов с высокими требованиями рекомендуем использовать профессиональные плагины, например, SearchWP, которые значительно расширяют функционал и экономят время разработки.
Не забывайте про оптимизацию запросов и кеширование, чтобы поиск работал быстро и не нагружал сервер.