Включение терминов пользовательской таксономии в поиск

6 окт. 2010 г., 04:06:56
Просмотры: 61.4K
Голосов: 39

У меня есть две пользовательские таксономии, применяемые к двум пользовательским типам записей. Список терминов отлично отображается на боковой панели и показывает все связанные с ними записи. Однако при поиске конкретного термина не отображаются записи, содержащие этот термин.

Пример: http://dev.andrewnorcross.com/das/all-case-studies/ Поиск термина "PQRI"

Я не получаю никаких результатов. Есть идеи? Я пробовал использовать различные поисковые плагины, но они либо нарушают мои пользовательские параметры поиска, либо просто не работают.

2
Комментарии

Nocross, можешь добавить отзыв к предложенному Яном ответу? Возможно, ты ищешь плагин, который выполнит эту задачу?

hakre hakre
6 нояб. 2010 г. 19:13:00

В итоге я отказался от этой затеи. Поскольку я создал 3 отдельных функции поиска (основанных на разных потребностях в определенных областях), все протестированные мной плагины ломали их. В конце концов, я посоветовал клиенту включать термины в контент, если он хочет, чтобы они были доступны для поиска.

Norcross Norcross
13 нояб. 2010 г. 22:25:45
Все ответы на вопрос 6
8
46

Я бы также порекомендовал плагин Search Everything, но если вы хотите реализовать это с помощью стандартной функции поиска WordPress, вот код, который я использую в своей теме Atom:

// поиск по всем таксономиям, основано на: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23

function atom_search_where($where){
  global $wpdb;
  if (is_search())
    $where .= "OR (t.name LIKE '%".get_search_query()."%' AND {$wpdb->posts}.post_status = 'publish')";
  return $where;
}

function atom_search_join($join){
  global $wpdb;
  if (is_search())
    $join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id";
  return $join;
}

function atom_search_groupby($groupby){
  global $wpdb;

  // группировка по ID записи
  $groupby_id = "{$wpdb->posts}.ID";
  if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;

  // если группировка пуста, используем нашу
  if(!strlen(trim($groupby))) return $groupby_id;

  // если не пуста, добавляем нашу
  return $groupby.", ".$groupby_id;
}

add_filter('posts_where','atom_search_where');
add_filter('posts_join', 'atom_search_join');
add_filter('posts_groupby', 'atom_search_groupby');

Этот код основан на плагине Tag-Search: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23

15 дек. 2010 г. 13:48:39
Комментарии

Это отлично! Как можно изменить этот код, чтобы исключить массив ID таксономий из поиска?

HandiworkNYC.com HandiworkNYC.com
6 янв. 2012 г. 22:23:28

Следует отметить, что функции обратного вызова для этих хуков принимают 2 аргумента; второй для всех них — это экземпляр WP_Query, который передается по ссылке. Любые проверки на is_search() или другие вызовы методов WP_Query (is_search(), is_home() и т.д.) всегда должны вызываться непосредственно на экземпляре запроса (например, $query->is_search(), предполагая, что имя переменной экземпляра — $query в сигнатуре обратного вызова), а не через функцию шаблона, которая всегда будет ссылаться на основной запрос, а не на запрос, для которого выполняется фильтр.

Evan Mattson Evan Mattson
7 июн. 2014 г. 05:55:33

Кроме того, вероятно, не лучшая идея вставлять непосредственно в SQL-запрос сырую строку поиска, доступную публично... рекомендуемая литература

Evan Mattson Evan Mattson
7 июн. 2014 г. 06:03:43

Хочу добавить, что здесь есть конфликт с WPML, потому что WPML уже использует 'T' в части join, поэтому использование чего-то кастомного вместо tr, tt и t решает эту проблему

Bobz Bobz
9 февр. 2016 г. 06:16:24

@EvanMattson — вы прокомментировали выше, что «вероятно, не лучшая идея вставлять сырую публично доступную строку поиска напрямую в SQL-запрос». Как бы вы порекомендовали устранить этот риск? Я прочитал предоставленную вами ссылку, но не понял, как это связано с исходным ответом. Большое спасибо, Em.

pjk_ok pjk_ok
5 апр. 2020 г. 04:11:42

@TheChewy в ответе выше показано использование get_search_query() напрямую в MySQL-выражении WHERE. Этот код уязвим к SQL-инъекциям, когда любой может выполнять произвольные SQL-запросы на вашем сайте, передавая их через поле поиска. Очевидно, что поисковики работают в какой-то мере именно так, но важно, чтобы этот ввод был правильно подготовлен, чтобы гарантировать, что он интерпретируется как поисковые термины, а не SQL-команды. Именно для этого предназначен метод $wpdb->prepare(), который описан в рекомендуемом чтении

Evan Mattson Evan Mattson
19 апр. 2020 г. 17:50:11

@TheChewy ты также можешь найти хорошие примеры в документации для wpdb::prepare() здесь: https://developer.wordpress.org/reference/classes/wpdb/prepare/

Evan Mattson Evan Mattson
19 апр. 2020 г. 17:52:40

@EvanMattson Привет, Эван, спасибо за совет. Я новичок и в php, и в кастомном коде WP, и это сейчас для меня слишком сложно. Не мог бы ты продублировать код с добавлением $wpdb->prepare(), если это не слишком сложно? Думаю, мне понадобятся недели, чтобы приблизиться к пониманию таких вещей.

