Hiyerarşik terimler listesi nasıl gösterilir?


34

'Coğrafi konumlar' olarak adlandırılan hiyerarşik bir taksonomiye sahibim. İlk seviyede kıtalar ve daha sonra her biri için ülkeler içerir. Örnek :

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

vb.

Get_terms () kullanarak terimlerin tam listesini çıkarmayı başardım, ancak kıtalar ülkelerle karışık bir büyük listeye girdi.

Yukarıdaki gibi hiyerarşik bir listeyi nasıl çıkartabilirim?


2
Herhangi birinin hiyerarşik bir KONTROL LİSTESİ'ne ihtiyacı varsa (buradaki soru değil ancak hiyerarşik taksonomiler için özel UI oluşturan kişilerle ilgili), en iyi cevap wp_terms_checklist () 'i özel taksonominizle kullanmaktır.
jerclarke

Yanıtlar:


19

Argüman wp_list_categoriesile kullanın 'taxonomy' => 'taxonomy', hiyerarşik kategori listeleri oluşturmak için inşa edilmiştir, aynı zamanda özel bir taksonomi kullanmayı da destekler.

Kodeks Örneği:
Terimleri özel bir taksonomide gösterme

Liste düz görünüyorsa, listelere dolgu eklemek için biraz CSS'ye ihtiyacınız olabilir, böylece hiyerarşik yapılarını görebilirsiniz.


Bu tersine çevrilebilir mi? Önce çocukları göster ..
Arg Geo

43

Farkındayım, bu çok eski bir soru, ama gerçek bir gerçekleşme ihtiyacı varsa terim yapısı , bu sizin için yararlı bir yöntem olabilir:

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

Kullanım aşağıdaki gibidir:

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

var_dump($categoryHierarchy);

3
Bu aslında gerçekten çok iyi. Bir şeyi değiştirirdim: $into[$cat->term_id] = $cat;içine $into[] = $cat;dizi anahtarı sinir bozucu olarak terimin kimliğine sahip olmak (0 tuşunu kullanarak ilk öğeyi kolayca elde edemezsiniz) ve işe yaramaz ( $catnesneyi zaten saklıyorsunuz ve kimliği alabilirsiniz. term_idözelliği kullanarak
Nahuel

Benim gibi, bu işlevi alt kategorilerdeki bir kategoriye uygulamaya çalışıyorsanız, şu an çalışmakta olduğunuz seviyenin kimliğini girmeniz gerekir. Ama güzel çalışır, teşekkürler, teşekkürler.
Ben Everard

bu işe
yarar

10

İstediğinizi yapan herhangi bir işlevi bilmiyorum ama böyle bir şey oluşturabilirsiniz:

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

Bunu test etmedim ama neye bulaştığımı görebilirsiniz. Yukarıdaki kodun ne yapacağı size sadece iki seviye vermektir

EDIT: ahh evet sonra ne yapmak için wp_list_category () kullanabilirsiniz.


Aslında bu oldukça kullanışlıdır, çünkü bağlantılar üzerinde özel bağlantılara (GET param ile) sahip olmam gerekiyor, ki bunu wp_list_category () yöntemiyle yapmak mümkün görünmüyor.
mike23 15

1
Evet, bu yöntem çıktılarınız üzerinde daha fazla kontrol sağlayacaktır. Ancak wp_list_categories(), GET parametrelerinize eklemek için çıktılarını bulmak ve değiştirmek için biraz güzel bir şeyler yapabilirsiniz . Veya fonksiyonun istediğiniz bitlere ekleyebilmesi için bir filtre oluşturabilirsiniz. Bana bunu nasıl yaptığınızı sorma, henüz kafamı bulamadım çünkü:
Brady

3
Bir kullanarak öneririm özel kategori Walker ile wp_list_categories.. Eğer çıkış üzerinde daha fazla kontrol istiyorsanız, kodunuzu çok daha yeniden kullanılabilir yapacağız
t31os

6

'Taksonomi' argümanı ile wp_list_category () öğesini kullanabilirsiniz.


3

Aynı şeyi ararken, ancak bir gönderinin koşullarını almak için nihayet bunu derledim ve bu benim için çalışıyor.

Ne yapar:
• belirli bir yazı için tüm taksonomi ismini alır
• iki seviyeli hiyoksik bir taksonomi için (örneğin: seviye1: 'ülke' ve seviye2: 'şehirler), seviye1'i takip eden bir h4 ve ardından seviye2'nin ul listesi ve tüm seviye1 maddeler için.
• Taksonomi hiyerarşik değilse, tüm öğelerin sadece bir ul listesini oluşturacaktır. İşte kod (benim için yazıyorum, bu yüzden olabildiğince jenerik olmaya çalıştım ama ...):

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

Sonunda fonksiyonu şununla çağırıyorsunuz (açıkçası, my_taxonomy'yi sizinkilerle değiştirirsiniz): finishingLister('my_taxonomy');

Mükemmel gibi davranmıyorum ama dediğim gibi benim için çalışıyor.


3

Aşağıdaki kod, terimlerle birlikte aşağı açılır, ancak $ outputTemplate değişkenini düzenleyerek ve str_replace satırlarını düzenleyerek başka herhangi bir öğe / yapı da oluşturabilir:

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

1

Bu problemi yaşadım ve buradaki cevapların hiçbiri bir nedenden ötürü benim için işe yaramadı.

İşte benim güncellenmiş ve çalışan versiyonum.

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

Ve kullanım:

$selector = locationSelector('locationSelectClass');
echo $selector;

1

Gerçekten iyi çalışan @popsi kodunu kullandım ve okumayı daha verimli ve kolay hale getirdim:

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

Kullanım:

$sorted_terms = sort_terms_hierarchicaly($terms);

-1

Aramanıza hierarchical=trueiletildiğinden emin olun get_terms().

Bunun hierarchical=truevarsayılan olduğunu unutmayın , yani gerçekten, geçersiz kılınmadığından emin olun false.


Merhaba Chip, evet 'hiyerarşik' varsayılan olarak 'true'.
mike23

Çıktının canlı örneğine bir link verebilir misiniz?
Chip Bennett,

Neredeyse iki yıl önce bırakılmış bir cevap hakkında yorum yapmak? Gerçekten mi? Aslında olan bir soru olarak ifadeli olsa bile, önerilen cevap. Bunu bir sorudan ziyade bir ifade olarak düzenleyeyim mi?
Chip Bennett,

get_terms()Şartların tam bir listesini (OP'nin belirtildiği gibi) geri getirecek, ancak talep edildiği şekilde ebeveyn / çocuk ilişkisini gösteren hiyerarşik bir listeyi sunmayacaktır.
jdm2112

-1

Burada gizli ilk madde ile dört seviye açılır seçim listesi var

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

2
Lütfen bunun sorunu neden çözebileceğini açıklayın .
fuxia

Bence mantık bunun bir problem olduğudur. Bu yazıyı, kategori stilinde bir hiyerarşik kontrol listesinin nasıl alınacağını bulmaya çalışırken buldum ve şimdi çözdüğümde buraya bir cevap eklemek için can atıyorum. Olmayacağım çünkü belirttiğin gibi OQ'ya cevap vermiyor.
jerclarke
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.