get_terms, функция для вывода элементов таксономий

Это универсальная функция, позволяющая получить данные об элементах таксономий.

Короче говоря вы можете вывести в любом виде рубрики с блога, метки, а также таксономии, созданные вами. Если же надо получить текущий элемент таксономии, то воспользуйтесь функциями get_query_var() (co значением параметра равным term — так вы получите ярлык текущего элемента таксономии) и get_term_by() (со значением первого параметра равным slug).

Выводим отсортированные по имени рубрики в виде выпадающего списка

Приведу сразу же несложный пример с кучей комментов, иначе, как мне кажется, если я начну с документации функции, то некоторым будет непонятно, как её использовать.

// вытаскиваем все рубрики в массив $categories, описание параметров функции смотрите чуть ниже
$categories = get_terms('category', 'orderby=name&hide_empty=0');
 
// если рубрики, соответствующие заданным параметрам, существуют,
if($categories){
 
	// тогда создаем выпадающий список из них
	echo '<select>';
 
	// обращаемся к каждому объекту массива (в данном случае рубрика)
	foreach ($categories as $cat){
 
		// выводим элемент списка, где атрибут value равен ID рубрики, а $cat->name - название рубрики
		echo "<option value='{$cat->term_id}'>{$cat->name}</option>";
	}
	echo '</select>';
}

Вот что у меня получилось в результате выполнения этого кода на тестовом сайте:

список рубрик при помощи get_terms

Слева — сам список (открытый), а справа его HTML-код.

Синтаксис

get_terms( $taxonomies, $args )

$taxonomies
(строка|массив) таксономия или массив таксономий, элементы которых нам нужны.

$args
(строка|массив) параметры по типу, как в WP_Query, их тоже можно записать и в виде массива и в виде строки.

Параметры массива $args

number
(целое число) количество элементов, которые нужно вывести, по умолчанию выводятся все.

offset
(целое число) сколько элементов нужно пропустить, то есть если offset=2, то начинаем с третьего.

include
(целое число|строка|массив) укажите ID элементов, которые нужно вывести, можно указать число, числа через запятую в виде строки или одномерный массив чисел, например так:

$categories = get_terms('category', 'include=1');

или так:

$categories = get_terms('category', 'include=1,4');

или даже так:

$args = array(
	'include' => array(1,4)
);
$categories = get_terms('category', $args);

Если вы хотите исключить какие-то элементы, не пытайтесь использовать минус перед числом, просто смотрите следующий параметр.

exclude
(целое число|строка|массив) укажите ID элементов, которые нужно исключить.

orderby
(строка) сортировать по:

  • id — по ID элементов (по умолчанию),
  • count — по количеству постов,
  • name — по имени,
  • slug — по ярлыку,
  • term_group — по значениям колонки term_group в таблице wp_terms базы данных,
  • none — без сортировки;

order
(строка) порядок сортировки.

  • ASC — по возрастанию (по умолчанию),
  • DESC — по убыванию;

hide_empty
(логическое) нужно ли добавлять в результат также и пустые (без постов) рубрики/метки/элементы таксономий:

  • true — не нужно (по умолчанию),
  • false — нужно;

