Включение категорий в результаты поиска
Я пытаюсь включить категории в результаты поиска. Я искал решение уже несколько часов, но безуспешно.
Под "включением категорий" я не имею в виду поиск в определенной категории. Например, у меня есть веломагазин с множеством компаний на сайте; пользователь ищет BMX горный кросс
. В результатах должна первой отображаться категория BMX (при клике происходит переход на страницу категории), а затем записи, связанные с поисковым запросом, как обычно это делает WordPress.
Есть ли у кого-нибудь идеи или может кто-то направить меня в правильном направлении?
Используйте get_terms()
, тогда вам не понадобится делать кастомный запрос к базе данных.
$terms = get_terms( 'category', array(
'name__like' => $s,
'hide_empty' => true // Опционально
) );
if ( count($terms) > 0 ){
echo '<ul>';
foreach ( $terms as $term ) {
echo '<li><a href="' . esc_url( get_term_link( $term ) ) . '" title="' . esc_attr( $term->name ) . '">' . esc_html( $term->name ) . '</a></li>';
}
echo '</ul>';
}
Основано на ответе birgire на аналогичный вопрос: https://wordpress.stackexchange.com/a/239680/50432

Я использую этот код в своем файле search.php перед основным циклом:
$search_term = explode( ' ', get_search_query( false ) );
global $wpdb;
$select = "
SELECT DISTINCT t.*, tt.*
FROM wp_terms AS t
INNER JOIN wp_term_taxonomy AS tt
ON t.term_id = tt.term_id
WHERE tt.taxonomy IN ('category')";
$first = true;
foreach ( $search_term as $s ){
if ( $first ){
$select .= " AND (t.name LIKE '%s')";
$string_replace[] = '%'.$wpdb->esc_like( $s ).'%';
$first = false;
}else{
$select .= " OR (t.name LIKE '%s')";
$string_replace[] = '%'. $wpdb->esc_like( $s ).'%';
}
}
$select .= " ORDER BY t.name ASC";
$terms = $wpdb->get_results( $wpdb->prepare( $select, $string_replace ) );
if ( count($terms) > 0 ){
echo '<ul>';
foreach ( $terms as $term ) {
echo '<li><a href="'.esc_url( get_term_link( $term ) ).'" title="'.esc_attr( $term->name ).'">' . esc_html( $term->name ) . '</a></li>';
}
echo '</ul>';
}
Этот код выполняет дополнительный запрос к базе данных, но ищет категории не только связанные с найденными записями, а делает дополнительный поиск по каждому слову из поискового запроса и выводит все найденные категории - даже пустые.

Я создал страницу с пользовательскими результатами поиска, которая сопоставляет ключевое слово(а) с категориями, записями, пользовательскими типами записей (CPT)...
Вот код для категорий (он также отображает поле ACF категории для изображений):
<?php
// категории записей в результатах
$terms = get_terms( 'post', array(
'name__like' => $s,
'hide_empty' => false // Необязательно
) );
?>
<?php
// список категорий записей в результатах
if ( count($terms) > 0 ) {
echo '<div class="sr-categories">';
echo '<h3 class="search-title">Результаты по категориям</h3>';
?>
<div class="posts-wrap posts-layout-default row">
<?php
foreach ( $terms as $term ) { ?>
<?php
echo '<article class="sub-cat-row col-md-4 col-sm-6 col-xs-6 col-xxs-12">';
echo '<a href="' . esc_url( get_term_link( $term ) ) . '" title="' . esc_attr( $term->name ) . '">';
$taximg_id = get_field('image', $term);
$taxsize = "grid-image"; // (thumbnail, medium, large, full или пользовательский размер)
$taximage = wp_get_attachment_image_src( $taximg_id, $taxsize );
if($taximg_id) { ?>
<img src="<?php echo $taximage[0]; ?>" alt="" class="img-responsive" />
<?php } else { ?>
<img src="<?php echo get_stylesheet_directory_uri(); ?>/assets/images/default-image-600x400.png" alt="" title="" />
<?php }
echo '<div class="sc-title text-center">' . esc_html( $term->name ) . '</div></a>';
echo '</article>';
//get_template_part('template-parts/loop/content','listevents');
wp_reset_postdata();
}
?>
</div>
<?php echo '</div>'; // конец sr-events
} else {
echo 'Категории событий не найдены';
}
?>

