Comment afficher une liste de termes hiérarchique?

27

J'ai une taxonomie hiérarchique appelée "lieux géographiques". Il contient les continents sur un premier niveau, puis les pays pour chacun. Exemple:

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

etc.

À l’aide de get_terms (), j’ai réussi à afficher la liste complète des termes, mais les continents se confondent avec les pays dans une seule et même liste.

Comment puis-je générer une liste hiérarchique comme ci-dessus?

    
posée mike23 13.04.2011 - 16:23
la source

10 réponses

15

Utilisez wp_list_categories avec l'argument taxonomy, il est conçu pour créer des listes de catégories hiérarchiques, mais prend également en charge l'utilisation d'une taxonomie personnalisée.

Exemple de codex:
Afficher les termes d'une taxonomie personnalisée

Si la liste semble plate, il vous suffira peut-être d'un peu de CSS pour ajouter du remplissage aux listes afin que vous puissiez voir leur structure hiérarchique.

    
réponse donnée t31os 13.04.2011 - 16:38
la source
35

Je réalise que la question est très ancienne, mais si vous avez besoin de créer une structure de termes, cela pourrait être une méthode utile pour vous:

/**
 * 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);
    }
}

L'utilisation est la suivante:

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

var_dump($categoryHierarchy);
    
réponse donnée pospi 15.05.2013 - 08:54
la source
9

Je ne connais aucune fonction qui fasse ce que vous voulez, mais vous pouvez créer quelque chose comme ceci:

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

Je n'ai pas testé cela, mais vous pouvez voir où je veux en venir. Le code ci-dessus ne vous donnera que deux niveaux

EDIT: ahh oui, vous pouvez utiliser wp_list_categories () pour faire ce que vous voulez.

    
réponse donnée Brady 13.04.2011 - 16:39
la source
5

Vous pouvez utiliser wp_list_categories () avec un argument 'taxonomy'.

    
réponse donnée scribu 13.04.2011 - 16:37
la source
3

Comme je recherchais la même chose, mais pour obtenir les conditions d'un poste, je l'ai finalement compilé, et cela fonctionne pour moi.

Ce que ça fait:
• il obtient tous les termes d'un nom de taxonomie pour un article spécifique.
• pour une taxonomie hiérarchique à deux niveaux (ex: niveau1: 'pays' et niveau2: 'villes'), il crée un h4 avec le niveau1 suivi d'une liste ul de niveau2 et ceci pour tous les éléments de niveau1.
• si la taxonomie n'est pas hiérarchique, il ne créera qu'une liste ul de tous les éléments. voici le code (je l’écris pour moi alors j’ai essayé d’être aussi générique que possible mais ...):

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

Alors finalement, vous appelez la fonction avec ceci (vous remplacez évidemment my_taxonomy par le vôtre): finishingLister('my_taxonomy');

Je ne prétends pas que c'est parfait, mais comme je l'ai dit, cela fonctionne pour moi.

    
réponse donnée Trouille2 21.02.2013 - 16:55
la source
3

Le code suivant générera une liste déroulante avec les termes, mais peut également générer tout autre élément / structure en modifiant la variable $ outputTemplate et en modifiant les lignes str_replace:

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>';  
    
réponse donnée Wesam Alalem 13.01.2016 - 12:18
la source
1

J'avais ce problème et aucune des réponses ici ne fonctionnait pour moi, pour une raison ou une autre.

Voici ma version mise à jour et fonctionnelle.

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

Et utilisation:

$selector = locationSelector('locationSelectClass');
echo $selector;
    
réponse donnée Joe Tannorella 30.11.2013 - 11:35
la source
0

J'ai utilisé le code @popsi qui fonctionnait très bien et je l'ai rendu plus efficace et plus facile à lire:

/**
 * 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;
}

Utilisation:

$sorted_terms = sort_terms_hierarchicaly($terms);
    
réponse donnée Pierre Roels 09.07.2018 - 14:44
la source
-1

Assurez-vous que hierarchical=true est passé à votre appel get_terms() .

Notez que hierarchical=true est la valeur par défaut, alors assurez-vous simplement qu'elle n'a pas été remplacée par false .

    
réponse donnée Chip Bennett 13.04.2011 - 16:31
la source
-1

Ici, j'ai une liste de sélection déroulante à quatre niveaux avec le premier élément caché

<select name="lokalizacja" id="ucz">
            <option value="">Wszystkie lokalizacje</option>
            <?php
            $excluded_term = get_term_by('slug', 'podroze', 'my_travels_places');
            $args = array(
                'orderby' => 'slug',
                'hierarchical' => 'true',
                'exclude' => $excluded_term->term_id,
                'hide_empty' => '0',
                'parent' => $excluded_term->term_id,
            );              
            $hiterms = get_terms("my_travels_places", $args);
            foreach ($hiterms AS $hiterm) :
                echo "<option value='".$hiterm->slug."'".($_POST['my_travels_places'] == $hiterm->slug ? ' selected="selected"' : '').">".$hiterm->name."</option>\n";

                $loterms = get_terms("my_travels_places", array("orderby" => "slug", "parent" => $hiterm->term_id,'hide_empty' => '0',));
                if($loterms) :
                    foreach($loterms as $key => $loterm) :

                    echo "<option value='".$loterm->slug."'".($_POST['my_travels_places'] == $loterm->slug ? ' selected="selected"' : '').">&nbsp;-&nbsp;".$loterm->name."</option>\n";

                    $lo2terms = get_terms("my_travels_places", array("orderby" => "slug", "parent" => $loterm->term_id,'hide_empty' => '0',));
                    if($lo2terms) :
                        foreach($lo2terms as $key => $lo2term) :

                        echo "<option value='".$lo2term->slug."'".($_POST['my_travels_places'] == $lo2term->slug ? ' selected="selected"' : '').">&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;".$lo2term->name."</option>\n";



                        endforeach;
                    endif;

                    endforeach;
                endif;

            endforeach;
            ?>
         </select>
        <label>Wybierz rodzaj miejsca</label>
        <select name="rodzaj_miejsca" id="woj">
            <option value="">Wszystkie rodzaje</option>
            <?php
            $theterms = get_terms('my_travels_places_type', 'orderby=name');
            foreach ($theterms AS $term) :
                echo "<option value='".$term->slug."'".($_POST['my_travels_places_type'] == $term->slug ? ' selected="selected"' : '').">".$term->name."</option>\n";                   
            endforeach;
            ?>
         </select>
    
réponse donnée Powiększanie biustu 25.03.2013 - 10:31
la source

Lire d'autres questions sur les étiquettes