Поиск по алфавиту и содержимому в WordPress?
Добрый день! Вопрос следующего характера! Допустим, есть страница на wordpress на странице есть поиск по алфавиту, но хотелось бы сделать еще поиск по содержимому. Как такое можно реализовать? Понятно, что все идет к wp_query, на вот как сделать так, что-бы возвращалась информация и из таблицы с содержимым?
Заранее благодарен за ответ.
Дополнительно
Добрый день! Ищем информацию в таблицах!
Прилагаю скрин того, что мы ищем!
Есть, алфавитный поиск! Как сделать там, что-бы искало не только по алфавитному но по примеру таблицы, которая на скриншоте?
- А
- Б
- В
- Г
- Д
- Е
- Ж
- З
- И
- К
- Л
- М
- Н
- О
- П
- Р
- С
- Т
- У
- Ф
- Х
- Ц
- Ч
- Ш
- Щ
- Э
- Ю
- Я
- ВСЕ
<?php
function getRaoMemberTemplate( $title, $content ) {
$result = <<<"END"
$title
$content
END;
return ( $result );
}
$p = isset( $_GET[ 'p' ] ) ? $_GET[ 'p' ] : 'А';
$like = isset( $_GET[ 'like' ] ) ? $_GET[ 'like' ] : NULL;
if(is_string($like)) {
$like = trim(mb_strtolower($like));
}
global $wpdb;
$query = "SELECT p.* FROM $wpdb->posts AS p inner join $wpdb->postmeta AS pm ON pm.post_id = p.id WHERE post_type = 'page' AND pm.meta_key = '_wp_page_template' AND pm.meta_value = 'template/templ-online-reg-psy111.php'";
if(is_string($like)) {
$likeValue = '%' . $wpdb->esc_like($like) . '%';
$likeQuery = " AND LOWER( post_content ) LIKE %s";
$query .= $wpdb->prepare($likeQuery, $likeValue);
}
$rows = $wpdb->get_results( $query );
foreach($rows as $post){
echo getRaoMemberTemplate( $post->post_title, $post->post_content );
}
if(!$rows) {
echo "Не найдено: '" . ($like ? $like: $p) . "'";
}
?>
Вот такой вот код! С ним, поиск по полям работает, но вешается алфавитный, возвращаю назад старый код, работает алфавитный и не работает по полям.
Ответы:
А что ищете то? Есть шикарный плагин Search & Filter - от Code Amp
https://ru.wordpress.org/plugins/search-filter/
И более крутой но платный аналог
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос

Алфавитный фильтр и поиск по содержимому нужно объединять в одном запросе, а не переключать один код на другой. В вашем примере есть ещё одна опасная деталь: GET-параметр p лучше не использовать, потому что в WordPress p уже занят под ID записи. Из-за этого можно получить странное поведение запроса и конфликт с основным роутингом. Назовите параметр буквы, например letter, а поисковую строку q или like.
Если страницы выбираются по шаблону, а искать нужно и по заголовку, и по содержимому страницы, и по данным из произвольных полей, можно сделать один SQL-запрос через wpdb. Важно использовать prepare и esc_like, иначе поиск легко превратить в SQL-инъекцию. Ниже пример для ваших страниц с шаблоном template/templ-online-reg-psy111.php.
global $wpdb; $letter = isset($_GET['letter']) ? sanitize_text_field(wp_unslash($_GET['letter'])) : ''; $letter = mb_substr($letter, 0, 1); $q = isset($_GET['q']) ? trim(sanitize_text_field(wp_unslash($_GET['q']))) : ''; $joins = ' INNER JOIN ' . $wpdb->postmeta . ' AS pm_tpl ON pm_tpl.post_id = p.ID '; $where = array( $wpdb->prepare('p.post_type = %s', 'page'), $wpdb->prepare('p.post_status = %s', 'publish'), $wpdb->prepare('pm_tpl.meta_key = %s', '_wp_page_template'), $wpdb->prepare('pm_tpl.meta_value = %s', 'template/templ-online-reg-psy111.php'), ); if ($letter !== '' && $letter !== 'Все') { $where[] = $wpdb->prepare('p.post_title LIKE %s', $wpdb->esc_like($letter) . '%'); } if ($q !== '') { $joins .= ' LEFT JOIN ' . $wpdb->postmeta . ' AS pm_search ON pm_search.post_id = p.ID '; $like = '%' . $wpdb->esc_like($q) . '%'; $where[] = $wpdb->prepare( '(p.post_title LIKE %s OR p.post_content LIKE %s OR pm_search.meta_value LIKE %s)', $like, $like, $like ); } $sql = 'SELECT DISTINCT p.* FROM ' . $wpdb->posts . ' AS p ' . $joins . ' WHERE ' . implode(' AND ', $where) . ' ORDER BY p.post_title ASC'; $rows = $wpdb->get_results($sql);
Дальше выводите результат тем же шаблоном, который у вас уже есть:
foreach ($rows as $row) { echo getRaoMemberTemplate($row->post_title, apply_filters('the_content', $row->post_content)); } if (! $rows) { echo 'Не найдено: ' . esc_html($q !== '' ? $q : $letter); }
Логика такая: если выбрана буква, добавляется условие post_title LIKE А%. Если введена поисковая фраза, добавляется поиск по заголовку, post_content и meta_value. Если выбрано Все, буквенное условие не добавляется, и поиск идёт по всему набору страниц с нужным шаблоном. DISTINCT нужен потому, что у одной страницы может быть несколько строк postmeta, и без DISTINCT одна и та же страница может повториться.
Для небольшого справочника на 10-100 страниц этот вариант нормальный. Главное не смешивать параметр p, не собирать SQL из сырых $_GET и не делать два независимых запроса, которые перетирают результат друг друга.