Блог |

Поиск по нескольким тегам сразу

Не пользы ради, а скорее истории для документирую следующее: теперь этот сайт умеет отображать время публикации поста, если их больше чем два за день, и обрабатывать запросы на поиск по двум и более тегам через URL.

Про первое рассказывать не так интересно: там всё построено на вордпрессовой функции the_date(), которая, в отличие от get_the_date(), умеет отличать первый пост за день от всех остальных. Интереснее про второе.

Я увидел поиск по двум тегам сразу в блоге Ильи Бирмана, и мне захотелось тупо повторить эту функцию у себя, просто из принципа — всё равно пользоваться ей будут полтора человека, если вообще будут. После визита в гугл оказалось, что в WordPress есть особенность, позволяющая по запросу а-ля https://site.com/tags/tag1+tag2 получать посты, где есть оба тега — и tag1, и tag2 (здесь я имею в виду, понятно, ярлыки этих тегов, а не названия). А заменив + на ,, можно бросаться похожими запросами, только не И, а ИЛИ.

Но в документации об этой особенности — ни слова. Более того, нет ни одной функции, которая бы что-то из неё извлекала, а все существующие функции, работающие с тегами, написаны так, будто искать можно только по одному тегу за раз, а по двум и более — нельзя.

Однако есть ещё функция get_query_var(), которая смотрит на ваш запрос и извлекает из него разное интересное. В том числе она умеет извлекать и список тегов. Но, зараза, извлекает его как есть, строчкой! То есть если вы перешли по ссылке https://site.com/tags/tag1+tag2get_query_var('tag') так и напишет в выводе: tag1+tag2! Хотя могла бы, ну, не знаю, сразу массив вывести, что ли.

Пришлось изобретать велосипед и вставлять его туда, где определяется заголовок <h1>:

/* Проверяем, есть ли в части запроса с тегами запятая: */
if ( strpos(get_query_var('tag'), ',') ) {
  /* Если есть, превращаем часть запроса с тегами в массив: */
  $tags_query_array_or = explode(',', get_query_var('tag'));
  foreach ($tags_query_array_or as $i => $tag) {
    if ($i !== 0) echo ' или ';
    $term = get_term_by('slug', $tag, 'post_tag');
    echo '<a href="/tags/' . $term->slug . '">' . $term->name . '</a>';
  }
} else if ( strpos(get_query_var('tag'), '+') ) {
  /* Если запятой не оказалось, ищем плюс: */
  $tags_query_array_and = explode('+', get_query_var('tag'));
  foreach ($tags_query_array_and as $i => $tag) {
    if ($i !== 0) echo ' и ';
    $term = get_term_by('slug', $tag, 'post_tag');
    echo '<a href="/tags/' . $term->slug . '">' . $term->name . '</a>';
  }
} else { // Если и плюса нет, значит, тег один, и надо просто написать его название:
  echo '<span>' . single_tag_title( '', false ) . '</span>';
}

Похожий код добавлен в функцию, обрабатывающую заголовки страниц.

Проверить, как всё это работает, можно, например, поискав посты, у которых одновременно стоит тег «как жить» и тег «Телеграм». По ссылке блог выдаст вам один пост, хотя постов с этими тегами отдельно — восемнадцать штук.

Так же можно комбинировать и три тега, и четыре, и вообще сколько угодно. Было бы что комбинировать: очевидно, эта фича заработает в полную силу, когда пройдёт лет пять, и постов на этом сайте будет несколько тысяч.

Это нововведение — из серии «ума не приложу, кому это может быть надо, но делать было интересно». Возможно, это же относится и к сайту в целом.

Впрочем, один use case у него всё же есть: как и на теги поодиночке, на комбинации тегов можно подписываться по RSS, добавив к адресу /feed. Например, вот ссылка на фид постов с одним из упомянутых выше тегов.

Комментировать

Комментировать