pjk_ok pjk_ok
21 апр. 2020 г. 03:07:09
Показать остальные 3 комментариев
0

Это стандартный поиск WordPress? Потому что похоже, он не включает таксономии (даже стандартные, такие как категории и теги) в поиск. Код ищет в post_title и post_content, но если вы хотите включить что-то ещё, вам следует использовать хук posts_search.

7 окт. 2010 г. 18:56:16
0

Я попробовал решение Onetrickpony, указанное выше https://wordpress.stackexchange.com/a/5404/37612, которое отлично работает, но обнаружил одну проблему, которая не сработала в моем случае, и хотел бы внести одно небольшое изменение:

  1. если я искал строку в заголовке таксономии — это работает отлично
  2. если в таксономии есть специальные символы, например, немецкие умлауты (ö,ä,ü), и пользователь ищет oe, ae, ue вместо специальных символов — необходимо добавить поиск по слагу таксономии — OR t.slug LIKE '%".get_search_query()."%'

  3. если вы ищете комбинацию поискового запроса и фильтра таксономии — это тоже работает отлично

  4. Но проблема возникает, когда вы пытаетесь использовать только фильтр таксономии — хук поиска добавляет пустую строку к запросу, если текст не ищется, и по этой причине вы получаете ВСЕ записи в результатах, а не только те, которые относятся к отфильтрованной таксономии. Простое условие IF решает проблему. Таким образом, весь модифицированный код будет выглядеть так (работает идеально в моем случае!):

function custom_search_where($where){ 
  global $wpdb;
  if (is_search() && get_search_query())
    $where .= "OR ((t.name LIKE '%".get_search_query()."%' OR t.slug LIKE '%".get_search_query()."%') AND {$wpdb->posts}.post_status = 'publish')";
  return $where;
}

function custom_search_join($join){
  global $wpdb;
  if (is_search()&& get_search_query())
    $join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id";
  return $join;
}

function custom_search_groupby($groupby){
  global $wpdb;

  // группировка по ID записи
  $groupby_id = "{$wpdb->posts}.ID";
  if(!is_search() || strpos($groupby, $groupby_id) !== false || !get_search_query()) return $groupby;

  // если группировка пуста, используем нашу
  if(!strlen(trim($groupby))) return $groupby_id;

  // если не пуста, добавляем нашу
  return $groupby.", ".$groupby_id;
}

add_filter('posts_where','custom_search_where');
add_filter('posts_join', 'custom_search_join');
add_filter('posts_groupby', 'custom_search_groupby');
9 сент. 2013 г. 01:05:26
0

Я нашел ответ от onetrickpony отличным, но он обрабатывает любой поиск как единый термин и не работает с поисковыми фразами в кавычках. Я немного изменил его код (в частности, функцию atom_search_where), чтобы учесть эти две ситуации. Вот моя модифицированная версия его кода:

// поиск по всем таксономиям, основано на: http://projects.jesseheap.com/all-projects/wordpress-plugin-tag-search-in-wordpress-23

function atom_search_where($where){ 
    global $wpdb, $wp_query;
    if (is_search()) {
        $search_terms = get_query_var( 'search_terms' );

        $where .= " OR (";
        $i = 0;
        foreach ($search_terms as $search_term) {
            $i++;
            if ($i>1) $where .= " AND";     // --- измените на OR, если не требуется совпадение всех поисковых терминов с таксономиями
            $where .= " (t.name LIKE '%".$search_term."%')";
        }
        $where .= " AND {$wpdb->posts}.post_status = 'publish')";
    }
  return $where;
}

function atom_search_join($join){
  global $wpdb;
  if (is_search())
    $join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id";
  return $join;
}

function atom_search_groupby($groupby){
  global $wpdb;

  // группируем по ID записи
  $groupby_id = "{$wpdb->posts}.ID";
  if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;

  // если группировка пуста, используем нашу
  if(!strlen(trim($groupby))) return $groupby_id;

  // если не пуста, добавляем нашу
  return $groupby.", ".$groupby_id;
}

add_filter('posts_where','atom_search_where');
add_filter('posts_join', 'atom_search_join');
add_filter('posts_groupby', 'atom_search_groupby');
12 нояб. 2015 г. 07:52:40
1

У меня такой же уровень информации, как у Яна. Я знаю, что поиск можно расширить с помощью плагинов.

Вероятно, Search Everything (плагин для WordPress) — это то, что вам нужно. Согласно списку возможностей, он теперь поддерживает пользовательские таксономии.

6 нояб. 2010 г. 19:17:22
Комментарии

+1 за плагин Search Everything. Работает как ожидалось и возвращает больше результатов, чем стандартный поиск WordPress.

PNMG PNMG
3 дек. 2010 г. 00:00:21
0

У меня такая же проблема с плагином корзины WooCommerce... Мои результаты поиска не включают пользовательскую таксономию 'product_tag', потому что это не стандартный тег записи. Я нашел решение в другой теме на StackOverflow по этому поводу:

https://stackoverflow.com/questions/13491828/how-to-amend-wordpress-search-so-it-queries-taxonomy-terms-and-category-terms

Пример кода от tkelly сработал для меня, когда я заменил термин author в его примере на product_tag в соответствии с нашими потребностями для плагинов корзины.

8 дек. 2012 г. 23:42:36