l

WordPress, рубрики и облако тэгов

02.10.2014 7796 Пишу 8 комментариев wordpress, компьютерный практикум, облако тегов, свои функции

Те из вас, друзья мои, кто уже занимался сайтами на вордпрессе, наверняка сталкивались с тем, как в нём реализованы облака тэгов. И всё-таки я попробую в этой статье перечислить некоторые возможности их использования. Оговорюсь, в моей реализации вордпресса (сейчас это — русская версия 4.0) виджет по-умолчанию называется «Облако меток», хотя в английской версии это привычные всем «Tag Cloud».

Вариант первый — виджет в сайдбаре

Позвольте мне не вдаваться подробно в то, как на сайтах регистрируются сайдбары. Эта тема выходит за рамки данной статьи. Будем считать, что вы или уже знаете как его зарегистрировать, или используете у себя на сайте тему от сторонних разработчиков, в которой он уже есть. Я не считаю нужным сейчас об этом писать ещё и потому, что в сети и так полно сайтов, где это объясняется. Впрочем, возможно, это тема одной из будущих статей.

Приведу в пример собственный сайт.

Виджеты в сайдбаре

На иллюстрации видно, что в теме уже есть сайдбар и называется он «Боковая колонка 1». Достаточно блок «Облако меток» перетащить мышкой в «Боковую колонку 1» и поместить его выше или ниже среди уже установленных там виджетов. Затем лишь останется указать заголовок вашему виджету и выбрать один из вариантов доступных таксономий. Этим виджетом, вообще говоря можно, разместить в сайдбаре или облако тэгов, или список рубрик вашего сайта.

Плюсом данного варианта является простота и наглядность его использования.

Вариант второй — функция the_widget( )

the_widget( $widget, $instance = array(), $args = array() );

Вариант с использованием этой функции интереснее первого хотя бы тем, что функцию можно разместить в любом месте шаблона вашего сайта, а не только в сайдбаре. Кроме того, этой функции можно передать значительно больше аргументов — настроек. Разберем её чуть подробнее.

Первый же параметр — $widget — строка, позволяет указать какой именно виджет мы хотим разместить — список стандартных виджетов вордпресса достаточно обширен:

WP_Widget_Archives — Помесячный архив,
WP_Widget_Calendar — Календарь,
WP_Widget_Categories — Рубрики,
WP_Widget_Meta — Мета,
WP_Widget_Pages — Страницы,
WP_Widget_Recent_Comments — Свежие комментарии,
WP_Widget_Recent_Posts — Свежие записи,
WP_Widget_RSS — RSS,
WP_Widget_Search — Поиск,
WP_Widget_Tag_Cloud — Облако меток,
WP_Widget_Text — Текст,
WP_Nav_Menu_Widget — Произвольное меню.

В нашем случае мы будем использовать вариант «WP_Widget_Tag_Cloud». Позвольте мне не рассказывать в этой статье об остальных виджетах и их параметрах. В интернете полно сайтов, начиная с Кодекса вордпресса, где перечислены все стандартные функции и передаваемые им аргументы.

В переменной $instance — массив или строка, можно передать заголовок для виджета и таксономию (всё-таки облако тегов или рубрики сайта нужно выводить).

В переменной $args — массив или строка, можно передать оформление заголовка виджета и кое-какие параметры ещё. На них я тоже не буду подробно останавливаться.

Стоит для наглядности привести пример использования этой функции для вывода облака тегов:

<?php $instance = array (
    'title' => 'Облако тегов',
    'taxonomy' => 'tags'
);
$args = array (
    'before_widget' => '<div class="widget">',
    'after_widget' => '</div>',
    'before_title' => '<h3>',
    'after_title' => '</h3>'
);
the_widget( 'WP_Widget_Tag_Cloud', $instance, $args ); ?>

Плюс данного варианта я описал в самом начале — его можно использовать в любом месте шаблона сайта, даже если у вас в теме совсем нет сайдбаров. И подключать можно любой из доступных виджетов.

О минусах