fields
(строка) в каком виде выводить результат:

  • all — массив объектов элементов таксономий (по умолчанию), после print_r() он будет выглядеть так:
    $categories = get_terms('category');
    print_r($categories);
    /*
    Результат:
    Array ( [0] => stdClass Object ( [term_id] => 1 [name] => Заметки [slug] => notes [term_group] => 0 [menu_order] => 0 [term_taxonomy_id] => 1 [taxonomy] => category [description] => [parent] => 0 [count] => 7 ) [1] => stdClass Object ( [term_id] => 4 [name] => Новости [slug] => news [term_group] => 0 [menu_order] => 0 [term_taxonomy_id] => 4 [taxonomy] => category [description] => [parent] => 0 [count] => 2 ) [2] => stdClass Object ( [term_id] => 11 [name] => Обновления [slug] => updates [term_group] => 0 [menu_order] => 0 [term_taxonomy_id] => 11 [taxonomy] => category [description] => [parent] => 4 [count] => 1 ) )
    */
  • ids — массив составленный из ID элементов, вот как он будет выглядеть, если пропустить его через функцию print_r():
    $categories = get_terms('category', 'fields=ids');
    print_r($categories);
    /*
    Результат:
    Array ( [0] => 1 [1] => 4 [2] => 11 )
    */
  • names — возвращает массив наименований, например:
    $categories = get_terms('category', 'fields=names');
    print_r($categories);
    /*
    Результат:
    Array ( [0] => Новости [1] => Заметки )
    */
  • count — (с версии 3.2) возвращает количество всех элементов таксономии, вне зависимости от других параметров. Для этих целей вы также можете использовать wp_count_terms().
    $categories = get_terms('category', 'fields=count');
    echo $categories;
    /*
    Результат:
    4
    */
  • id=>parent — ассоциативный массив состоящих из ID элементов и ID их родителей, если родительского элемента не существует, то возвращается 0, пример:
    $categories = get_terms('category', 'fields=id=>parent');
    print_r($categories);
    /*
    Результат:
    Array ( [1] => 0 [4] => 0 [11] => 4 )
    */

slug
(строка) возвращает элементы, ярлыки которых совпадают с заданным значением.

hierarchical
(логическое) нужно ли включить в результат родительские элементы, даже если в них нет постов?

  • 1 — нужно (по умолчанию),
  • 0 — не нужно;

name__like
(строка) возвращает только те элементы, названия которых начинаются с заданного значения (без чувствительности в регистру), например:

// выведем через пробел все метки, начинающиеся с буквы "н"
$tags = get_terms('post_tag', 'name__like=н');
foreach($tags as $tag){
	echo $tag->name . ' ';
}

search
(строка) возвращает только те элементы, названия которых содержат заданное значение (без чувствительности в регистру).

pad_counts
(логическое) влияет только на числовые значения количества постов в родительских элементах.

  • 1 — количество постов родительского элемента суммируется с количеством постов дочерних элементов,
  • 0 — не суммируется (по умолчанию);

get
(строка)

  • all — вывести все элементы, вне зависимости от параметров offset, hide_empty, child_of (по умолчанию — пустая строка)

child_of
(целое число) вывести все элементы таксономии, которые являются дочерними для элемента с указанным ID вне зависимости от уровня вложенности.

parent
(целое число) вывести элементы таксономии, которые являются дочерними для элемента с указанным ID и находятся на первом уровне вложенности. Если указать 0, то будут выведены только элементы верхнего уровня.

cache_domain
(строка) (с версии 3.2) если вы планируете использовать get_terms с указанными параметрами несколько раз, укажите в качестве значения cache_domain уникальную фразу, чтобы задействовать кэш (по умолчанию — «core»).

Возвращаемые значения

Если параметр fields не изменен, то функция возвращает массив объектов, каждый из которых содержит следующую информацию об элементе таксономии.

  • term_id — ID рубрики/метки/элемента таксономии
  • name — название
  • slug — ярлык
  • term_group — значение term_group из базы данных (особого применения пока что нет, в основном — в плагинах)
  • term_taxonomy_id — ID таксономии
  • taxonomy — название таксономии
  • description — описание элемента (можно заполнить в админке при создании и редактировании)
  • parent — ID родительского элемента
  • count — количество записей

Выводим список из 5-и рубрик, отсортированных по количеству записей

В этом примере параметры функции задаются в виде массива:

$number = 5; // ради интереса вынесем переменную отдельно
$args = array(
	'number' => $number,
	'orderby' => 'count',
	'order' => 'DESC'
);
$terms = get_terms('category', $args);
if($terms){
	echo '<ul>';
	foreach ($terms as $term){
		echo "<li>{$term->name} ({$term->count})</li>";
		// рядом в скобках указываем количество записей в категории
	}
	echo '</ul>';
}

