Расширенная форма поиска с фильтрами для пользовательских таксономий и произвольных полей
Я хочу создать расширенную форму поиска для определенного произвольного типа записей с фильтрами по пользовательским полям, таксономиям и свойствам (полям и таксономиям) отдельного произвольного типа записей, которые будут связаны с первым типом записей через поле отношений.
Я недавно начал работать с произвольными типами записей, полями и таксономиями WordPress. Мне это очень нравится, но для максимальной эффективности я хотел бы иметь возможность правильно осуществлять поиск. Нужно ли делать это вручную? Если да, то как?
PS. Если это важно, я использую плагины: Advanced Custom Fields и Custom Post Type UI.
Ниже я создал макет примера того, как будет выглядеть фильтрация и как она может быть связана с вышеуказанными типами записей.
Думаю, что подобное лучше написать самостоятельно.
Посмотрите пример: http://www.catalysthomes.co.uk/homes-for-sale/
Объекты загружаются в пользовательский тип записи (CPT), а в боковой панели у меня реализован собственный поиск. Этот поиск учитывает несколько параметров, таких как таксономии, произвольные поля, а также сортировку по дате, цене и т.д.
Как это реализовано? Форма отправляется на шаблон страницы, где я обрабатываю данные и формирую новый WP_Query на основе критериев поиска. Для хранения параметров поиска и последующей пагинации результатов использую сессии.
WP_Query очень мощный инструмент. Ознакомьтесь с документацией: http://codex.wordpress.org/Class_Reference/WP_Query
Вы можете использовать meta_query
для запроса нескольких произвольных полей и tax_query
для работы с таксономиями, а также многое другое. Ниже пример реализации для наглядности.
Файл шаблона:
<?php
$temp = $wp_query;
$wp_query = NULL;
$args = array();
?>
<?php include("functions/Homes-for-sale/propertyrawresults.php"); ?>
<?php include("functions/Homes-for-sale/propertysearchresults.php"); ?>
<?php
$args['post_type'] = "homes-for-sale";
$args['showposts'] = 10;
$args['paged'] = $paged;
$wp_query = new WP_Query($args);
?>
<?php include("functions/Homes-for-sale/propertylistlayout.php"); ?>
Обработка сортировки
<?php
if($_POST['sortby']) {
$_SESSION['prop_selectedsortby'] = $_POST['sortby'];
}
switch($_SESSION['prop_selectedsortby']) {
case "name-asc": $args['order'] = "ASC"; $args['orderby'] = "title"; break;
case "name-desc": $args['orderby'] = "title"; break;
case "price-asc": $args['order'] = "ASC"; $args['orderby'] = "meta_value_num"; $args['meta_key'] = "chb_homes_for_sale_specifics_fmv"; break;
case "price-desc": $args['orderby'] = "meta_value_num"; $args['meta_key'] = "chb_homes_for_sale_specifics_fmv"; break;
case "date-asc": $args['order'] = "ASC"; break;
default: /* Аргументы не требуются, используются значения по умолчанию WP_Query */ break;
}
$selectedsortby[$_SESSION['prop_selectedsortby']] = " selected=\"selected\"";
?>
Параметры поиска
<?php
if( ! empty( $_SESSION['s_property_ptype'] ) ) {
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_types_nbrs',
'value' => $_SESSION['s_property_ptype']
);
}
if( ! empty( $_SESSION['s_property_development'] ) ) {
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_ofdevelopment',
'value' => $_SESSION['s_property_development']
);
}
if( isset( $_SESSION['s_property_area'] ) && 0 != $_SESSION['s_property_area'] ) {
$args['tax_query'][] = array(
'taxonomy' => 'areas',
'field' => 'id',
'terms' => array( (int) $_SESSION['s_property_area'] ),
);
}
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_specifics_bedrooms',
'value' => $_SESSION['s_property_bedrooms_min'],
'compare' => '>=',
'type' => 'SIGNED'
);
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_specifics_bedrooms',
'value' => $_SESSION['s_property_bedrooms_max'],
'compare' => '<=',
'type' => 'SIGNED'
);
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_specifics_bathrooms',
'value' => $_SESSION['s_property_bathrooms_min'],
'compare' => '>=',
'type' => 'SIGNED'
);
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_specifics_bathrooms',
'value' => $_SESSION['s_property_bathrooms_max'],
'compare' => '<=',
'type' => 'SIGNED'
);
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_specifics_fmv',
'value' => $_SESSION['s_property_min_price'],
'compare' => '>=',
'type' => 'SIGNED'
);
$args['meta_query'][] = array(
'key' => 'chb_homes_for_sale_specifics_fmv',
'value' => $_SESSION['s_property_max_price'],
'compare' => '<=',
'type' => 'SIGNED'
);
?>
Вывод результатов Стандартный цикл WordPress для отображения анонсов записей и информации.

Привет, Брэди. Спасибо за этот пример. Могу я попросить тебя, если возможно, поделиться формой? В ней, на какой URL ты её отправляешь?

@salocin - Эту информацию можно получить, посмотрев исходный код страницы по указанному URL в ответе

Форма находится на сайте catalysthomes.co.uk. Вы можете просмотреть исходный код и увидеть, как работает форма

Попробуйте плагин Taxonomy Picker вместе с Relevanssi. Убойная комбинация.
http://www.squidoo.com/taxonomy-picker-wordpress-plugin http://wordpress.org/extend/plugins/relevanssi/

Ознакомьтесь с плагином Relevanssi, возможно, он предоставит нужный вам функционал: http://wordpress.org/extend/plugins/relevanssi/

Если у кого-то возникли трудности с реализацией решения Брейди (как и у меня), вот подсказка: похоже, что у WordPress есть проблемы с передачей данных сессии, поэтому вам, вероятно, придется сделать что-то дополнительное, чтобы это работало правильно. Эти вопросы обсуждаются здесь.
В functions.php:
function init_sessions() {
if (!session_id()) {
session_start();
}
}
add_action('init', 'init_sessions');
В вашем шаблоне:
/**
* Включение сессий
*/
if (!session_id())
session_start();
В моем случае помогло установка плагина Питера Вустера "Simple Session Support".

Привет, Стив. Спасибо за твой первый ответ здесь. Рады видеть тебя на WPSE. Для будущих заметок: ответы не должны полностью зависеть от внешних ссылок. Если ссылка станет нерабочей, твой ответ потеряет ценность. Не мог бы ты обновить свой ответ, добавив пару примеров соответствующего кода?