Минусов у обоих вариантов только два — облако тегов выводится целиком и ограничивается 45 самыми популярными тегами.

Сначала поясню второе. Если окажется, что у вас на сайте будет очень много различных тегов, то виджет, вызванный любым из двух вариантов покажет только 45 самых популярных из них — те, которыми помечено наибольшее количество ваших статей. Остальные, менее популярные теги, просто не будут показываться в общем списке до тех пор, пока помеченных ими статей, не станет достаточно много. Согласен, не у всех так много тегов и кому-то может даже понравиться такая соревновательность. Кроме того, порывшись в движке, всегда можно найти файл, где указано это ограничение и рамки несколько раздвинуть — просто сменить 45 на любое удобное вам число. У этого метода в свою очередь есть только один минус. При обновлении движка, вордпресс сотрёт ваши изменения и снова сделает ограничение равным сорока пяти.

Теперь я поясню, что значит для меня «облако тегов выводится целиком». Возможно, для кого-то это совсем не минус. В самом деле, если вы используете движок вордпресс только для ведения собственного блога, то и фиг бы с ним, общее облако для любых рубрик вашего сайта вам не помешает. Но на своей домашней страничке я веду по крайней мере два раздела, где использую теги. Это раздел статей «Пишу» и фотоальбом «Снимаю». (Позже добавилась ещё рубрика «Видеоролики»).

Вариант третий — своё облако тегов для каждой рубрики

С ростом количества тегов мне расхотелось смешивать теги разных рубрик (разделов сайта), в одно общее облако. Появилось желание реализовать его так, чтобы у каждой рубрики показаны были только собственные теги. Из поисков информации по этой теме я понял, что данным вопросом озадачивался не я один. Собственно статейка эта и затеяна ради этого третьего варианта облака тегов. Прежде всего, потратив какое-то время, я нашел в интернете написанную кем-то функцию (автор мне не известен, к сожалению), которая как раз позволяла вывести теги только для конкретной рубрики. Ликовал я не долго, ибо, хотя функция и работала как было заявлено, но выводила она теги единым стилем и размером. Мне же, избалованному тем, как работает стандартный виджет, хотелось, чтобы более популярные теги выводились более крупным шрифтом, менее популярные — мелким. В итоге, функцию я переписал и доработал так, что теперь она во-первых: выводит облако тегов только для указанной рубрики; во-вторых: в скобочках после названия тега показано количество статей, этим тегом отмеченных; и, наконец, в-третьих: Теги в зависимости от популярности выводятся разными размерами шрифта.

Далее приведена функция целиком.

<?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;
    }
    
    /* Если теги у раздела есть и массив не пуст! (Изменение от 30.01.2015)      *
     * Сортируем элементы массива по возрастанию. В конце самые популярные теги. */
    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;
            }
            $out .= '<a href="'. get_tag_link($tag->tag_id) .'"
                class="tag-link-'.$tag->tag_id.'" ' . 
                $stil . '>'. $tag->tag_name .' ('. $tag->posts_count .')</a>, ';        
        }
    }
    return rtrim($out, ', ');
} ?>

Саму функцию необходимо разместить в файле functions.php вашей темы. Позвольте мне не описывать подробно как именно она работает. Те из вас, кто разбирается в php и не один день работает с сайтами на вордпрессе, наверное разберутся сами, кроме того, функция порядком откомментирована. Добавлю лишь три ключевых момента:

$min_size = 13; // Минимальный размер шрифта тегов

Как следует из комментария, в этой переменной указан размер для самых непопулярных тегов моего сайта. Размер этот подбирался опытным путём, исходя из того, какой шрифт выбран для вывода облака тегов. Само собой, в вашем случае это может быть совсем другой размер и вам его придётся подбирать самостоятельно, другие стили шрифта описаны в css-классе.

$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;
}

