Создание формы поиска для произвольных полей
Я разработал тему для автосалона. Каждый автомобиль представлен как произвольный тип записи ("vehicle") и имеет около 12 произвольных полей, таких как Марка, Модель, Пробег, Тип топлива и т.д.
В общем, на главной странице я хочу создать форму поиска с выпадающими списками для Марки и Модели, которые содержат все доступные марки и модели.
Также я хочу добавить 2 поля для Года, чтобы пользователь мог выбрать "2006" и "2012", а результаты поиска показывали все автомобили, год выпуска которых находится между этими двумя значениями.
Существует ли плагин, который может это реализовать?
Спасибо за любую помощь... я уже несколько часов ломаю над этим голову!!!!

Хотя ответ @MayeenulIslam может работать, я считаю, что правильный способ реализации расширенного поиска - это использование хука действия pre_get_posts
.
Шаг 1: Форма поиска
Этот шаг аналогичен шагу 1 в другом ответе, просто изменен id
поля name
(<input type="text" ...>
), используемого для поиска, на "s", чтобы оно использовалось напрямую как поле поиска.
Сохраните этот код в advanced-searchform.php
в папке вашей темы. Затем используйте get_template_part( 'advanced', 'searchform' );
для загрузки формы там, где вам нужно:
<?php /**`advanced-searchform.php`*/ ?>
<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<h3><?php _e( 'Расширенный поиск', 'textdomain' ); ?></h3>
<!-- ЭТО ПЕРЕДАЕТСЯ ДЛЯ АКТИВАЦИИ СТРАНИЦЫ РЕЗУЛЬТАТОВ РАСШИРЕННОГО ПОИСКА ИЗ functions.php -->
<input type="hidden" name="search" value="advanced">
<label for="s" class=""><?php _e( 'Название: ', 'textdomain' ); ?></label><br>
<input type="text" value="" placeholder="<?php _e( 'Введите название автомобиля', 'textdomain' ); ?>" name="s" id="name" />
<label for="model" class=""><?php _e( 'Выберите модель: ', 'textdomain' ); ?></label><br>
<select name="model" id="model">
<option value=""><?php _e( 'Выберите...', 'textdomain' ); ?></option>
<option value="model1"><?php _e( 'Модель 1', 'textdomain' ); ?></option>
<option value="model2"><?php _e( 'Модель 2', 'textdomain' ); ?></option>
</select>
<input type="submit" id="searchsubmit" value="Поиск" />
</form>
Шаг 2: Добавление фильтров к поисковому запросу
add_action( 'pre_get_posts', 'advanced_search_query' );
function advanced_search_query( $query ) {
if ( isset( $_REQUEST['search'] ) && $_REQUEST['search'] == 'advanced' && ! is_admin() && $query->is_search && $query->is_main_query() ) {
$query->set( 'post_type', 'vehicle' );
$_model = $_GET['model'] != '' ? $_GET['model'] : '';
$meta_query = array(
array(
'key' => 'car_model', // предполагается, что ваш meta_key это 'car_model'
'value' => $_model,
'compare' => 'LIKE', // находит модели, соответствующие 'model' из выпадающего списка
)
)
);
$query->set( 'meta_query', $meta_query );
}
}
Шаг 3: Шаблонизация (опционально)
При таком подходе будет использоваться стандартный шаблон поиска WordPress с фильтрацией результатов без необходимости дополнительного запроса. Если вы хотите использовать другой шаблон для расширенного поиска, вы можете использовать фильтр template_include
. Например, если вы хотите использовать файл advanced-search-template.php
в качестве шаблона для результатов расширенного поиска:
add_action('template_include', 'advanced_search_template');
function advanced_search_template( $template ) {
if ( isset( $_REQUEST['search'] ) && $_REQUEST['search'] == 'advanced' && is_search() ) {
$t = locate_template('advanced-search-template.php');
if ( ! empty($t) ) {
$template = $t;
}
}
return $template;
}

