Obtener el término padre de nivel superior de una taxonomía personalizada
¿Cómo podría obtener el término padre de nivel superior de un término dado?
Estoy usando wp_get_object_terms
para obtener términos de taxonomía en las entradas, pero en lugar de mostrar todos los términos etiquetados, solo quiero mostrar los términos padre de nivel superior de los términos etiquetados.
Entonces, si estos son mis términos seleccionados, solo quiero mostrar Desayuno, Almuerzo y Cena.
x DESAYUNO
x Cereal
x Huevos
ALMUERZO
Hamburguesa
x Pizza
CENA
Pescado
Lubina
x Salmón
Trucha
Lasaña
¿Cómo puedo hacer esto?

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_parent
, acepta un término y una taxonomía y devuelve el padre de nivel superior del término (o el término mismo, si no tiene padre); la segunda función (get_top_parents
) funciona dentro del loop y, dada una taxonomía, devuelve una lista HTML de los padres de nivel superior de los términos de una entrada.
// Determina el padre más superior de un término
function get_term_top_most_parent( $term, $taxonomy ) {
// Comienza desde el término actual
$parent = get_term( $term, $taxonomy );
// Asciende en la jerarquía hasta llegar a un término con padre = '0'
while ( $parent->parent != '0' ) {
$term_id = $parent->parent;
$parent = get_term( $term_id, $taxonomy);
}
return $parent;
}
Una vez que tienes la función anterior, puedes iterar sobre los resultados devueltos por wp_get_object_terms
y mostrar el padre superior de cada término:
function get_top_parents( $taxonomy ) {
// obtiene los términos para la entrada actual
$terms = wp_get_object_terms( get_the_ID(), $taxonomy );
$top_parent_terms = array();
foreach ( $terms as $term ) {
//obtiene el padre de nivel superior
$top_parent = get_term_top_most_parent( $term, $taxonomy );
//verifica si ya está en el array para agregarlo solo una vez
if ( !in_array( $top_parent, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}
// construye la salida (el HTML depende de ti)
$output = '<ul>';
foreach ( $top_parent_terms as $term ) {
//Agrega cada término
$output .= '<li><a href="'. get_term_link( $term ) . '">' . $term->name . '</a></li>';
}
$output .= '</ul>';
return $output;
}

Me encantaría ver una modificación que no solo muestre los términos de nivel superior, sino todos los términos debajo del padre más alto, de forma jerárquica.

@RobertAndrews Si solo necesitas los hijos de un único término, puedes usar la función incorporada de WordPress get_term_children( $term, $taxonomy )
(documentación).
Si quisieras obtener todos los hijos del padre de nivel superior de un término dado, podrías pasar el resultado anterior así: get_term_children( get_term_top_most_parent( $term, $taxonomy ), $taxonomy )
.

¿Qué es $term en este caso? ¿El objeto, el nombre del término, el taxonomyname_number con prefijo? En cualquier caso, este método tarda muchísimo en cargar. Llevo varios minutos esperando a que cargue la página.

Como estaba escrito originalmente, esperaba un ID, pero edité la respuesta para permitir un ID de término o un objeto WP_Term.
No eres el único que reporta un problema con este código—idealmente debería 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 probarlo.

Desde la versión 3.1.0, está disponible get_ancestors()
. Devuelve un array de ancestros ordenados de menor a mayor en la jerarquía.

Aquí tienes una función simple que te dará el término padre superior 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 tienes esta función, puedes iterar sobre los resultados devueltos por wp_get_object_terms
:
$terms = wp_get_object_terms( $post->ID, 'taxonomy' );
$top_parent_terms = array();
foreach ( $terms as $term ) {
//Obtener el padre de nivel superior
$top_parent = get_term_top_most_parent( $term->ID, 'taxomony' );
//Verificar si ya está en el array para agregarlo solo una vez
if ( !in_array( $top_parent->ID, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}

¡Gracias! Estoy probando esto ahora. Por cierto, creo que te falta un paréntesis de cierre en la línea 1 de la función.

Agregué el parámetro $taxonomy pero estoy recibiendo un error cuando uso este código, aquí: https://gist.github.com/1122631

Con eso solucionado, ¿sabes por qué el código aquí (http://gist.github.com/1122631) no estaría funcionando?

tu función parece rota, tus bucles foreach se están solapando, prueba esto: http://pastebin.com/u48dxzap y si aún obtienes un error, pega todo tu código y lo revisaré

Sigue dando el mismo error; si hago print_r($top_parent_terms), obtengo un array vacío, así que tal vez el problema esté realmente en la primera función? Mi versión aquí - http://pastebin.com/cMUxs9Nn

OK creo que el problema está con get_the_ID
que funciona dentro del loop, así que prueba esto: http://pastebin.com/u48dxzap

@Bainternet continuemos esta discusión en el chat

@Bainternet-¿se publicó automáticamente ese mensaje de chat? Respecto a global $post y post->ID, estoy usando esto dentro de bucles WP_Query así que get_the_ID debería estar funcionando.

Tuve el mismo problema y lo resolví fácilmente. Mira esto:
Define $taxonomy
. Puede ser el slug de la taxonomía de la que quieres obtener los datos.
Después de hacer esto, simplemente puedes hacer:
<?php
$postterms = wp_get_post_terms($post->ID, $taxonomy); // obtiene los términos del post
$parentId = $postterms[0]->parent; // obtiene el ID del término padre
$parentObj = get_term_by('id', $parentId, $taxonomy); // obtiene el objeto padre
?>
Ahora tienes algo como esto:
object(stdClass)#98 (11) {
["term_id"]=>
int(3)
["name"]=>
string(8) "Deportes"
["slug"]=>
string(8) "deportes"
["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 puedes usar $parentObj
para obtener el slug, nombre, id, lo que sea. Solo usando $parentObj->slug
o $parentObj->name
como ejemplo.

Quizás esto te ayude: get_ancestors( $object_id, $object_type );

¡Prueba esto!
function get_term_top_most_parent( $term_id, $taxonomy ) {
// Obtener los ancestros del término
$ancestors = get_ancestors( $term_id, $taxonomy );
// Si hay ancestros, obtener el ID del padre más alto
if(!empty($ancestors)){
$parentID = end( $ancestors );
}else{
// Si no hay ancestros, usar el ID del término actual
$parentID = $term_id;
}
return $parentID;
}
