web-dev-qa-db-de.com

Wie zeige ich eine hierarchische Begriffsliste an?

Ich habe eine hierarchische Taxonomie namens "geografische Standorte". Es enthält Kontinente auf einer ersten Ebene und dann die Länder für jeden einzelnen. Beispiel:

Europe
- Ireland
- Spain
- Sweden
Asia
- Laos
- Thailand
- Vietnam

usw.

Mit get_terms () habe ich es geschafft, die vollständige Liste der Begriffe auszugeben, aber die Kontinente werden mit den Ländern in einer großen, flachen Liste verwechselt.

Wie kann ich eine hierarchische Liste wie oben ausgeben?

31
mike23

Verwenden Sie wp_list_categories mit dem Taxonomie-Argument. Es wurde für die Erstellung hierarchischer Kategorielisten entwickelt, unterstützt jedoch auch die Verwendung einer benutzerdefinierten Taxonomie.

Codex-Beispiel:
Begriffe in einer benutzerdefinierten Taxonomie anzeigen

Wenn die Liste flach erscheint, brauchen Sie möglicherweise nur ein wenig CSS, um die Listen aufzufüllen, damit Sie ihre hierarchische Struktur sehen können.

16
t31os

Mir ist klar, dass dies eine sehr alte Frage ist, aber wenn Sie eine tatsächliche Struktur von Begriffen aufbauen müssen, könnte dies eine nützliche Methode für Sie sein:

/**
 * Recursively sort an array of taxonomy terms hierarchically. Child categories will be
 * placed under a 'children' member of their parent term.
 * @param Array   $cats     taxonomy term objects to sort
 * @param Array   $into     result array to put them in
 * @param integer $parentId the current parent ID to put them in
 */
function sort_terms_hierarchicaly(Array &$cats, Array &$into, $parentId = 0)
{
    foreach ($cats as $i => $cat) {
        if ($cat->parent == $parentId) {
            $into[$cat->term_id] = $cat;
            unset($cats[$i]);
        }
    }

    foreach ($into as $topCat) {
        $topCat->children = array();
        sort_terms_hierarchicaly($cats, $topCat->children, $topCat->term_id);
    }
}

Verwendung ist wie folgt:

$categories = get_terms('my_taxonomy_name', array('hide_empty' => false));
$categoryHierarchy = array();
sort_terms_hierarchicaly($categories, $categoryHierarchy);

var_dump($categoryHierarchy);
40
pospi

Ich kenne keine Funktion, die das tut, was Sie wollen, aber Sie können so etwas aufbauen:

<ul>
    <?php $hiterms = get_terms("my_tax", array("orderby" => "slug", "parent" => 0)); ?>
    <?php foreach($hiterms as $key => $hiterm) : ?>
        <li>
            <?php echo $hiterm->name; ?>
            <?php $loterms = get_terms("my_tax", array("orderby" => "slug", "parent" => $hiterm->term_id)); ?>
            <?php if($loterms) : ?>
                <ul>
                    <?php foreach($loterms as $key => $loterm) : ?>
                        <li><?php echo $loterm->name; ?></li>
                    <?php endforeach; ?>
                </ul>
            <?php endif; ?>
        </li>
    <?php endforeach; ?>
</ul>

Ich habe das nicht getestet, aber Sie können sehen, worauf ich hinaus will. Mit dem obigen Code erhalten Sie nur zwei Ebenen

EDIT: ahh ja du kannst mit wp_list_categories () machen was du willst.

10
Brady

Sie können wp_list_categories () mit dem Argument 'taxonomy' verwenden.

6
scribu

Der folgende Code generiert ein Dropdown-Menü mit Begriffen, kann aber auch jedes andere Element/jede andere Struktur generieren, indem Sie die Variable $ outputTemplate bearbeiten und die Zeilen str_replace bearbeiten:

function get_terms_hierarchical($terms, $output = '', $parent_id = 0, $level = 0) {
    //Out Template
    $outputTemplate = '<option value="%ID%">%PADDING%%NAME%</option>';

    foreach ($terms as $term) {
        if ($parent_id == $term->parent) {
            //Replacing the template variables
            $itemOutput = str_replace('%ID%', $term->term_id, $outputTemplate);
            $itemOutput = str_replace('%PADDING%', str_pad('', $level*12, '&nbsp;&nbsp;'), $itemOutput);
            $itemOutput = str_replace('%NAME%', $term->name, $itemOutput);

            $output .= $itemOutput;
            $output = get_terms_hierarchical($terms, $output, $term->term_id, $level + 1);
        }
    }
    return $output;
}

$terms = get_terms('taxonomy', array('hide_empty' => false));
$output = get_terms_hierarchical($terms);