Тот же самый пример, но только с заданными в виде строки параметрами:

$number = 5;
$terms = get_terms('category', "number=$number&orderby=count&order=DESC");
if($terms){
	echo '<ul>';
	foreach ($terms as $term){
		echo "<li>{$term->name} ({$term->count})</li>";
	}
	echo '</ul>';
}

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

  • Максим25 мая 2015 в 19:05 #

    Здравствуйте Михаил. Подскажите пожалуйста, как узнать ID категории в посте пользовательской таксаномии ?
    Я разобрался, как этого можно добиться, если надо получить ID из вордпресовских разделов и оно работает вот код. Но вот, как добиться того же с пастами пользовательской таксаномии не могу понять.

    $category = get_the_category(); 
    echo $category[0]->term_id;
  • alx dh22 июля 2015 в 16:07 #

    Доброго дня.
    Вопрос по первому примеру (вывод терминов таксономии в выпадающий список).
    Можно ли реализовать иерархический выпадающий список терминов произвольной таксономии, как это делается для иерархии категорий с помощью wp_dropdown_categories() ?

    • Миша23 июля 2015 в 07:07 #

      Добрый день!
      В функции wp_dropdown_categories() есть параметр taxonomy.

      • alx dh23 июля 2015 в 11:07 #

        Спасибо, я вчера подумал в ту же сторону и перестал изобретать велосипед. Использовал wp_dropdown_categories(). Не работал сабмит, но это удалось победить прикручиванием джаваскрипта.

  • Евгений3 октября 2015 в 13:10 #

    А как сделать что бы вместо ( term_id) выводилась ссылка ?

  • Алексей19 апреля 2016 в 13:04 #

    Здравствуйте, спасибо за ценный сайт!
    Подскажите, пожалуйста: нужно в архиве таксономии вывести списком дочернии таксономии. В рубриках я сделал это так:

    <?php     $children =  wp_list_categories('title_li=&use_desc_for_title=0&child_of='.$cat.'&echo=0&show_option_none=');
          if ($children) { ?>
     
         <ul>
             <h2><?php echo $children; ?></h2>
         </ul>
         <?php }  ?>

    Но нигде не могу найти аналог, как сделать это в произвольной таксономии.
    ???

    • Миша19 апреля 2016 в 16:04 #

      Здравствуйте!
      Для того, чтобы вывести дочерние таксономии, вам вполне подойдёт функция get_terms(), то есть наша задача стоит в том, чтобы выяснить ID текущей таксономии на странице её архива для того, чтобы передать в параметр функции child_of или parent (какой вам больше подходит).

      В этом нам поможет get_query_var().

      В общем вот примерный код:

      // пока что у нас есть возможность получить ярлык текущего элемента таксономии и название самой таксономии
      $taxonomy_slug = get_query_var('term');
      $taxonomy = get_query_var('taxonomy');
       
      // затем уже можно получить ID
      $term = get_term_by( 'slug', $taxonomy_slug, $taxonomy );
      $term_id = $term->term_id;
       
      // и потом уже выводим через get_terms() :)
      $children = get_terms($taxonomy, array( 'child_of' => $term_id ) );
  • Алексей19 апреля 2016 в 18:04 #

    Миша, а Вы не могли бы дать код уже обернутый в php теги, а то я в этом не силен, и делаю методом многих тыков...
    А этот код поверг меня в растерянность

    • Миша19 апреля 2016 в 19:04 #

      Ну а это уже зависит куда его вставлять :)

      Вообще теги так то <?php и ?>, но если они уже открыты, то второй раз не нужны.

  • Алексей19 апреля 2016 в 20:04 #

    Код вставляется на страницу архива таксономии. После кода

    	<?php echo term_description(); ?>

    ставлю Ваш

    <?php // пока что у нас есть возможность получить ярлык текущего элемента таксономии и название самой таксономии
    $taxonomy_slug = get_query_var('term');
    $taxonomy = get_query_var('taxonomy');
     
    // затем уже можно получить ID
    $term = get_term_by( 'slug', $taxonomy_slug, $taxonomy );
    $term_id = $term->term_id;
     
    // и потом уже выводим через get_terms() :)
    $children = get_terms($taxonomy, array( 'child_of' => $term_id ) ); 
    ?>

    И ничего не показывает.
    Может быть, мне в Вашем коде где-то надо подставить свои значения?

    • Миша19 апреля 2016 в 22:04 #

      А, так вы посмотрите, как get_terms() работает, не зря же вы под ней комментарий поставили, я просто не стал дописывать до конца :)

  • Алексей20 апреля 2016 в 14:04 #

    смотрю в статью как баран на новые ворота, хоть подскажите, в какой части смотреть?
    нужно подставить значения term, taxonomy и slug ?

  • Алексей20 апреля 2016 в 15:04 #

    так вроде я пробовал, не выходит

    • Миша20 апреля 2016 в 15:04 #

      Просто сразу после моего кода добавьте.

      echo '<ul>';
      foreach ($children as $term){
      	echo "<li>{$term->name} ({$term->count})</li>";
      }
      echo '</ul>';
  • Алексей20 апреля 2016 в 16:04 #

    Прекрасно, заработало!
    Но.
    А как сделать так, чтобы дочерние таксономии были ссылками? Иначе ведь смысл то какой их выводить...
    И как сделать, чтобы посты дочерней таксономии не выводились тогда в родительском архиве?

    • Миша20 апреля 2016 в 18:04 #

      Точно-точно,
      поменять

      echo "<li>{$term->name} ({$term->count})</li>";

      на

      echo "<li><a href='" . get_term_link( $term ) . " '>{$term->name} ({$term->count})</a></li>";
    • Миша20 апреля 2016 в 18:04 #

      При помощи pre_get_posts. Тут уже готового кода на руках нет.

      • Алексей4 мая 2016 в 15:05 #

        Миша, здравствуйте!
        Подскажите, пожалуйста. Все подсказанное мне выше очень хорошо получилось.
        Но когда в таксономии выведены ссылки на дочерние таксономии, а под ними каша из постов всех (и родительской и дочерних) то смысл теряется.
        В рубриках я это решил вот таким кодом в functions^

        function no_children( $query ) {
            if ( ! is_admin() && $query->is_main_query() && $query->is_category() )
                $query->set( 'category__in', array( get_queried_object_id() ) );
        }
        add_action( 'pre_get_posts', 'no_children' );

        Но для таксономий не работает.
        Понимаю, что надо изменить слово is_category в данном куске кода.
        Но на что изменить?

        • Миша4 мая 2016 в 18:05 #

          Здравствуйте!
          Если просто нужно изменить is_category, то попробуйте поменять на is_tax

          • Алексей4 мая 2016 в 22:05 #

            вставляю такой код

            function no_children( $query ) {
                if ( ! is_admin() && $query->is_main_query() && $query->is_tax() )
                    $query->set( 'category__in', array( get_queried_object_id() ) );
            }
            add_action( 'pre_get_posts', 'no_children' );

            после предыдущего, при обновлении страницы сайта - белая страница пустая

            может, надо еще category__in на что-то менять?

            • Миша5 мая 2016 в 10:05 #

              Да, вы правы, нужно заменить на tax_query. Синтаксис подробно описан здесь, и там как раз есть параметр include_children.

              • Алексей5 мая 2016 в 11:05 #

                Только обрадовался, пошел ставить, но не тут то было.
                Ставлю такой код в function

                function include_children( $query ) {
                    if ( ! is_admin() && $query->is_main_query() && $query->is_tax() )
                        $query->set( 'tax_query', array( get_queried_object_id() ) );
                }
                add_action( 'pre_get_posts', 'include_children' );

                Но не работает.
                Правда, уже не ломает сайт, не делает его пустыми белыми страницами.
                Но просто нет никакого эффекта.
                Миша, где же косяк?

                • Миша6 мая 2016 в 07:05 #

                  Не всё так просто, Алексей, смотрите внимательно какой там синтаксис.

                  get_queried_object_id() это по идее ID, а значит будет примерно так:

                  $query->set( 'tax_query', array(array(  'taxonomy' => 'НАЗВАНИЕ_ТАКСОНОМИИ', 'field' => 'id', 'terms' => array( get_queried_object_id() ), 'include_children' => false )));
                  • Алексей6 мая 2016 в 13:05 #

                    Ок, дело сдвинулось с мертвой точки, но вылез новый косяк.
                    Когда пишу в функции это:

                    function include_children( $query ) {
                        if ( ! is_admin() && $query->is_main_query() && $query->is_tax() )
                            $query->set( 'tax_query', array(array(  'taxonomy' => 'my-tax', 'field' => 'id', 'terms' => array( get_queried_object_id() ), 'include_children' => false )));
                    }

                    то оно начинает работать и действительно в архиве родительской таксономии не выводит записи дочерней.
                    НО!
                    Ломает код, который мы с таким трудом создавали для вывода таксономий на страницах архивов.

                    <?php 
                    // пока что у нас есть возможность получить ярлык текущего элемента таксономии и название самой таксономии
                    $taxonomy_slug = get_query_var('term');
                    $taxonomy = get_query_var('taxonomy');
                     
                    // затем уже можно получить ID
                    $term = get_term_by( 'slug', $taxonomy_slug, $taxonomy );
                    $term_id = $term->term_id;
                     
                    // и потом уже выводим через get_terms() :)
                    $children = get_terms($taxonomy, array( 'child_of' => $term_id ) );
                     
                    echo '<ul>';
                    foreach ($children as $term){
                    	echo "<li><h2><a href='" . get_term_link( $term ) . " '>{$term->name}</a></h2></li>";
                    }
                    ?>

                    и последний код выводит на каждой странице таксономии ВСЕ таксономии маркированным списком.
                    Ну не одна каша (из постов), так другая (из заголовков).
                    Что-же теперь не так?

                  • Миша6 мая 2016 в 15:05 #

                    Я бы рекомендовал всё-таки в данном случае не модифицировать цикл через pre_get_posts, а сделать это при помощи query_posts(), самый последний пример в этой статье.

                    • Алексей6 мая 2016 в 16:05 #

                      час от часу не легче.
                      То есть, прекратить мучить файл function и внести изменения в файл taxonomy?

      • Алексей4 мая 2016 в 15:05 #

        попробовал экспериментировать, но сайт ломается :(

  • Алексей21 апреля 2016 в 22:04 #

    Миша, а как убрать количество постов в скобках?

    • Миша22 апреля 2016 в 08:04 #

      Алексей, если вы просто попробуете удалить из этой строчки кода то, что считаете нужным, ничего плохого с сайтом не случится.

      Прошу прощения, просто вопрос, который вы задаёте, не требует знаний кода — только немного логики.

  • Алексей22 апреля 2016 в 22:04 #

    Ок, сработало. Спасибо!

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • alex morozov: Добрый вечер! у меня возникла следующая проблема. Я делаю фотоальбомы, чтобы они выглядели "как в контакте". Так вот, та...

  • Vladislav: Если эту муть убрать, то исчезает меню, и появляется описание под миниатюрами, которого не должно быть, как вы видите, я...

  • Миша: Либо размеры изображений вам помогут, либо CSS. И строку 14 гляньте, там муть какая-то.

  • Vladislav: Подправил имеющийся у меня код, по вашим рекомендациям, миниатюры начали отображаться, но они стали очень огромными, что...

  • Миша: Лишь предложил решение. Думаю можно нашаманить и так, чтобы чисто для рубрик было, не уверен только, что обойдётся без и...