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

14

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

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

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

x BREAKFAST
   x Cereal
   x Eggs
  LUNCH
     Hamburger
   x Pizza
  DINNER
     Fish
        Bass
      x Salmon
        Trout
     Lasagna

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

supertrue
источник

Ответы:

22

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

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

// Determine the top-most parent of a term
function get_term_top_most_parent( $term, $taxonomy ) {
    // Start from the current term
    $parent  = get_term( $term, $taxonomy );
    // Climb up the hierarchy until we reach a term with 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 ) {
    // get terms for current post
    $terms = wp_get_object_terms( get_the_ID(), $taxonomy );
    $top_parent_terms = array();

    foreach ( $terms as $term ) {
        //get top level parent
        $top_parent = get_term_top_most_parent( $term, $taxonomy );
        //check if you have it in your array to only add it once
        if ( !in_array( $top_parent, $top_parent_terms ) ) {
            $top_parent_terms[] = $top_parent;
        }
    }

    // build output (the HTML is up to you)
    $output = '<ul>';
    foreach ( $top_parent_terms as $term ) {
          //Add every term
          $output .= '<li><a href="'. get_term_link( $term ) . '">' . $term->name . '</a></li>';
    }
    $output .= '</ul>';

    return $output;
}
supertrue
источник
Я хотел бы увидеть модификацию, которая будет не просто печатать термины верхнего уровня, а, скорее, все термины ниже самого верхнего родителя, в иерархическом порядке.
Роберт Эндрюс
@RobertAndrews Если вам просто нужны дети одного термина, вы можете использовать встроенный WordPress get_term_children( $term, $taxonomy )( документация ). Если вы хотите , чтобы все дети родителя данного термина топ-уровня, вы могли бы пройти предыдущий результат в него, как это: get_term_children( get_term_top_most_parent( $term, $taxonomy ), $taxonomy ).
SuperTrue
Что такое $ term в этом случае, т.е. объект, название термина, префикс таксономина_номер? Во всех случаях этот метод очень долго загружается. Я ждал загрузки страницы уже несколько минут.
Роберт Эндрюс
1
Как первоначально было написано, ожидался идентификатор, но я отредактировал ответ, чтобы разрешить использование термина или объекта WP_Term. Вы не единственный, кто сообщает о проблеме с этим кодом - в идеале его следует переписать, чтобы использовать встроенную get_ancestorsфункцию WP , которая была новой и плохо документированной, когда был написан ответ. Я опубликую новый ответ, когда у меня будет время для тестирования.
SuperTrue
21

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

markd
источник
1
Это правильный ответ на мой взгляд.
numediaweb
1
Это лучший ответ.
Марк
8

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

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 ) {

    //Get top level parent
    $top_parent = get_term_top_most_parent( $term->ID, 'taxomony' );

    //Check if you have it in your array to only add it once
    if ( !in_array( $top_parent->ID, $top_parent_terms ) ) {
        $top_parent_terms[] = $top_parent;
    }
}
Bainternet
источник
Благодарность! Я пытаюсь это сейчас. К вашему сведению, вам не хватает близкого члена в строке 1 функции.
SuperTrue
мне нужно добавить $ taxonomy как второй параметр в $ top_parent?
SuperTrue
Я добавил параметр $ taxonomy, но получаю сообщение об ошибке при использовании этого кода: gist.github.com/1122631
supertrue
да, вы делаете. я обновил ответ.
Bainternet
1
кажется, что ваша функция нарушена, ваши циклы foreach перекрываются, попробуйте это: pastebin.com/u48dxzap, и если вы все еще получаете сообщение об ошибке, вставьте весь код, и я проверю
Bainternet
5
/**
 * Get top level term
 */
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 );
}
Kiet
источник
1
Пожалуйста, добавьте объяснение вместе с вашим кодом.
s_ha_dum
4

У меня была такая же проблема, и я решил ее легко. Проверь это:

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

<?php
    $postterms = wp_get_post_terms($post->ID, $taxonomy);   // get post terms
    $parentId = $postterms[0]->parent;                      // get parent term ID
    $parentObj = get_term_by('id', $parentId, $taxonomy);   // get parent object 
?>

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

object(stdClass)#98 (11) {
  ["term_id"]=>
  int(3)
  ["name"]=>
  string(8) "Esportes"
  ["slug"]=>
  string(8) "esportes"
  ["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чтобы получить слаг, имя, идентификатор, что угодно. Просто используя $parentObj->slugили $parentObj->nameкак пример.

user3328615
источник
2

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

$rootId = end( get_ancestors( $term_id, 'my_taxonomy' ) );
$root = get_term( $rootId, 'my_taxonomy' );
echo $root->name;
Винсент Вастилс
источник