echo '<select>' . $output . '</select>';  
3
wesamly

Da ich das selbe aber suchte, um Konditionen für einen Beitrag zu bekommen, habe ich dies endlich kompiliert, und es funktioniert bei mir.

Was es macht :
• Es werden alle Begriffe eines Taxonomienamens für einen bestimmten Beitrag abgerufen.
• Für eine hierarchische Taxonomie mit zwei Ebenen (z. B. Ebene 1: 'Land' und Ebene 2: 'Städte') wird ein h4 mit Ebene 1 erstellt, gefolgt von einer ul-Liste von Ebene 2 und dies für alle Elemente der Ebene 1.
• Wenn die Taxonomie nicht hierarchisch ist, wird nur eine ul-Liste aller Elemente erstellt. Hier ist der Code (ich schreibe ihn für mich, also habe ich versucht, so allgemein wie möglich zu sein, aber ...):

function finishingLister($heTerm){
    $myterm = $heTerm;
    $terms = get_the_terms($post->ID,$myterm);
    if($terms){
        $count = count($terms);
        echo '<h3>'.$myterm;
        echo ((($count>1)&&(!endswith($myterm, 's')))?'s':"").'</h3>';
        echo '<div class="'.$myterm.'Wrapper">';
        foreach ($terms as $term) {
            if (0 == $term->parent) $parentsItems[] = $term;
            if ($term->parent) $childItems[] = $term; 
        };
        if(is_taxonomy_hierarchical( $heTerm )){
            foreach ($parentsItems as $parentsItem){
                echo '<h4>'.$parentsItem->name.'</h4>';
                echo '<ul>';
                foreach($childItems as $childItem){
                    if ($childItem->parent == $parentsItem->term_id){
                        echo '<li>'.$childItem->name.'</li>';
                    };
                };
                echo '</ul>';
            };
        }else{
            echo '<ul>';
            foreach($parentsItems as $parentsItem){
                echo '<li>'.$parentsItem->name.'</li>';
            };
            echo '</ul>';
        };
        echo '</div>';
    };
};

Zum Schluss rufen Sie die Funktion mit folgendem Befehl auf (offensichtlich ersetzen Sie my_taxonomy durch yours): finishingLister('my_taxonomy');

Ich tue nicht so, als wäre es perfekt, aber wie gesagt, es funktioniert für mich.

3
Trouille2

Ich hatte dieses Problem und keine der Antworten hier hat aus dem einen oder anderen Grund für mich funktioniert.

Hier ist meine aktualisierte und funktionierende Version.

function locationSelector( $fieldName ) {
    $args = array('hide_empty' => false, 'hierarchical' => true, 'parent' => 0); 
    $terms = get_terms("locations", $args);

    $html = '';
    $html .= '<select name="' . $fieldName . '"' . 'class="chosen-select ' . $fieldName . '"' . '>';
        foreach ( $terms as $term ) {
            $html .= '<option value="' . $term->term_id . '">' . $term->name . '</option>';

            $args = array(
                'hide_empty'    => false, 
                'hierarchical'  => true, 
                'parent'        => $term->term_id
            ); 
            $childterms = get_terms("locations", $args);

            foreach ( $childterms as $childterm ) {
                $html .= '<option value="' . $childterm->term_id . '">' . $term->name . ' > ' . $childterm->name . '</option>';

                $args = array('hide_empty' => false, 'hierarchical'  => true, 'parent' => $childterm->term_id); 
                $granchildterms = get_terms("locations", $args);

                foreach ( $granchildterms as $granchild ) {
                    $html .= '<option value="' . $granchild->term_id . '">' . $term->name . ' > ' . $childterm->name . ' > ' . $granchild->name . '</option>';
                }
            }
        }
    $html .=  "</select>";

    return $html;
}

Und Nutzung:

$selector = locationSelector('locationSelectClass');
echo $selector;
1
Joe Tannorella

Ich habe @popsi-Code verwendet, der sehr gut funktioniert hat und der effizienter und einfacher zu lesen ist:

/**
 * Recursively sort an array of taxonomy terms hierarchically. Child categories will be
 * placed under a 'children' member of their parent term.
 * @param Array   $cats     taxonomy term objects to sort
 * @param integer $parentId the current parent ID to put them in
 */
function sort_terms_hierarchicaly(Array $cats, $parentId = 0)
{
    $into = [];
    foreach ($cats as $i => $cat) {
        if ($cat->parent == $parentId) {
            $cat->children = sort_terms_hierarchicaly($cats, $cat->term_id);
            $into[$cat->term_id] = $cat;
        }
    }
    return $into;
}

Verwendungszweck :

$sorted_terms = sort_terms_hierarchicaly($terms);
1
Pierre R