Ottenere il genitore di livello superiore di un termine di tassonomia personalizzata
Come posso ottenere il genitore di livello superiore di un determinato termine?
Sto utilizzando wp_get_object_terms
per ottenere i termini della tassonomia sui post, ma invece di mostrare tutti i termini assegnati, voglio mostrare solo i genitori di livello superiore dei termini assegnati.
Quindi se questi sono i miei termini selezionati, voglio mostrare solo Colazione, Pranzo e Cena.
x COLAZIONE
x Cereali
x Uova
PRANZO
Hamburger
x Pizza
CENA
Pesce
Spigola
x Salmone
Trota
Lasagna
Come posso farlo?

Grazie a Ivaylo per questo codice, basato sulla risposta di Bainternet.
La prima funzione qui sotto, get_term_top_most_parent
, accetta un termine e una tassonomia e restituisce il genitore di livello più alto del termine (o il termine stesso, se non ha genitori); la seconda funzione (get_top_parents
) opera all'interno del loop e, data una tassonomia, restituisce una lista HTML dei genitori di livello più alto dei termini di un post.
// Determina il genitore di livello più alto di un termine
function get_term_top_most_parent( $term, $taxonomy ) {
// Parte dal termine corrente
$parent = get_term( $term, $taxonomy );
// Risale la gerarchia finché non raggiunge un termine con parent = '0'
while ( $parent->parent != '0' ) {
$term_id = $parent->parent;
$parent = get_term( $term_id, $taxonomy);
}
return $parent;
}
Una volta che hai la funzione precedente, puoi ciclare sui risultati restituiti da wp_get_object_terms
e visualizzare il genitore di livello più alto di ogni termine:
function get_top_parents( $taxonomy ) {
// ottieni i termini per il post corrente
$terms = wp_get_object_terms( get_the_ID(), $taxonomy );
$top_parent_terms = array();
foreach ( $terms as $term ) {
// ottieni il genitore di livello più alto
$top_parent = get_term_top_most_parent( $term, $taxonomy );
// controlla se è già presente nell'array per aggiungerlo solo una volta
if ( !in_array( $top_parent, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}
// costruisci l'output (l'HTML dipende da te)
$output = '<ul>';
foreach ( $top_parent_terms as $term ) {
// Aggiungi ogni termine
$output .= '<li><a href="'. get_term_link( $term ) . '">' . $term->name . '</a></li>';
}
$output .= '</ul>';
return $output;
}

Mi piacerebbe vedere una modifica che non si limitasse a stampare i termini di primo livello, ma piuttosto tutti i termini al di sotto del genitore più in alto, in modo gerarchico.

@RobertAndrews Se hai bisogno solo dei figli di un singolo termine, puoi usare la funzione integrata di WordPress get_term_children( $term, $taxonomy )
(documentazione).
Se invece vuoi ottenere tutti i figli del genitore di livello più alto di un dato termine, potresti passare il risultato sopra in questo modo: get_term_children( get_term_top_most_parent( $term, $taxonomy ), $taxonomy )
.

Cos'è $term in questo caso, cioè l'oggetto, il nome del termine, il taxonomyname_number con prefisso? In ogni caso, questo metodo è estremamente lento da caricare. Ho atteso diversi minuti per il caricamento della pagina.

Come scritto originariamente ci si aspettava un ID, ma ho modificato la risposta per consentire un ID del termine o un oggetto WP_Term.
Non sei l'unico a segnalare un problema con questo codice - idealmente dovrebbe essere riscritto usando la funzione integrata di WP get_ancestors
, che era nuova e non ben documentata quando la risposta è stata scritta. Pubblicherò una nuova risposta quando avrò avuto tempo di testare.

Dalla versione 3.1.0, è disponibile la funzione get_ancestors()
. Restituisce un array di elementi antenati ordinati dal livello più basso al più alto nella gerarchia.

Ecco una semplice funzione che ti permetterà di ottenere il termine genitore più in alto per qualsiasi termine specificato:
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 volta che hai questa funzione, puoi semplicemente iterare sui risultati restituiti da wp_get_object_terms
:
$terms = wp_get_object_terms( $post->ID, 'taxonomy' );
$top_parent_terms = array();
foreach ( $terms as $term ) {
//Ottieni il genitore di livello più alto
$top_parent = get_term_top_most_parent( $term->ID, 'taxomony' );
//Controlla se è già presente nell'array per aggiungerlo solo una volta
if ( !in_array( $top_parent->ID, $top_parent_terms ) ) {
$top_parent_terms[] = $top_parent;
}
}

Grazie! Sto provando ora. FYI penso ti manchi una parentesi chiusa nella prima riga della funzione.

Ho aggiunto il parametro $taxonomy ma ottengo un errore quando uso questo codice, qui: https://gist.github.com/1122631

Con quello sistemato, sai perché il codice qui (http://gist.github.com/1122631) non funzionerebbe?

la tua funzione sembra rotta, i tuoi cicli foreach si sovrappongono prova questo: http://pastebin.com/u48dxzap e se ancora ottieni un errore incolla tutto il tuo codice e controllerò

Continua a dare lo stesso errore; se faccio print_r($top_parent_terms), ottengo un array vuoto, quindi forse il problema è effettivamente con la prima funzione? La mia versione qui - http://pastebin.com/cMUxs9Nn

OK penso che il problema sia con get_the_ID
che funziona nel loop quindi prova questo: http://pastebin.com/u48dxzap

@Bainternet facciamo continuare questa discussione nella chat

@Bainternet-it quel messaggio nella chat è stato pubblicato automaticamente? Riguardo a global $post e post->ID, sto usando questo all'interno di loop WP_Query quindi get_the_ID dovrebbe funzionare.

Ho avuto lo stesso problema e l'ho risolto facilmente. Guarda qui:
Definisci $taxonomy
. Può essere lo slug della tassonomia di cui vuoi ottenere i dati.
Dopo aver fatto questo, puoi semplicemente fare:
<?php
$postterms = wp_get_post_terms($post->ID, $taxonomy); // ottieni i termini del post
$parentId = $postterms[0]->parent; // ottieni l'ID del termine genitore
$parentObj = get_term_by('id', $parentId, $taxonomy); // ottieni l'oggetto genitore
?>
Ora otterrai qualcosa come questo:
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 puoi usare $parentObj
per ottenere lo slug, il nome, l'id, quello che vuoi. Basta usare $parentObj->slug
o $parentObj->name
come esempio.

Forse questo può aiutare: get_ancestors( $object_id, $object_type );
