Получение родительского термина верхнего уровня для произвольной таксономии

3 авг. 2011 г., 15:30:06
Просмотры: 76.3K
Голосов: 17

Как получить родительский термин верхнего уровня для заданного термина?

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

Если это мои выбранные термины, я хочу показывать только Завтрак, Обед и Ужин.

x ЗАВТРАК
   x Хлопья
   x Яйца
  ОБЕД
     Гамбургер
   x Пицца
  УЖИН
     Рыба
        Окунь
      x Лосось
        Форель
     Лазанья

Как я могу это сделать?

0
Все ответы на вопрос 8
4
24

Спасибо Ivaylo за этот код, который основан на ответе Bainternet.

Первая функция ниже, get_term_top_most_parent, принимает термин и таксономию и возвращает самого верхнего родителя термина (или сам термин, если у него нет родителя); вторая функция (get_top_parents) работает в цикле и, учитывая таксономию, возвращает HTML-список самых верхних родителей терминов записи.

// Определение самого верхнего родителя термина
function get_term_top_most_parent( $term, $taxonomy ) {
    // Начинаем с текущего термина
    $parent  = get_term( $term, $taxonomy );
    // Поднимаемся по иерархии, пока не достигнем термина с parent = '0'
    while ( $parent->parent != '0' ) {
        $term_id = $parent->parent;
        $parent  = get_term( $term_id, $taxonomy);
    }
    return $parent;
}

Как только у вас есть функция выше, вы можете перебирать результаты, возвращенные wp_get_object_terms, и отображать самого верхнего родителя каждого термина:

function get_top_parents( $taxonomy ) {
    // Получаем термины для текущей записи
    $terms = wp_get_object_terms( get_the_ID(), $taxonomy );
    $top_parent_terms = array();

    foreach ( $terms as $term ) {
        // Получаем самого верхнего родителя
        $top_parent = get_term_top_most_parent( $term, $taxonomy );
        // Проверяем, есть ли он уже в массиве, чтобы добавить только один раз
        if ( !in_array( $top_parent, $top_parent_terms ) ) {
            $top_parent_terms[] = $top_parent;
        }
    }

    // Формируем вывод (HTML на ваше усмотрение)
    $output = '<ul>';
    foreach ( $top_parent_terms as $term ) {
          // Добавляем каждый термин
          $output .= '<li><a href="'. get_term_link( $term ) . '">' . $term->name . '</a></li>';
    }
    $output .= '</ul>';

    return $output;
}
5 авг. 2011 г. 07:27:34
Комментарии

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

Robert Andrews Robert Andrews
22 дек. 2018 г. 02:14:31

@RobertAndrews Если вам нужны только дочерние элементы одного термина, вы можете использовать встроенную функцию WordPress get_term_children( $term, $taxonomy ) (документация).

Если вы хотите получить все дочерние элементы самого верхнего родителя данного термина, вы можете передать результат выше в эту функцию, вот так: get_term_children( get_term_top_most_parent( $term, $taxonomy ), $taxonomy ).

supertrue supertrue
4 янв. 2019 г. 23:12:25

Что представляет собой $term в данном случае - объект, название термина, имя таксономии с префиксом_number? В любом случае, этот метод очень долго грузится. Я жду загрузки страницы уже несколько минут.

Robert Andrews Robert Andrews
4 янв. 2019 г. 23:54:59

Изначально код ожидал ID, но я отредактировал ответ, чтобы он мог принимать как ID термина, так и объект WP_Term.

Вы не единственный, кто сообщает о проблеме с этим кодом — в идеале его следует переписать с использованием встроенной функции WP get_ancestors, которая была новой и плохо документирована на момент написания ответа. Я опубликую новый ответ, когда у меня будет время протестировать.

supertrue supertrue
5 янв. 2019 г. 06:14:35
2
24

Начиная с версии 3.1.0, доступна функция get_ancestors(). Она возвращает массив предков (родительских элементов) в порядке от низшего к высшему в иерархии.

17 июн. 2013 г. 05:19:11
Комментарии

Это правильный ответ, на мой взгляд.

numediaweb numediaweb
5 июл. 2015 г. 13:14:00

Это лучший ответ.

Mark Mark
23 июл. 2015 г. 00:28:06
11

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

function get_term_top_most_parent( $term_id, $taxonomy ) {
    $parent  = get_term_by( 'id', $term_id, $taxonomy );
    while ( $parent->parent != 0 ){
        $parent  = get_term_by( 'id', $parent->parent, $taxonomy );
    }
    return $parent;
}

После создания этой функции вы можете просто перебрать результаты, возвращаемые функцией wp_get_object_terms:

$terms =  wp_get_object_terms( $post->ID, 'taxonomy' );
$top_parent_terms = array();
foreach ( $terms as $term ) {

    //Получаем самый верхний родительский элемент
    $top_parent = get_term_top_most_parent( $term->ID, 'taxomony' );

    //Проверяем, есть ли он уже в массиве, чтобы добавить только один раз
    if ( !in_array( $top_parent->ID, $top_parent_terms ) ) {
        $top_parent_terms[] = $top_parent;
    }
}
3 авг. 2011 г. 15:43:31
Комментарии

