Не так давно один из моих клиентов заказал такое задание: клиенту требовалось добавить в архивы категорий и в отдельную запись блоки навигации по меткам (тегам). Ничего сложного в этом как бы нет, однако, заказчику требовалось организовать вывод меток таким образом, чтобы в архивах конкретных рубрик выводились только соответствующие текущей рубрике метки! т.е чтобы “облако меток” выводилось не всё скопом, а только те метки, которые принадлежат конкретной категории. Такой же принцип вывода и для отдельной записи, чтобы метки выводились только из той категории, к которой относится запись…
Просил подобную фичу организовать без плагина.
Как известно, в стандартном виджете WordPress “Облако меток” возможности вывода меток для отдельной категории нет.
Короче, решение было найдено – им и делюсь с читателями:
своё облако меток для каждой отдельной категории записей
Вот, например, у меня на тестовом сайте получилось так (скриншот ниже): в разделе сайта (в категории/рубрике) “Шаблоны – описания” выведены метки, принадлежащие записям только этой категории. Т.е. все имеющиеся на сайте теги – всё их общее количество выводиться не будут – а будут отображены только те метки (теги) которые относятся к данной конкретной категории – в любой другой рубрике, будут выводиться только соответствующие ЕЙ метки!
Как и говорил выше, точно таким же образом возможно и в отдельной статье показывать только соответствующие категории статьи метки.
В принципе – это удобно для требовательного администратора.
Что нам и требовалось.
функция – код вывода меток для определённой категории
Для начала, требуется добавить в файл functions.php активного шаблона код показанный ниже (либо организуем – создадим свой плагин):
/* Выводим теги для конкретной рубрики/записи */
function get_category_tags($cats) {
// формируем запрос к базе данных
global $wpdb;
$tags = $wpdb->get_results
("
SELECT DISTINCT terms2.term_id as tag_id, terms2.name as
tag_name, t2.count as posts_count, null as tag_link
FROM
wp_posts as p1
LEFT JOIN wp_term_relationships as r1 ON
p1.ID = r1.object_ID
LEFT JOIN wp_term_taxonomy as t1 ON
r1.term_taxonomy_id = t1.term_taxonomy_id
LEFT JOIN wp_terms as terms1 ON
t1.term_id = terms1.term_id,
wp_posts as p2
LEFT JOIN wp_term_relationships as r2 ON
p2.ID = r2.object_ID
LEFT JOIN wp_term_taxonomy as t2 ON
r2.term_taxonomy_id = t2.term_taxonomy_id
LEFT JOIN wp_terms as terms2 ON
t2.term_id = terms2.term_id
WHERE
t1.taxonomy = 'category' AND
p1.post_status = 'publish' AND
terms1.term_id IN (". $cats .") AND
t2.taxonomy = 'post_tag' AND
p2.post_status = 'publish'
AND p1.ID = p2.ID
ORDER by tag_name
");
$min_size = 13; // Минимальный размер шрифта тегов
$i = 0;
/* Перебираем результаты запроса к БД в массив *
* $keys сохраняем количество статей данной рубрики, помеченных каждым из тегов
*/
foreach( $tags as $tag ) {
$keys[$i] = $tag->posts_count; // количество статей
//$i += 1; // изменение размера в зависимости от кол записей
}
/*
* Сортируем элементы массива по возрастанию. В конце самые популярные теги
*/
if ( $keys ) {
sort( $keys );
/* Перебираем все теги, используя отсортированный массив, $keys - ключи. Добьёмся при смене количества статей,
* в массиве $sizes СНОВА изменение (перезаписанного) размера шрифта. Чем больше статей - тем крупнее ШРИФТ. Шаг увеличения шрифта = 1px
*/
$i = 0;
foreach ( $keys as $key ) {
if ($i==0) { $curr_size = $min_size; $prev_key = $key; }
if ( $prev_key > $key) { $curr_size += 1; }
$sizes[$i] = $curr_size;
$prev_key = $key;
// $i += 1; // закомментить, если нужно чтоб величина тега равнялась кол. записей
}
/* Подготовка выборки окончена, теперь формируем список тегов: чем больше статей
* помеченных тем или иным тегом, тем он выводится крупнее, сортируем теги
* по алфавиту
*/
foreach($tags as $tag) {
$i = 0;
foreach ( $keys as $key ) {
if ( $tag->posts_count == $key ) {
$stil = 'style="font-size: ' . $sizes[$i] . 'px;"';
}
// $i += 1; // исключим повтор ссылки (например, статьи) - закомментировать!
}
//echo "<div class='tag-link-styles22'>"; // дополнительные стили
$out .= '<span class="tag-link-styles"><a href="'. get_tag_link($tag->tag_id) .'" // если ДИВ о будет в столбик вывод
class="tag-link-'.$tag->tag_id.'" ' .
$stil . '>'. $tag->tag_name .' </a></span>'; // разделитель - ( отделить знак запись ,) показать количество записей ('. $tag->posts_count .')
//echo "</div>"; // дополнительные стили
}
}
return rtrim($out, ', ');
}
/* Выводим теги для конкретной рубрики/записи */
Код я немного подработал и дополнил понятности ради комментариями…
1 – например, возможно сделать так, чтобы в скобках после каждого имени метки отображалось количество записей…
В финальной части кода – там, где формируется ссылка меток – можно добавить ('. $tag->posts_count .')
– в этом случае будет показано (в скобках) количество записей…
2 – …чтобы в зависимости от количества записей в разделе МЕТКИ, шрифт тега увеличивался/уменьшался… Отработка данных переменной $i += 1;
– в коде комментарии.
Код возможно сократить… однако, я его сильно кастрировать не стал, потому как у всех у нас разные потребности… Пусть каждый решает сам, что ему требуется, а что нет…
выводим метки только конкретной категории
Для того, чтобы вывести на сайте (фронтенд) СВОИ метки для каждой конкретной рубрики сайта, всего-то потребуется запросить в файлах (либо в сайдбаре) отработку функции данной выше.
Как это делается?
В то место, в котором требуется вывести, скажем так, облако меток – навигацию по тегам, следует прописать код вызова, показанный ниже:
Код прописывать в сайдбар (виджет), либо напрямую в соответствующий файл активного шаблона.
<?php
// Выводим теги конкретного раздела (рубрики), если они есть
$cat = get_the_category();
$tags = get_category_tags( $cat[0]->cat_ID );
if ( $tags != '' )
echo '' . $tags . '';
?>
Для того, чтобы вывести метки по конкретной категории (записи), к примеру, в сайдбаре, потребуется воспользоваться выджетом, который умеет работать с PHP кодом (стандартные виджеты WP такой возможности не имеют) – а посему смею предложить свой плагин Плагин widget text class ats – текстовый виджет для работы с php и шорткодами – скачивать или прямо у меня на сайте, либо – стандартно – через админку своего сайта установка плагинов “Добавить новый”.
Плагин очень простой – никаких настроек – после установки и активации, в админке, в разделе “Виджеты”, появится новый виджет, который умеет работать с PHP и шорткодами..
Что ещё… …если нам требуется дать имя блоку меток по рубрикам, то возможно при помощи оператора echo
– в коде вызова функции (данном чуть выше) организовать примерно такую строку:
как видите, пример – имя раздела “Теги”.
echo '<div class="tagCloud"><h3>Теги</h3></div>';
Возможно, будет кому-то полезна статья о том, как закрыть метки (теги) от роботов – либо nofollow либо AJAX.
Либо же – к вашим услугам плагин “Закрытых меток” по метОде AJAX…
Тем, которые не знают:
вывод блоков меток для конкретной рубрики возможно организовать и ещё более тонко (или в сайдбаре/виджете, либо в коде) – например, запретить вывод блока меток на главной странице, в конкретном архиве рубрик/меток и пр. или статье, а в каких-то иных архивах напротив – разрешить…
Если изучите статью Условные теги WordPress – полная подборка, пояснения то у вас всё получится так, как требуется для вашего бизнеса.
css для вывода меток привязанных к конкретной категории
Вот примерный CSS код для описанного в статье вывода блока меток для отдельных рубрик: код дан для примера, так что можете его смело редактировать в соответствии со стилистикой своего сайта.
.tag-link-styles a{background-color:#e9f6fc;text-decoration:none;padding:2px 2px 2px 7px;border:1px solid #CFCECE;border-radius:6px;line-height:1.8;margin-right:3px;color:#007205;
}
.tag-link-styles a:hover{color:#a43900;}
.tag-link-{display:none;}
вариант 2:
выводим метки только для конкретной рубрики
Код, показанный ниже, призван выводить метки только для текущей рубрики (раздела сайта). Таким образом функция отработает для каждой категории свои собственные метки (теги)!
Помещать в файл функций functions.php
активного шаблона и выводить в том месте, где следует… В сайдбаре или в файлах шаблона.
Внимание! в записях – код правильно работать не будет – в записях метки будут отображены все, которые имеются на сайте. Поэтому, если нужно чтобы в записях были показаны метки текущей категории, к которой относится запись, используйте код выше – ПЕРВЫЙ вариант!
/* Выводим теги ТОЛЬКО для конкретной рубрики (только в архивах) */
function get_tags_in_cat($cat_id){
$posts = get_posts( array('category' => $cat_id, 'numberposts' => -1) );//
$tags = array();
foreach($posts as $post)
{
$post_tags = get_the_tags($post->ID);
if( !empty($post_tags) )
foreach($post_tags as $tag)
$tags[$tag->term_id] = $tag->name;
}
asort($tags);
return $tags;
}
/* Выводим теги ТОЛЬКО для конкретной рубрики (только в архивах) */
…далее… вызываем функцию там, где требуется кодом, показанным ниже: (со ссылкой возможно работать по своим усмотрениям – закрыть ссылки в либо nofollow
либо AJAX – как это делается, ссылки ВЫШЕ)
<?php
$cat_id = get_query_var('cat'); // получим ID-дентификатор текущей категории
$tags = get_tags_in_cat($cat_id);
foreach($tags as $tag_id => $tag_name)
$tags_print[] = '<span class="tag-link-styles"><a title="' .$tag_name. '" href="' .get_tag_link($tag_id). '">' .$tag_name. '</a></span>';
echo implode(' ', $tags_print); // разделитель: ', ' если требуется (запятая)
?>
Код CSS использован что и для первого кода: span class="tag-link-styles"
Вот в принципе и всё, что хотелось сегодня рассказать…
Если что-то не ясно…
mihalica.ru !
Здравствуйте,а как вывести метки так:7-8 отображаются ,а остальные скрыты “сполером” и рядом кнопка “показать все метки”
Тоже интересно, не нашли информацию про сполер для меток?
это нужно в конкретном шаблоне смотреть…
в принципе не сложно скрыть в спойлер контент, но нужно решать по обстоятельствам подключения JS и прочего для конкретного шаблона…
Подскажите, а как на странице тега вывести список рубрик относящихся к этому тегу.
Спасибо, буду очень благодарен!
Привет.
Это нужно код писать…
Сиюминутного решения нет.
В общем, это задача. Потому что обычно поступают от обратного.
Божественная статья” Спасибо огромное
На здоровье, Павел!
Код отлично работает, спасибо!
Хотелось бы немного разгрузить сайт, ограничившись выводом облаков тэгов только в архивах категорий, не выводя их в постах. Не подскажете — что для этого нужно изменить в выводе?
Привет!
Это вам, насколько я понял из вопроса, нужно как-то использовать условные теги WP и все получится.
Спасибо! Благодаря вам, впервые воспользовался кондишенами и всё получилось. Облако теперь не перегружает своим присутствием посты, но отображается там, где ему место — в архивах.
Возник ещё один вопрос, если позволите. Подскажите пожалуйста конструкцию для отображения виджетов только в том случае, если они содержат данные. То есть, если им есть что показать. А то бывает, что заголовок висит на фронтэнде и скучает в одиночестве. С php-виджетом я это решил теми же условными операторами, отказавшись от заголовка виджета и добавив операторы присутствия/отсутствия заголовка в php-коде. А вот то, как глобально решить проблему — докопаться сам не смог.
На здоровье)
В вашей задаче, насколько я понял, нужно определиться – как убирать (скажем так) виджет – php либо display: none …
А вообще, как вы говорите – глобально, решать целесообразно кастомно, перестраивая ядро шаблона по выводу виджетов (некоторые юзают и полный сайдбар) – в том или ином месте… В этом случае решается и задача легкости кода (скорости загрузки стр.).
Задача решаема. Главное определиться с целями и более логичным индивидуальным решением. ЛИБО по ID-виджета скрываете виджет полностью!..
Это, если вас правильно понял…
Да, нужно скрывать виджет. Но по условию: тогда, когда ему нечего выводить. Учитывая же то, что заголовок виджета будет виден постоянно, есть вывод данных или их нет, заголовок будет висеть в одиночестве. Если делать в CSS через «display:none», то виджет закроется навсегда — даже если наворотить логики: CSS не понимает — есть данные виджета или нет. А вот php другое дело. Поэтому подошла бы конструкция, проверяющая наличие у виджета данных для вывода или их отсутствие. Таким образом, при отсутствии данных, виджет просто не выводился бы. Я перерыл массу плагинов для виджета, но они в основном предлагают стилизацию, но не выключение виджета по условиям.
Я вам уже описал в предыдущем комменте… вы, вероятно, не поняли. Либо я не ясно пояснил)
Так же и мне не ясно, чтобы помочь, – как это у вас остается Title виджета, если его вывод запрещен условием.?. (так может получится только в том случае, если условия отрабатываются внутри виджета)
Во-первых, каким именно виджетом у вас выводится облако меток?
В том-то и дело, что виджеты не предусматривают — ни «самоотключения» в отсутствие данных для вывода, ни php-кода в своих заголовках для условных операторов. На это способен лишь виджет предназначенный специально для кода.
А мне нужно, чтобы была возможность проверить виджет на сам факт вывода данных. И если данные не выводятся («пусто»), то виджет должен отключиться.
Ну, об этом я вам говорил – узнать логику вывода виджетов, тогда и решение само-собой придет.
…
Тогда нужно что-нить с кодом придумывать – код писать для ваших условий и задач.
Но в любом случае, со слов ясно только приблизительно… без визуального осмотра не вполне ясна логика вывода виджетов в шаблоне. А значит и помочь конкретным решением сложно..
Здравствуйте. А как реализовать тоже самое о чем говорится в статье, только для товарных меток woocommerce? То есть вывод меток в сайдбаре в зависимости от того, к какой категории принадлежит товара. То есть, товар находится категорий-подкатегория-подподкатегория. У него есть метка. Ну так вот во всей это цепочке в облаки меток указана метка данного товара, но в других разделах этого нет. По идее тоже самое, что вы описали только с товарными метками. Буду очень благодарен за ответ. Спасибо
Здравствуйте, Юрий! по woocommerce тоже возможно подобное организовать. В комментарии решение думаю не к месту описывать, да и тестировать нужно, потому как готового кода нет…. Напишу немного позже статью…