Obtenga el padre de nivel superior de un término de taxonomía personalizado

14

¿Cómo obtendría el padre de primer nivel de un término determinado?

Estoy usando wp_get_object_termspara obtener términos de taxonomía en las publicaciones, pero en lugar de mostrar todos los términos etiquetados, solo quiero mostrar los términos etiquetados de los padres de nivel superior.

Entonces, si estos son mis términos seleccionados, solo quiero mostrar Desayuno, Almuerzo y Cena.

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

¿Cómo puedo hacer esto?

supertrue
fuente

Respuestas:

22

Gracias a Ivaylo por este código, que se basó en la respuesta de Bainternet.

La primera función a continuación, get_term_top_most_parentacepta un término y una taxonomía y devuelve el padre de nivel superior del término (o el término en sí mismo, si no tiene padres); la segunda función ( get_top_parents) funciona en el bucle y, dada una taxonomía, devuelve una lista HTML de los padres de nivel superior de los términos de una publicación.

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

Una vez que tenga la función anterior, puede recorrer los resultados devueltos wp_get_object_termsy mostrar el padre principal de cada término:

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
fuente
Me encantaría ver una modificación que no solo imprima los términos de nivel superior sino, más bien, todos los términos debajo del padre superior, jerárquicamente.
Robert Andrews
@RobertAndrews Si solo necesita los hijos de un solo término, puede utilizar la get_term_children( $term, $taxonomy )( documentación ) incorporada de WordPress . Si usted quiere conseguir todos los hijos de los padres de nivel superior de un término dado, se puede pasar el resultado anterior en ella, así: get_term_children( get_term_top_most_parent( $term, $taxonomy ), $taxonomy ).
supertrue
¿Qué es $ term en este caso? el objeto, el nombre del término, la taxonomía nombre_nombre_número? En todos los casos, este método es extremadamente largo de cargar. He estado esperando que la página se cargue durante varios minutos.
Robert Andrews
1
Como se escribió originalmente, esperaba una ID, pero edité la respuesta para permitir una ID de término o un objeto WP_Term. No es el único que informa un problema con este código; idealmente, debe reescribirse para usar la función incorporada de WP get_ancestors, que era nueva y no estaba bien documentada cuando se escribió la respuesta. Publicaré una nueva respuesta cuando haya tenido tiempo de probar.
supertrue
21

Desde 3.1.0, get_ancestors()está disponible. Devuelve una serie de antepasados ​​de menor a mayor en la jerarquía.

Markd
fuente
1
Esta es la respuesta correcta en mi opinión.
numediaweb
1
Esta es la mejor respuesta.
Mark
8

Aquí hay una función simple que le dará el término principal más alto de cualquier término dado:

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

Una vez que tenga esta función, puede recorrer los resultados devueltos 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
fuente
¡Gracias! Estoy intentando esto ahora. FYI Creo que te estás perdiendo un par cercano en la línea 1 de la función.
supertrue
¿Necesito agregar $ taxonomía como segundo parámetro en $ top_parent?
supertrue
Agregué el
supertrue
si lo haces Actualicé la respuesta.
Bainternet
1
su función parece roto sus foreach se superponen intente esto: pastebin.com/u48dxzap y si usted todavía consigue pegar un error todos ustedes código y voy a comprobar
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
fuente
1
Agregue una explicación junto con su código.
s_ha_dum
4

Tuve el mismo problema y lo resolví fácilmente. Mira esto:

Definir $taxonomy. Puede ser la babosa de la taxonomía que desea obtener los datos. Después de hacer esto, simplemente puede hacer esto:

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

Ahora tienes algo como esto:

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

Y puede usar $parentObjpara obtener babosa, nombre, identificación, lo que sea. Simplemente usando $parentObj->slugo $parentObj->namecomo ejemplo.

usuario3328615
fuente
2

La manera más fácil:

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