Как создать фильтр результатов поиска в WordPress
Нативный поиск в WordPress работает неплохо. Но его возможности можно расширить с помощью системы фильтров. Всё, что вам нужно для этого, немного PHP-кода и небольшое ноу-хау.
Итоговый результат

Вот как будет выглядеть итоговый результат.
1. HTML- код
Мы будем использовать тему Twenty Seventeen. Скачайте ее и откройте в редакторе кода. В файле search.php перейдите на строку 26. Под ней добавьте HTML-код меню фильтров.
<h3 class="page-title">
Filter By
</h3>
<nav class="page-nav">
<a class="current" href="#">
All
</a>
<a href="#">
Posts
</a>
<a href="#">
Pages
</a>
</nav>
Как видите, мы используем стандартный элемент nav с несколькими ссылками внутри него.
Также добавьте заголовок, применив для этого стандартный класс page-title из темы Twenty Seventeen.
2. CSS- код
CSS- код достаточно прост. Тема Twenty Seventeen предоставляет большинство стилей для отступов и шрифтов.
Откройте файл style.css, прокрутите его в самый низ и добавьте следующий CSS-код:
.page-nav {
margin-bottom: 70px;
padding-bottom: 70px;
display: flex;
flex-wrap: wrap;
border-bottom: 2px solid #eee;
}
.page-nav a {
padding: 5px 20px;
border-radius: 1000px;
background: #eee;
}
.page-nav a:hover {
background: #ddd;
}
.page-nav a.current {
background: #222;
color: #fff;
}
.page-nav a:not(:last-child) {
margin-right: 20px;
}
Единственный момент, требующий внимания, это использование .page-nav a:not(:last-child). Это значит: “применить ко всем ссылкам, кроме последней”.
3. PHP- код
Откройте файл functions.php. Добавьте приведенный ниже код в самый низ, чтобы отделить этот код от основного.
Чтобы применять CSS-класс .current к ссылкам элемента nav, нужно создать новую функцию ip_search_filter_item_class();.
Заметьте, что мы используем префикс ip_ в начале имени функции. На сайте могут быть установлены другие плагины, которые используют функцию search_filter_item_class();. Применение префикса существенно снижает вероятность возникновения ошибки.
function ip_search_filter_item_class($passed_string = false) {
}
Затем нужно получить тип поста, который будет передаваться в строку запроса. И после этого проверить, совпадает ли он с тем, что передаётся в функцию:
$post_type = (isset($_GET['post_type']) ? $_GET['post_type'] : false);
if($passed_string == $post_type) {
echo 'current';
}
Перед тем, как создать основную функцию, добавьте следующий код в HTML-файл:
<nav class="page-nav">
<a class="<?php echo (!isset($_GET['post_type']) ? 'current' : false); ?>" href="#">
All
</a>
<a class="<?php ip_search_filter_item_class('post'); ?>" href="#">
Posts
</a>
<a class="<?php ip_search_filter_item_class('page'); ?>" href="#">
Pages
</a>
</nav>
Теперь добавим корректные URL- адреса к этим ссылкам:
<nav class="page-nav">
<a class="<?php echo (!isset($_GET['post_type']) ? 'current' : false); ?>" href="<?php echo home_url(); ?>?s=<?php echo get_search_query(); ?>">
All
</a>
<a class="<?php ip_search_filter_item_class('post'); ?>" href="<?php echo home_url(); ?>?s=<?php echo get_search_query(); ?>&post_type=post">
Posts
</a>
<a class="<?php ip_search_filter_item_class('page'); ?>" href="<?php echo home_url(); ?>?s=<?php echo get_search_query(); ?>&post_type=page">
Pages
</a>
</nav>
Мы получаем адрес URL-адрес домашней страницы и добавляем к нему параметр ?s=
вместе с поисковым запросом. У вас должен получиться примерно такой URL- адрес:
http://localhost:8888/wordpress/?s=test&post_type=page
Ссылка на пост работает, а ссылка на страницу – нет. Исправим это в следующей функции фильтра результатов поиска:
function ip_search_filter($query) {
}
add_filter('pre_get_posts', 'ip_search_filter');
Затем настроим возврат запроса и проверку того, не находимся ли мы в панели администрирования:
function ip_search_filter($query) {
// Проверяем, что мы не в панели администрирования
if(!is_admin()) {
}
// Возвращаем результат
return $query;
}
add_filter('pre_get_posts', 'ip_search_filter');
Теперь нужно убедиться в том, что мы работаем с правильным запросом. В данном случае это главный запрос поиска:
// Проверяем, что это главный запрос поиска
if($query->is_main_query() && $query->is_search()) {
}
Последним шагом будет получение значения переменной $_GET['post_type'], его обработка и применение к текущему запросу:
// Проверяем, задана ли $_GET['post_type']
if(isset($_GET['post_type']) && $_GET['post_type'] != '') {
// Фильтруем его для безопасности
$post_type = sanitize_text_field($_GET['post_type']);
// Устанавливаем тип поста
$query->set('post_type', $post_type);
}
PHP-код создан и размещён в нужном месте.
4. Итоговый код примера
HTML-код
<h3 class="page-title">
Filter By
</h3>
<nav class="page-nav">
<a class="<?php echo (!isset($_GET['post_type']) ? 'current' : false); ?>" href="<?php echo home_url(); ?>?s=<?php echo get_search_query(); ?>">
All
</a>
<a class="<?php ip_search_filter_item_class('post'); ?>" href="<?php echo home_url(); ?>?s=<?php echo get_search_query(); ?>&post_type=post">
Posts
</a>
<a class="<?php ip_search_filter_item_class('page'); ?>" href="<?php echo home_url(); ?>?s=<?php echo get_search_query(); ?>&post_type=page">
Pages
</a>
</nav>
CSS-код
.page-nav {
margin-bottom: 70px;
padding-bottom: 70px;
display: flex;
flex-wrap: wrap;
border-bottom: 2px solid #eee;
}
.page-nav a {
padding: 5px 20px;
border-radius: 1000px;
background: #eee;
}
.page-nav a:hover {
background: #ddd;
}
.page-nav a.current {
background: #222;
color: #fff;
}
.page-nav a:not(:last-child) {
margin-right: 20px;
}
PHP-код
function ip_search_filter_item_class($passed_string = false) {
$post_type = (isset($_GET['post_type']) ? $_GET['post_type'] : false);
if($passed_string == $post_type) {
echo 'current';
}
}
function ip_search_filter($query) {
// Проверяем, что мы не в административной области
if(!is_admin()) {
// Проверяем, что это главный запрос поиска
if($query->is_main_query() && $query->is_search()) {
// Проверяем, задана ли $_GET['post_type']
if(isset($_GET['post_type']) && $_GET['post_type'] != '') {
// Фильтруем его для безопасности
$post_type = sanitize_text_field($_GET['post_type']);
// Устанавливаем тип поста
$query->set('post_type', $post_type);
}
}
}
// Возвращаем результат
return $query;
}
add_filter('pre_get_posts', 'ip_search_filter');
Созданный нами поисковый фильтр легко расширяется. На его основе можно создать более мощные системы сортировки поисковых результатов для WordPress-сайта.