Wie liste ich nur die untergeordneten Begriffe einer Taxonomie auf und nicht deren Eltern?

9

Ich erstelle ein Altersauswahlmenü im Administrator, das aus einer Taxonomie von ausgefüllt ist age. Die Taxonomie ist wie folgt hierarchisch:

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

Ich möchte nur die Kinder (18, 19 usw.) und nicht die Eltern (18-25, 26-30) usw. auflisten. Derzeit verwende ich get_termsdas parentArgument, aber es akzeptiert nicht mehr als 1 Eltern-ID. Folgendes habe ich bisher, das die Kinder von 18 bis 25 Jahren zeigt.

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

Hier ist, was ich möchte, aber nicht unterstützt wird. Ich habe es auch mit einem Array versucht, aber es funktioniert auch nicht.

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

Ich sehe, dass es eine Funktion get_term_children gibt , aber ich bin mir nicht sicher, wie ich diese verwenden soll, da sie anscheinend auch nur einen Wert akzeptiert. Beispiel: In diesem Beispiel würde eine ungeordnete Liste erstellt, aber ich könnte sie für das Auswahlmenü ändern.

<?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>';
?> 
Andrew
quelle
get_termsZweimal anrufen und die beiden Ergebnisfelder zusammenführen?
Mark Duncan
@Mark Danke, ich habe darüber nachgedacht, es so zu machen, aber selbst wenn ich die IDs zu einem Array zusammenführe, kann ich nicht sehen, wie es funktionieren würde, da es das gleiche wäre, als würde man sie manuell auflisten - 183, 184, was nicht der Fall ist. ' t arbeiten.
Andrew
Nachdem ich die akzeptierte Antwort gelesen habe, stelle ich fest, dass Ihre Frage nicht ganz klar war, was das Aussehen der Dinge betrifft, die Sie alle Begriffe wollten , mit Ausnahme derjenigen der obersten Ebene. (Was Sie mit einem einzigen get_termsAnruf tun können ). Ihre Frage lautete, als wollten Sie alle Kinder mit zwei bestimmten Elternbegriffen.
Mark Duncan

Antworten:

14

Dies sollte für Sie funktionieren:

$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>';
Manny Fleurmond
quelle
Danke @Manny, hat ein Vergnügen gemacht. Ich nahm das, was Sie bereitgestellt hatten, und pürierte es in das Auswahlmenü, nach dem ich gesucht hatte. Tolles Zeug.
Andrew
Kein Problem. Ich bin froh, dass es für dich geklappt hat.
Manny Fleurmond
1
Siehe karimhossenbux ‚s Antwort unten für eine wesentlich effizientere Antwort.
Dotancohen
$term->nameist ungültig in get_term_link(), es akzeptiert nur den Begriff ID, Schnecke oder Objekt
Pieter Goosen
14

Sie könnten auch tun:

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

Ich habe festgestellt, dass Eltern ein "Eltern" -Feld gleich 0 haben und ein Kind seine Eltern-ID darin hat.

karimhossenbux
quelle
4
Die akzeptierte Antwort führt N get_terms () -Aufrufe aus und wird in Polynomzeit ausgeführt. Diese Antwort führt einen einzelnen Aufruf von get_terms () aus und wird in linearer Zeit ausgeführt. Dies ist eine viel bessere Antwort.
Dotancohen
@dotancohen Sie können dies tun, ohne Begriffe der obersten Ebene bei der Ausgabe ausschließen zu müssen. Sie können Begriffe der obersten Ebene mit dem wpse_exclude_topParameter entfernen , der den Abfrageargumenten hinzugefügt wurde ;-). Ich stimme jedoch zu, dies ist schneller als die akzeptierte Antwort
Pieter Goosen
1
@PieterGoosen: Danke Pieter. Ich habe gerade den 4.4.2-Quellcode für die Zeichenfolgen gepackt wpse_exclude_topund exclude_topsie nicht gefunden. Google weiß auch nichts davon. Wo ist es dokumentiert?
Dotancohen
1
@dotancohen in meiner Antwort ;-)
Pieter Goosen
4

Wir können die Eltern der obersten Ebene ausschließen, indem wir sie herausfiltern, indem wir den terms_clausesFilter verwenden, um die SQL-Abfrage zu ändern, bevor sie ausgeführt wird. Auf diese Weise müssen wir Eltern nicht in der letzten foreachSchleife überspringen, da sie nicht in der zurückgegebenen Reihe von Begriffen enthalten sind. Dies erspart uns unnötige Arbeit und Codierung

Sie können Folgendes versuchen:

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

Um Eltern der obersten Ebene auszuschließen, können wir jetzt 'wpse_exclude_top' => 1mit unseren Argumenten übergeben. Der neue wpse_exclude_topParameter wird vom obigen Filter unterstützt

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

Nur eine Anmerkung, get_term_link()akzeptieren Sie nicht den Begriff Namen, nur Slug, ID oder das vollständige Begriff Objekt. Übergeben Sie für die Leistung immer den Begriff Objekt an, get_term_link()wenn der Begriff Objekt verfügbar ist ( wie in diesem Fall ).

Pieter Goosen
quelle
2

Warum können Sie das childlessArgument nicht einfach auf true setzen?

$ages = get_terms( array(
    'taxonomy' => 'age',
    'childless' => true
    )
);
Yaron
quelle
Wenn Sie das childlessArgument auf true setzen, können Sie nur eine Ebene tief gehen. Dies funktioniert also nicht für Taxonomien mit drei oder mehr Ebenen.
GeckoSEO
-1

Wenn Sie das Kind mehrerer Eltern anzeigen, können Sie dies versuchen. Erwähnung des Begriffs des untergeordneten Begriffs.

$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>';
    }
  }
}
Jakir Hossain
quelle
1
Bitte erläutern Sie, warum dieser Code Ihrer Meinung nach funktionieren sollte. Ich bin mir auch ziemlich sicher, dass eine fest codierte Lösung nicht der beste Weg ist.
s_ha_dum
Frage Erwähnungen mit IDs, aus diesem Grund habe ich verwandte Gedanken beantwortet.
Jakir Hossain