Спасибо! Пробую это сейчас. Кстати, кажется, у вас не хватает закрывающей скобки в первой строке функции.

supertrue supertrue
3 авг. 2011 г. 16:19:26

нужно ли добавлять $taxonomy как второй параметр в $top_parent?

supertrue supertrue
3 авг. 2011 г. 16:20:51

Я добавил параметр $taxonomy, но получаю ошибку при использовании этого кода, вот здесь: https://gist.github.com/1122631

supertrue supertrue
3 авг. 2011 г. 16:33:21

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

Bainternet Bainternet
3 авг. 2011 г. 16:33:45

Теперь, когда это исправлено, ты не знаешь, почему код здесь (http://gist.github.com/1122631) не работает?

supertrue supertrue
3 авг. 2011 г. 19:27:11

твоя функция кажется сломанной, твои циклы foreach перекрываются, попробуй это: http://pastebin.com/u48dxzap и если ошибка останется, вставь весь свой код, и я проверю

Bainternet Bainternet
3 авг. 2011 г. 20:36:03

Ошибка всё та же; если сделать print_r($top_parent_terms), получается пустой массив, так что, возможно, проблема в первой функции? Моя версия здесь - http://pastebin.com/cMUxs9Nn

supertrue supertrue
3 авг. 2011 г. 20:59:52

Ладно, думаю, проблема в get_the_ID, который работает внутри цикла, так что попробуйте это: http://pastebin.com/u48dxzap

Bainternet Bainternet
3 авг. 2011 г. 21:33:19

@Bainternet давайте продолжим обсуждение в чате

supertrue supertrue
3 авг. 2011 г. 21:37:38

@Bainternet - это сообщение в чате было опубликовано автоматически? Что касается global $post и post->ID, я использую это внутри циклов WP_Query, поэтому get_the_ID должен работать.

supertrue supertrue
3 авг. 2011 г. 22:37:47

Нет, ты используешь это в функции, вызываемой внутри цикла. Это работает?

Bainternet Bainternet
3 авг. 2011 г. 23:54:10
Показать остальные 6 комментариев
1
/**
 * Получить термин верхнего уровня
 */
function get_top_level_term($term,$taxonomy){
    if($term->parent==0) return $term;
    $parent = get_term( $term->parent,$taxonomy);
    return get_top_level_term( $parent , $taxonomy );
}
18 окт. 2013 г. 07:14:54
Комментарии

Пожалуйста, добавьте пояснение вместе с вашим кодом.

s_ha_dum s_ha_dum
18 окт. 2013 г. 07:43:10
0

У меня была такая же проблема, и я легко её решил. Вот как:

Определите $taxonomy. Это может быть ярлык таксономии, данные которой вы хотите получить. После этого вы можете просто сделать следующее:

<?php
    $postterms = wp_get_post_terms($post->ID, $taxonomy);   // получаем термины поста
    $parentId = $postterms[0]->parent;                      // получаем ID родительского термина
    $parentObj = get_term_by('id', $parentId, $taxonomy);   // получаем объект родителя 
?>

Теперь у вас будет что-то вроде этого:

object(stdClass)#98 (11) {
  ["term_id"]=>
  int(3)
  ["name"]=>
  string(8) "Спорт"
  ["slug"]=>
  string(8) "sport"
  ["term_group"]=>
  int(0)
  ["term_taxonomy_id"]=>
  int(3)
  ["taxonomy"]=>
  string(17) "noticiaseditorias"
  ["description"]=>
  string(0) ""
  ["parent"]=>
  int(0)
  ["count"]=>
  int(4)
  ["object_id"]=>
  int(123)
  ["filter"]=>
  string(3) "raw"
}

И вы можете использовать $parentObj для получения ярлыка, названия, ID или чего угодно. Просто используйте $parentObj->slug или $parentObj->name в качестве примера.

30 окт. 2014 г. 19:38:35
0

Самый простой способ:

$rootId = end( get_ancestors( $term_id, 'my_taxonomy' ) );
$root = get_term( $rootId, 'my_taxonomy' );
echo $root->name;
29 янв. 2016 г. 12:24:18
0

Возможно, это поможет: get_ancestors( $object_id, $object_type );

codex.wordpress.org

11 дек. 2015 г. 12:49:16
1

Попробуйте это!

function get_term_top_most_parent( $term_id, $taxonomy ) {
    $ancestors = get_ancestors( $term_id, $taxonomy );

    if(!empty($ancestors)){
        $parentID = end( $ancestors );
    }else{
        $parentID = $term_id;
    }
    return $parentID;
}
1 сент. 2021 г. 13:19:53
Комментарии

Пожалуйста, [отредактируйте] ваш ответ и добавьте объяснение: почему это может решить проблему?

fuxia fuxia
1 сент. 2021 г. 15:25:06