¿Cómo mostrar una lista de términos jerárquica?

27

Tengo una taxonomía jerárquica llamada 'ubicaciones geográficas'. Contiene continentes en un primer nivel, y luego los países para cada uno. Ejemplo:

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

etc.

Usando get_terms () logré mostrar la lista completa de términos, pero los continentes se mezclan con los países, en una gran lista plana.

¿Cómo puedo generar una lista jerárquica como la de arriba?

    
pregunta mike23 13.04.2011 - 16:23

10 respuestas

15

Use wp_list_categories con el argumento de taxonomía, está diseñado para crear listas de categorías jerárquicas, pero también admite el uso de una taxonomía personalizada ..

Ejemplo de códice:
Mostrar términos en una taxonomía personalizada

Si la lista vuelve plana, es posible que solo necesite un poco de CSS para agregar relleno a las listas, para que pueda ver su estructura jerárquica.

    
respondido por el t31os 13.04.2011 - 16:38
35

Me doy cuenta de que esta es una pregunta muy antigua, pero si necesita crear una estructura de términos, este podría ser un método útil para usted:

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

El uso es el siguiente:

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

var_dump($categoryHierarchy);
    
respondido por el pospi 15.05.2013 - 08:54
9

No conozco ninguna función que haga lo que quieres, pero puedes crear algo como esto:

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

No he probado esto, pero puedes ver a qué me refiero. Lo que hará el código anterior es darle solo dos niveles

EDITAR: ahh, sí, puedes usar wp_list_categories () para hacer lo que desees.

    
respondido por el Brady 13.04.2011 - 16:39
5

Puede usar wp_list_categories (), con un argumento de 'taxonomía'.

    
respondido por el scribu 13.04.2011 - 16:37
3

Mientras buscaba lo mismo pero para obtener los términos de una publicación, finalmente compilé esto, y me funciona.

Lo que hace:
• obtiene todos los términos de un nombre de taxonomía para una publicación específica.
• para una taxonomía jerárquica con dos niveles (por ejemplo, nivel1: 'país' y nivel2: 'ciudades'), crea un h4 con el nivel1 seguido de una lista ul de nivel2 y esto para todos los elementos del nivel 1.
• Si la taxonomía no es jerárquica, solo creará una lista ul de todos los elementos. Aquí está el código (lo escribo para mí, así que traté de ser lo más genérico posible pero ...):

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

Entonces, finalmente, llamas a la función con esto (obviamente, reemplazas mi_taxonomía por la tuya): finishingLister('my_taxonomy');

No pretendo que sea perfecto, pero como dije, funciona para mí.

    
respondido por el Trouille2 21.02.2013 - 16:55
3

El siguiente código generará un menú desplegable con términos, pero también puede generar cualquier otro elemento / estructura editando la variable $ outputTemplate y editando líneas 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>';  
    
respondido por el Wesam Alalem 13.01.2016 - 12:18
1

Tuve este problema y ninguna de las respuestas aquí funcionó para mí, por una razón u otra.

Aquí está mi versión actualizada y en funcionamiento.

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

Y uso:

$selector = locationSelector('locationSelectClass');
echo $selector;
    
respondido por el Joe Tannorella 30.11.2013 - 11:35
0

Utilicé el código @popsi que funcionaba muy bien y lo hice más eficiente y fácil de leer:

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

Uso:

$sorted_terms = sort_terms_hierarchicaly($terms);
    
respondido por el Pierre Roels 09.07.2018 - 14:44
-1

Asegúrese de que hierarchical=true se pase a su llamada get_terms() .

Tenga en cuenta que hierarchical=true es el valor predeterminado, así que realmente, solo asegúrese de que no se haya anulado para que sea false .

    
respondido por el Chip Bennett 13.04.2011 - 16:31
-1

Aquí tengo una lista desplegable de cuatro niveles con el primer elemento oculto

<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>
    
respondido por el Powiększanie biustu 25.03.2013 - 10:31

Lea otras preguntas en las etiquetas