Obter o pai de nível superior de um termo de taxonomia personalizado

14

Como obteria o pai de nível superior de um determinado termo?

Estou usando wp_get_object_termspara obter termos de taxonomia nas postagens, mas em vez de mostrar todos os termos marcados, quero mostrar apenas os pais de nível superior dos termos marcados.

Portanto, se estes são os meus termos selecionados, eu só quero mostrar café da manhã, almoço e jantar.

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

Como posso fazer isso?

super verdadeiro
fonte

Respostas:

22

Agradecemos a Ivaylo por esse código, que foi baseado na resposta de Bainternet.

A primeira função abaixo, get_term_top_most_parentaceita um termo e taxonomia e retorna o pai de nível superior do termo (ou o próprio termo, se não tiver pais); a segunda função ( get_top_parents) funciona no loop e, dada uma taxonomia, retorna uma lista HTML dos pais de nível superior dos termos de uma postagem.

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

Depois de ter a função acima, você pode percorrer os resultados retornados por wp_get_object_termse exibir o principal pai de cada termo:

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;
}
super verdadeiro
fonte
Adoraria ver uma modificação que não apenas imprimisse os termos de nível superior, mas todos os termos abaixo do principal pai, hierarquicamente.
Robert Andrews
@RobertAndrews Se você só precisa os filhos de um único termo, você pode usar built-in do WordPress get_term_children( $term, $taxonomy )( documentação ). Se você queria para obter todos os filhos de pai de nível superior de um determinado prazo, você poderia passar o resultado acima para ele, como este: get_term_children( get_term_top_most_parent( $term, $taxonomy ), $taxonomy ).
usar o seguinte comando
O que é $ term neste caso, ie. o objeto, o nome do termo, o prefixo taxonomyname_number? Em todos os casos, esse método é extremamente longo para carregar. Estou esperando a página carregar por vários minutos agora.
Robert Andrews
1
Como originalmente escrito, esperava um ID, mas editei a resposta para permitir um termo ID ou objeto WP_Term. Você não é o único que relata um problema com esse código - idealmente, ele deve ser reescrito para usar a função interna do WP get_ancestors, que era nova e não estava bem documentada quando a resposta foi escrita. Vou postar uma nova resposta quando tiver tempo para testar.
supertrue
21

Desde 3.1.0, get_ancestors()está disponível. Retorna uma matriz de ancestrais da menor para a maior na hierarquia.

markd
fonte
1
Esta é a resposta correta na minha opinião.
Numeroweb
1
Esta é a melhor resposta.
Mark
8

Aqui está uma função simples que fornecerá o termo principal principal de qualquer termo:

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

Depois de ter essa função, basta percorrer os resultados retornados por 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
fonte
Obrigado! Estou tentando isso agora. Para sua informação, acho que falta um parêntese na linha 1 da função.
supertrue
preciso adicionar $ taxonomy como um segundo parâmetro em $ top_parent?
supertrue
Eu adicionei o parâmetro $ taxonomia, mas estou recebendo um erro quando eu usar esse código, aqui: gist.github.com/1122631
supertrue
sim você faz. eu atualizei a resposta.
Bainternet
1
sua função parece quebrado seus loops foreach são sobrepostos tente o seguinte: pastebin.com/u48dxzap e se você ainda receber um erro colar todos vocês código e eu vou verificar
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
fonte
1
Adicione uma explicação junto com o seu código.
s_ha_dum
4

Eu tive o mesmo problema e resolvi facilmente. Veja isso:

Definir $taxonomy. Pode ser a lesma da taxonomia que você deseja obter os dados. Depois de fazer isso, você pode simplesmente fazer o seguinte:

<?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 
?>

Agora você tem algo parecido com isto:

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"
}

E você pode usar $parentObjpara obter lesma, nome, identificação, qualquer que seja. Apenas usando $parentObj->slugou $parentObj->namecomo exemplo.

user3328615
fonte
2

Caminho mais fácil:

$rootId = end( get_ancestors( $term_id, 'my_taxonomy' ) );
$root = get_term( $rootId, 'my_taxonomy' );
echo $root->name;
Vincent Wasteels
fonte