______ОБНОВЛЕНИЕ_______
Хотя я получаю все больше голосов, и решение работает, но ответ cybmeta на самом деле является правильным и соответствует методологии WordPress. Вам определенно стоит попробовать этот вариант.
Шаг 1
Начните с создания расширенной формы поиска, с которой будет взаимодействовать пользователь, и сохраните ее под определенным именем (например, я сохранил как advanced-searchform.php
— но не сохраняйте как searchform.php
, иначе она заменит стандартную форму поиска WordPress):
<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<h3><?php _e( 'Расширенный поиск', 'textdomain' ); ?></h3>
<!-- ЭТОТ ПАРАМЕТР ЗАПУСКАЕТ СТРАНИЦУ РЕЗУЛЬТАТОВ РАСШИРЕННОГО ПОИСКА ИЗ functions.php -->
<input type="hidden" name="search" value="advanced">
<label for="name" class=""><?php _e( 'Название: ', 'textdomain' ); ?></label><br>
<input type="text" value="" placeholder="<?php _e( 'Введите название автомобиля', 'textdomain' ); ?>" name="name" id="name" />
<label for="model" class=""><?php _e( 'Выберите модель: ', 'textdomain' ); ?></label><br>
<select name="model" id="model">
<option value=""><?php _e( 'Выберите...', 'textdomain' ); ?></option>
<option value="model1"><?php _e( 'Модель 1', 'textdomain' ); ?></option>
<option value="model2"><?php _e( 'Модель 2', 'textdomain' ); ?></option>
</select>
<input type="submit" id="searchsubmit" value="Поиск" />
</form>
Затем вызовите форму в вашем шаблоне следующим образом:
<?php get_template_part( 'advanced', 'searchform' ); ?>
Теперь ваша форма поиска готова, и вы можете использовать ее для получения пользовательского ввода через URL.
Шаг 2
Теперь вам нужно: выполнить запрос к базе данных и проверить записи и их произвольные поля согласно поисковому запросу. Помните, что ваш поисковый запрос теперь находится в URL после отправки формы. Скажите WordPress загружать вашу собственную страницу результатов поиска при отправке формы. Добавьте следующую функцию в ваш functions.php
, чтобы она использовала ваш шаблон вместо стандартного search.php
:
<?php
function wpse_load_custom_search_template(){
if( isset($_REQUEST['search']) == 'advanced' ) {
require('advanced-search-result.php');
die();
}
}
add_action('init','wpse_load_custom_search_template');
?>
Я нашел этот код где-то на WPSE (забыл источник), но есть споры по поводу его использования. Однако он работает (хотя это слабое оправдание).
Проверьте альтернативный способ, предложенный @G.M.
Шаг 3
Создайте новый файл и сохраните его как advanced-search-result.php
(потому что мы использовали это имя в functions.php
), и теперь вы свободны. Концепция такова:
- Получите данные из URL,
- Используйте простой
WP_Query()
(если ваш запрос сложный, используйте$wpdb
), - Передайте параметры в запрос, получите данные из базы,
- Покажите результат[ы]
Пример может быть таким:
<?php
// Получаем данные из URL в переменные
$_name = $_GET['name'] != '' ? $_GET['name'] : '';
$_model = $_GET['model'] != '' ? $_GET['model'] : '';
// Формируем запрос
$v_args = array(
'post_type' => 'vehicle', // ваш CPT
's' => $_name, // ищет по ключевому слову из поля 'name'
'meta_query' => array(
array(
'key' => 'car_model', // предполагается, что ваш meta_key — 'car_model'
'value' => $_model,
'compare' => 'LIKE', // ищет модели, совпадающие с выбранной в поле
),
)
);
$vehicleSearchQuery = new WP_Query( $v_args );
// Раскомментируйте для отладки запроса
// var_dump($vehicleSearchQuery->request);
// Показываем результаты
if( $vehicleSearchQuery->have_posts() ) :
while( $vehicleSearchQuery->have_posts() ) : $vehicleSearchQuery->the_post();
the_title(); // Предполагается, что названия авто — это заголовки записей CPT
endwhile;
else :
_e( 'Извините, ничего не найдено по вашему запросу', 'textdomain' );
endif;
wp_reset_postdata();
?>
Итак, вот ваш окончательный вариант. Однако остаются некоторые сложности:
- Альтернативные значения — расширенный поиск может выполняться по ВСЕМ полям или ЛЮБОМУ из них, поэтому убедитесь, что запрос учитывает все параметры поиска. Для сложных запросов можно использовать
$wpdb
и чистый SQL — здесь WordPress уже не участвует. - Санитизация и валидация — текстовые поля уязвимы и могут нанести вред вашему сайту. Передавайте только проверенные данные. (Санитизация и валидация данных в WordPress - TutsPlus)
- Дизайн — вы можете использовать шаблон
page.php
(илиsearch.php
) для оформления этой страницы.
Итак, вы поняли идею, теперь ваша очередь исследовать и находить свой путь. Помните, у каждого свой путь. Создайте свой, чтобы мне было у кого учиться. :)

Спасибо, что уделили время, это очень любезно с вашей стороны. Вы не знаете, как сделать так, чтобы выпадающее меню "Марки" автоматически отображало все марки, которые были введены в одном из постов о транспортных средствах?

Вы не знаете, как сделать так, чтобы выпадающее меню "Марки" автоматически отображало все марки, которые были введены в одном из постов о транспортных средствах?

используйте WP_Query()
с параметрами произвольных полей и организуйте цикл для вывода элементов <option>
.
