Obtenez le parent de niveau supérieur d'un terme de taxonomie personnalisé

14

Comment puis-je obtenir le parent de niveau supérieur d'un terme donné?

J'utilise wp_get_object_termspour obtenir des termes de taxonomie sur les publications, mais au lieu d'afficher tous les termes balisés, je souhaite uniquement afficher les parents de niveau supérieur des termes balisés.

Donc, si ce sont mes termes sélectionnés, je veux seulement montrer le petit-déjeuner, le déjeuner et le dîner.

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

Comment puis-je faire ceci?

super vrai
la source

Réponses:

22

Merci à Ivaylo pour ce code basé sur la réponse de Bainternet.

La première fonction ci-dessous, get_term_top_most_parentaccepte un terme et une taxonomie et renvoie le parent de niveau supérieur du terme (ou le terme lui-même, s'il est sans parent); la deuxième fonction ( get_top_parents) fonctionne dans la boucle et, étant donné une taxonomie, renvoie une liste HTML des parents de niveau supérieur des termes d'un article.

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

Une fois que vous avez la fonction ci-dessus, vous pouvez parcourir les résultats renvoyés par wp_get_object_termset afficher le parent supérieur de chaque terme:

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 vrai
la source
J'adorerais voir une modification qui n'imprimerait pas seulement les termes de niveau supérieur, mais plutôt tous les termes sous le parent le plus élevé, hiérarchiquement.
Robert Andrews
@RobertAndrews Si vous avez juste besoin des enfants d'un seul terme, vous pouvez utiliser intégré à WordPress get_term_children( $term, $taxonomy )( documentation ). Si vous vouliez obtenir tous les enfants d'un parent haut niveau de terme donné, vous pouvez passer le résultat ci - dessus en elle, comme ceci: get_term_children( get_term_top_most_parent( $term, $taxonomy ), $taxonomy ).
super vrai
Quel est $ term dans ce cas, c.-à-d. l'objet, le nom du terme, le taxonomyname_number préfixé? Dans tous les cas, cette méthode est extrêmement longue à charger. J'attends le chargement de la page depuis plusieurs minutes maintenant.
Robert Andrews
1
Comme écrit à l'origine, il attendait un ID, mais j'ai modifié la réponse pour autoriser un terme ID ou un objet WP_Term. Vous n'êtes pas le seul à signaler un problème avec ce code - idéalement, il devrait être réécrit pour utiliser la fonction intégrée de WP get_ancestors, qui était nouvelle et mal documentée lorsque la réponse a été écrite. Je posterai une nouvelle réponse quand j'aurai le temps de tester.
super vrai
21

Depuis 3.1.0, get_ancestors()est disponible. Il renvoie un tableau d'ancêtres du plus bas au plus élevé de la hiérarchie.

markd
la source
1
C'est la bonne réponse à mon avis.
numediaweb
1
C'est la meilleure réponse.
Mark
8

Voici une fonction simple qui vous permettra d'obtenir le terme le plus parent de tout terme donné:

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

Une fois que vous avez cette fonction, vous pouvez simplement parcourir les résultats renvoyés par 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
la source
Merci! J'essaye maintenant. Pour info, je pense qu'il vous manque une parenthèse étroite dans la ligne 1 de la fonction.
super vrai
dois-je ajouter $ taxonomy comme deuxième paramètre dans $ top_parent?
supertrue
J'ai ajouté le paramètre $ taxonomy mais j'obtiens
supertrue
ouais tu fais. j'ai mis à jour la réponse.
Bainternet
1
votre fonction semble cassée vos boucles foreach se chevauchent essayez ceci: pastebin.com/u48dxzap et si vous obtenez toujours une erreur, collez tout votre code et je vérifierai
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
la source
1
Veuillez ajouter une explication avec votre code.
s_ha_dum
4

J'ai eu le même problème et j'ai résolu facilement. Regarde ça:

Définissez $taxonomy. Il peut s'agir de la limace de la taxonomie que vous souhaitez obtenir les données. Après cela, vous pouvez simplement faire ceci:

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

Maintenant, vous avez quelque chose comme ça:

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

Et vous pouvez utiliser $parentObjpour obtenir slug, nom, id, peu importe. Juste en utilisant $parentObj->slugou $parentObj->namecomme exemple.

user3328615
la source
2

Manière la plus simple:

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