Bagaimana cara menampilkan daftar istilah hirarkis?

34

Saya memiliki taksonomi hierarkis yang disebut 'lokasi geografis'. Ini berisi benua di tingkat pertama, dan kemudian negara untuk masing-masing. Contoh:

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

dll.

Menggunakan get_terms () saya berhasil menampilkan daftar istilah lengkap, tetapi benua-benua terlibat dengan negara-negara, dalam satu daftar besar.

Bagaimana saya bisa menampilkan daftar hierarkis seperti di atas?

mike23
sumber
2
Jika ada orang yang membutuhkan CHECKLIST hirarkis (bukan pertanyaan di sini tetapi terkait dengan orang-orang yang membangun UI khusus untuk taksonomi hierarki), jawaban terbaik adalah menggunakan wp_terms_checklist () dengan taksonomi khusus Anda.
jerclarke

Jawaban:

19

Gunakan wp_list_categoriesdengan 'taxonomy' => 'taxonomy'argumen, itu dibangun untuk membuat daftar kategori hirarkis tetapi juga akan mendukung menggunakan taksonomi kustom ..

Contoh Codex:
Menampilkan istilah dalam taksonomi khusus

Jika daftar kembali tampak datar, mungkin Anda hanya perlu sedikit CSS untuk menambahkan padding ke daftar, sehingga Anda dapat melihat struktur hierarkis mereka.

t31os
sumber
Mungkinkah ini dibalik? Perlihatkan anak-anak terlebih dahulu ..
Arg Geo
43

Saya menyadari, ini adalah pertanyaan yang sangat lama, tetapi jika Anda memiliki kebutuhan untuk membangun struktur istilah yang sebenarnya , ini mungkin metode yang berguna untuk Anda:

/**
 * 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_hierarchically(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_hierarchically($cats, $topCat->children, $topCat->term_id);
    }
}

Penggunaannya adalah sebagai berikut:

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

var_dump($categoryHierarchy);
pospi
sumber
3
Ini sebenarnya sangat bagus. Saya akan mengubah satu hal: $into[$cat->term_id] = $cat;menjadi $into[] = $cat;Memiliki ID istilah sebagai kunci array mengganggu (Anda tidak bisa mendapatkan elemen pertama dengan mudah menggunakan kunci 0) dan tidak berguna (Anda sudah menyimpan $catobjek dan Anda bisa mendapatkan id menggunakan term_idproperti
Nahuel
Jika seperti saya Anda mencoba menerapkan fungsi ini ke sub-level kategori, Anda harus memberikan ID level yang saat ini Anda gunakan agar berfungsi. Tapi bekerja dengan baik, terima kasih @popsi.
Ben Everard
itu berhasil, terima kasih
Luca Reghellin
10

Saya tidak tahu fungsi apa pun yang melakukan apa yang Anda inginkan tetapi Anda dapat membangun sesuatu seperti ini:

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

Saya belum menguji ini tetapi Anda dapat melihat apa yang saya maksudkan. Apa yang akan dilakukan oleh kode di atas adalah memberi Anda hanya dua level

EDIT: ahh ya Anda dapat menggunakan wp_list_categories () untuk melakukan apa yang Anda inginkan.

Brady
sumber
Sebenarnya ini cukup berguna, karena saya perlu memiliki tautan khusus (dengan param GET) pada tautan istilah, yang sepertinya tidak mungkin dilakukan dengan cara wp_list_categories () untuk melakukannya.
mike23
1
Ya metode ini akan memberikan kontrol lebih besar atas output Anda. Tapi Anda bisa melakukan sedikit mencari dan mengganti pada output wp_list_categories()untuk menambahkan parameter GET Anda. Atau bahkan lebih baik membangun filter untuk fungsi untuk menambahkan bit yang Anda inginkan. Jangan tanya saya bagaimana Anda melakukan itu karena saya belum bisa mengatasinya :(
Brady
3
Saya sarankan menggunakan walker kategori khusus dengan wp_list_categoriesjika Anda ingin kontrol yang lebih besar atas output, itu akan membuat kode Anda jauh lebih dapat digunakan kembali ..
t31os
6

Anda dapat menggunakan wp_list_categories (), dengan argumen 'taksonomi'.

scribu
sumber
3

Karena saya sedang mencari yang sama tetapi untuk mendapatkan syarat satu posting, akhirnya saya mengkompilasi ini, dan itu berfungsi untuk saya.

Kegunaannya:
• ia mendapatkan semua ketentuan nama taksonomi untuk pos tertentu.
• untuk taksonomi hirarki dengan dua level (mis: level1: 'negara' dan level2: 'kota'), ia menciptakan h4 dengan level1 diikuti oleh daftar level2 ul dan ini untuk semua item level1.
• jika taksonomi tidak hierarkis, itu hanya akan membuat daftar semua item ul. di sini adalah kode (saya menulis untuk saya jadi saya mencoba untuk menjadi generik yang saya bisa tetapi ...):

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

Jadi akhirnya Anda memanggil fungsi dengan ini (jelas, Anda mengganti my_taxonomy dengan milik Anda): finishingLister('my_taxonomy');

Saya tidak berpura-pura itu sempurna tetapi seperti yang saya katakan itu bekerja untuk saya.

Trouille2
sumber
3

Kode berikut akan menghasilkan drop-down dengan istilah, tetapi juga dapat menghasilkan elemen / struktur lain dengan mengedit variabel $ outputTemplate, dan mengedit baris 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>';  
wesamly
sumber
1

Saya memiliki masalah ini dan tidak ada jawaban di sini yang bekerja untuk saya, karena satu dan lain alasan.

Ini adalah versi saya yang diperbarui dan berfungsi.

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

Dan penggunaan:

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

Saya menggunakan kode @popsi yang berfungsi sangat baik dan saya membuatnya menjadi lebih efisien dan mudah dibaca:

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

Penggunaan:

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

Pastikan itu hierarchical=truediteruskan ke get_terms()panggilan Anda .

Perhatikan bahwa itu hierarchical=trueadalah default, jadi sungguh, pastikan saja itu belum ditimpa false.

Chip Bennett
sumber
Hai Chip, ya 'hierarkis' adalah 'benar' secara default.
mike23
Bisakah Anda memberikan tautan ke contoh langsung dari hasil?
Chip Bennett
Mengomentari jawaban yang tersisa hampir dua tahun lalu? Sangat? Sebenarnya, itu adalah jawaban yang diusulkan, bahkan jika diucapkan sebagai pertanyaan. Haruskah saya mengeditnya menjadi pernyataan, bukan pertanyaan?
Chip Bennett
get_terms()akan mengembalikan daftar lengkap persyaratan (seperti yang dinyatakan OP) tetapi bukan daftar hierarki yang menunjukkan hubungan orang tua / anak seperti yang diminta.
jdm2112
-1

Di sini saya memiliki daftar pilih turun empat tingkat dengan item pertama tersembunyi

<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>
Powiększanie biustu
sumber
2
Tolong jelaskan mengapa itu bisa menyelesaikan masalah.
fuxia
Saya pikir logikanya adalah masalah terkait. Saya menemukan posting ini berusaha mencari cara untuk mendapatkan daftar periksa hierarki kategori-gaya dan tergoda untuk menambahkan jawaban di sini sekarang setelah saya menemukannya. Saya tidak akan melakukannya karena ketika Anda menunjukkan itu tidak menjawab OQ.
jerclarke