Как создать фильтр результатов поиска в 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-сайта.

 

Пожалуйста, опубликуйте ваши мнения по текущей теме материала. За комментарии, дизлайки, отклики, подписки, лайки низкий вам поклон!

Пожалуйста, оставляйте свои комментарии по текущей теме статьи. Мы очень благодарим вас за ваши комментарии, лайки, дизлайки, отклики, подписки!

Сергей Бензенкоавтор-переводчик статьи «How to Make a Search Results Filter in WordPress»