Очевидно, это возможно. Если у вас используется тема TwentyTwelve, вам нужно отредактировать файл search.php
. Там вы найдете цикл:
<?php while ( have_posts() ) : the_post(); ?>
<?php get_template_part( 'content', get_post_format() ); ?>
<?php endwhile; ?>
Итак, цикл использует post_format()
. Поэтому вам нужно отредактировать content.php
. Там вы найдете следующее:
<?php if ( is_search() ) : // Отображаем только краткое описание для поиска ?>
<div class="entry-summary">
<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
Просто замените это на:
<?php if ( is_search() ) : // Отображаем только краткое описание для поиска ?>
<div class="entry-summary">
<?php the_category(); ?><br/>
<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
Если всё пойдет правильно, то это выведет категорию, связанную с результатом поиска. Но только если всё пойдет так, как мы хотим. :)

Основываясь на ответе @PhilOwen, я добавил следующий код в начало файла темы search.php:
// категории записей в результатах поиска
$terms = get_terms( 'taxonomy-goes-here', array(
'name__like' => $s,
'hide_empty' => false // Необязательно
) );
if ( count($terms) > 0 ) {
foreach ( $terms as $term ) {
echo '<h2><a href="' . esc_url( get_term_link( $term ) ) . '" title="' . esc_attr( $term->name ) . '">';
echo esc_html( $term->name );
echo '</a></h2>';
}
}
Я считаю, что часто имеет смысл показывать совпадения таксономий (если они есть) выше отдельных элементов, так как они находятся выше в иерархии данных.

Я нашел лучший способ и хотел поделиться не нужно использовать $wpdb этот код работает у меня:
$val = get_search_query(); // Получаем поисковый запрос
$categories = get_terms( ['taxonomy' => 'product_cat'] ); // Получаем все категории товаров
foreach($categories as $cat){ // Перебираем категории
if (stristr($cat->name , $val)){ // Проверяем, содержится ли поисковый запрос в названии категории (без учета регистра)
echo '<tr><td><a href="'.get_term_link( $cat ).'" >' .$cat->name.'</a></td></tr>'; // Выводим ссылку на категорию
break; // Прерываем цикл после первого совпадения
}
Этот код ищет в категориях товаров, и совпадение не обязательно должно быть точным

Я видел некоторые ответы с использованием get_terms()
, что неплохо, но я предпочитаю обращаться к источнику, поэтому вот что я придумал, используя класс WP_Term_Query
из исходного кода @ https://github.com/WordPress/wordpress-develop/blob/6.7/src/wp-includes/class-wp-term-query.php#L96:
$product_category_query = new WP_Term_Query(array(
'number' => 10,
'orderby' => 'name',
'order' => 'ASC',
'search' => $search_input_value,
'taxonomy' => array('product_cat'),
));
Затем можно пройтись по результатам в цикле:
<ul>
<?php foreach($product_category_query->terms as $term) : ?>
<li><a href="<?php echo get_term_link($term); ?>"><?php echo $term->name; ?></a></li>
<?php endforeach; ?>
</ul>

ПРОБЛЕМА: Начиная с марта 2022 года WordPress не осуществляет поиск по категориям или меткам.
РЕШЕНИЕ/ОБХОДНОЙ ПУТЬ: Используйте плагин для включения поиска по категориям или меткам. Я протестировал это с бесплатной версией плагина Relevanssi. https://www.relevanssi.com/features/. Другие плагины также могут работать.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не связан с Relevanssi или любым другим разработчиком плагинов для поиска в WordPress.

WordPress никогда не выполнял поиск по названиям или описаниям категорий, меток (или любого другого типа таксономий). Именно об этом вопрос. Ответ "используйте плагин" очевиден, но он мало что добавляет и не соответствует духу ожидаемых ответов на этом сайте.