Обратите внимание на выделенную строчку. Это шаг, с которым увеличивается шрифт с ростом популярности тегов. В моём случае — плюс 1. Если окажется, что минимальный размер шрифта у вас меньше моего, а тегов имеется всего пять или семь, возможно, увеличения размера шрифта на единицу вам будет не достаточно. Кроме того, в качестве единицы измерения я использовал пиксели, поэтому мой шаг растёт на целое число. Если указывать размеры шрифта в процентах, например, то увеличивать шаг можно будет и дробно.

И, наконец, третье. Саму функцию можно вызывать в любом месте вашей темы. Я делаю это примерно так:

<?php
	// Выводим теги данного раздела, если они есть
	$cat = get_the_category(); 
	$tags = get_category_tags( $cat[0]->cat_ID );
	if ( $tags != '' ) echo '<div class="tagCloud"><h3>Теги</h3>'
           . $tags . '</div>';
?>

Само собой, в css описаны стили для класса tagClud и заголовка h3. Функция была немного переписана так, чтобы её можно было использовать в любых шаблонах, не зная заранее ни ID текущей категории, ни того факта, а есть ли вообще у этой категории теги?

Используйте на здоровье, если кому-то пригодится. Не бойтесь экспериментировать и что-то менять.

8 комментариев на «WordPress, рубрики и облако тэгов»

  1. Облако штука прикольная, я использую плагин, в котором можно настроить внешний вид

    • Фото аватара Володька Смирнов:

      Не испытываю предубеждений к плагинам, но если где-то могу обойтись без них — обхожусь.

  2. Хорошая идея – вывод популярных тегов в конкретной рубрике. Но в жизни, как и в предлагаемых вариантах и других плагинах выводятся популярные теги именно с точки зрения автора (т.е. каких постов больше автор написал с этими тегами, те и показываются).
    А я вот ищу плагин или какое-либо решение чуть в другой плоскости. Хотелось бы, что бы отбор тегов шел не из их общей массы, а только из тех, которые оказались в популярных постах. Т.е. в тех постах, которые более всего заинтересовали читателей. И уже среди этого количества тегов шел бы их отбор по популярности (по сути с точки зрения посетителя).
    Встречали ли вы такие плагины или какое-либо решение этой идеи? Или возможно знаете как это реализовать?

    • Фото аватара Володька Смирнов:

      Игорь, я вас правильно понимаю? Вам необходимо показывать тэги только к тем постам, которые имели больше всего просмотров? Готового решения у меня нет и надо подумать как подобное написать. С другой стороны есть масса решений как показать не тэги, а именно самые популярные статьи. Один из вариантов реализован у меня, если вам интересно, я могу подсказать. где я решение нашёл. )

  3. Да, Вы правильно поняли. Вот пытаюсь найти такое решение, но пока не получается. Плагины для вывода отдельно популярных статей и плагинов я знаю. А вот искомая штука, думаю, заинтересовала бы многих.

    • Фото аватара Володька Смирнов:

      Хоть у вас и предостаточно функций, отображающих популярные статьи, подброшу вам ссылку на ту, которой пользовался я сам. Получив список популярных статей, нужно уже вторым действием выводить их теги. Правда в моём сайте эта функция реализована лишь при выводе самих статей. Внутри. Для каждой отдельной статьи. Очевидно, получив ID популярных статей, можно вывести теги в цикле, перебирая записи по очереди, а затем вывести их без повторов. )

  4. Юрий:

    Долго искал этот способ вывода меток… Есть один вопрос. Как выводить эти метки с укороченными названиями, либо как можно убрать определенные слова в названии каждой метки ? К примеру слово “картинка” нужно убрать из выводимого названия метки “Красивые дома, картинка”. Собственно таких меток много, и получается что слово картинка будет довольно спаммно. Как реализовать ? Нашел одни способ только немного под другое русло, но эта функция вырезает определенное слово $title = str_replace(‘wallpaper’, ”, $title); можно ли ее применить в этом случае ?

    • Фото аватара Володька Смирнов:

      Юрий, не убеждён, что замена одного слова на другое решит все проблемы, особенно, если таких слов будет много. Может быть можно вовсе не ставить тег “картинка” в вашем случае, а оставлять только более значимое “красивые дома”?

Оставьте ваш отзыв: