Come elencare solo i termini figlio di una tassonomia e non i loro genitori?


9

Sto creando un menu di selezione dell'età nell'amministratore, popolato da una tassonomia di age. La tassonomia è gerarchica come segue:

  • 18-25 (genitore, ID 183)
    • 18 (bambino)
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 26-30 (genitore, ID 184)
    • 26
    • 27
    • 28
    • 29
    • 30

Vorrei elencare solo i bambini (18, 19 ecc.) E non i genitori (18-25, 26-30) ecc. Attualmente sto usando get_termsl' parentargomento, ma non accetta più di un ID genitore. Ecco quello che ho finora, che mostra i bambini dai 18 ai 25 anni.

    $ages = get_terms( 'age', array(
        'hide_empty' => 0,
        'parent' => '183',
    ));

Ecco cosa voglio che faccia, ma non è supportato. L'ho provato anche con un array ma non funziona neanche.

    $ages = get_terms( 'age', array(
        'hide_empty' => 0,
        'parent' => '183,184',
    ));

Vedo che esiste una funzione get_term_children , ma non sono sicuro di come utilizzarlo poiché sembra che accetti solo un valore. Ad esempio: in questo esempio creerebbe un elenco non ordinato ma potrei modificarlo per selezionare il menu.

<?php
    $termID = 183;
    $taxonomyName = "age";
    $termchildren = get_term_children( $termID, $taxonomyName );

    echo '<ul>';
    foreach ($termchildren as $child) {
    $term = get_term_by( 'id', $child, $taxonomyName );
    echo '<li><a href="' . get_term_link( $term->name, $taxonomyName ) . '">' . $term->name . '</a></li>';
    }
    echo '</ul>';
?> 

Chiamare get_termsdue volte e unire i due array di risultati?
Mark Duncan,

@Mark Grazie, ho pensato di farlo in questo modo, ma anche se unissi gli ID in un array, non riesco a vedere come funzionerebbe perché sarebbe lo stesso che elencarli manualmente - 183, 184, che non non funziona.
Andrew

Dopo aver letto la risposta accettata, ora mi rendo conto che la tua domanda non era del tutto chiara, dall'aspetto delle cose che volevi tutti i termini, ad esclusione di quelli di alto livello .. (che puoi fare con una sola get_termschiamata). La tua domanda è come se volessi tutti i figli di 2 particolari condizioni genitoriali.
Mark Duncan,

Risposte:


14

Questo dovrebbe funzionare per te:

$taxonomyName = "age";
//This gets top layer terms only.  This is done by setting parent to 0.  
$parent_terms = get_terms( $taxonomyName, array( 'parent' => 0, 'orderby' => 'slug', 'hide_empty' => false ) );   
echo '<ul>';
foreach ( $parent_terms as $pterm ) {
    //Get the Child terms
    $terms = get_terms( $taxonomyName, array( 'parent' => $pterm->term_id, 'orderby' => 'slug', 'hide_empty' => false ) );
    foreach ( $terms as $term ) {
        echo '<li><a href="' . get_term_link( $term ) . '">' . $term->name . '</a></li>';   
    }
}
echo '</ul>';

Grazie @Manny, ha funzionato a meraviglia. Ho preso quello che mi hai fornito e l'ho inserito nel menu di selezione che stavo cercando. Roba fantastica.
Andrew,

Nessun problema. Sono contento che abbia funzionato per te.
Manny Fleurmond,

1
Vedi la risposta di karimhossenbux di seguito per una risposta molto più efficiente.
dotancohen,

$term->namenon è valido in get_term_link(), accetta solo il termine ID, lumaca o oggetto
Pieter Goosen

14

Puoi anche fare:

$terms = get_terms($taxonomyName);
foreach($terms as $term) {
    if ($term->parent != 0) { // avoid parent categories
        //your instructions here
    }
}

Ho notato che il genitore ha un campo "genitore" uguale a 0 e un figlio ha il suo id genitore in esso.


4
La risposta accettata esegue N chiamate get_terms () e viene eseguita in un tempo polinomiale. Questa risposta esegue una singola chiamata get_terms () e viene eseguita in tempo lineare. Questa è una risposta molto migliore.
dotancohen,

@dotancohen Puoi farlo senza dover escludere i termini di livello superiore sull'output, puoi rimuovere i termini di livello superiore con il wpse_exclude_topparametro aggiunto agli argomenti della query ;-). Sono comunque d'accordo, questo è più veloce della risposta accettata
Pieter Goosen

1
@PieterGoosen: Grazie Pieter. Ho appena grepped il codice sorgente 4.4.2 per le stringhe wpse_exclude_tope exclude_topnon le ho trovate. Né Google lo sa. Dove è documentato?
dotancohen,

1
@dotancohen nella mia risposta ;-)
Pieter Goosen

5

È possibile escludere i genitori di livello superiore filtrandoli utilizzando il terms_clausesfiltro per modificare la query SQL prima che venga eseguita. In questo modo non abbiamo bisogno di saltare i genitori nel foreachciclo finale in quanto non sono nella matrice di termini restituiti, questo ci fa risparmiare lavoro e codifica inutili

Puoi provare quanto segue:

add_filter( 'terms_clauses', function (  $pieces, $taxonomies, $args )
{
    // Check if our custom arguments is set and set to 1, if not bail
    if (    !isset( $args['wpse_exclude_top'] ) 
         || 1 !== $args['wpse_exclude_top']
    )
        return $pieces;

    // Everything checks out, lets remove parents
    $pieces['where'] .= ' AND tt.parent > 0';

    return $pieces;
}, 10, 3 );

Per escludere i genitori di livello superiore, ora possiamo passare 'wpse_exclude_top' => 1con la nostra serie di argomenti. Il nuovo wpse_exclude_topparametro è supportato dal filtro sopra

$terms = get_terms( 'category', ['wpse_exclude_top' => 1] );
if (    $terms
     && !is_wp_error( $terms )
) {
    echo '<ul>';
        foreach ($terms as $term) {
            echo '<li><a href="' . get_term_link( $term ) . '">' . $term->name . '</a></li>';  
        }
    echo '</ul>';
}

Solo una nota, get_term_link()non accettare il nome del termine, solo, lumaca, ID o l'oggetto termine completo. Per prestazioni, passare sempre il termine oggetto a get_term_link()se il termine oggetto è disponibile ( come in questo caso )


2

Perché non puoi semplicemente impostare l' childlessargomento su vero?

$ages = get_terms( array(
    'taxonomy' => 'age',
    'childless' => true
    )
);

impostando l' childlessargomento su true significa che puoi passare solo 1 livello in profondità, quindi questo non funziona per le tassonomie con 3 o più livelli.
GeckoSEO,

-1

Se visualizzi il figlio di più genitori, puoi provare questo. Visualizza i termini di menzione ID figlio termine.

$termIds = array(367, 366, 365, 364, 363, 362);
$taxonomyName = "age";

$args = array(
    'orderby'           => 'term_id', 
    'order'             => 'DESC',                      
    'hide_empty'        => false,                       
    'childless'         => false,
); 

$terms = get_terms( $taxonomyName, $args );

if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
$inc = 1;
foreach ( $terms as $term ) {                           
 if (in_array($term->parent, $termIds)) {
  echo '<option value="'.$term->term_id.'"><font><font>'.$term->name.'</font></font></option>';
    }
  }
}

1
Spiega perché pensi che questo codice dovrebbe funzionare. Inoltre, sono abbastanza sicuro che una soluzione hard-coded non sia il modo migliore.
s_ha_dum,

La domanda menziona gli ID, per questo motivo ho risposto al pensiero correlato.
Jakir Hossain,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.