จะแสดงรายการคำที่เป็นลำดับขั้นได้อย่างไร


34

ฉันมีอนุกรมวิธานลำดับชั้นเรียกว่า 'ที่ตั้งทางภูมิศาสตร์' มันประกอบด้วยทวีปในระดับแรกและจากนั้นแต่ละประเทศสำหรับแต่ละประเทศ ตัวอย่าง:

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

เป็นต้น

การใช้ get_terms () ฉันจัดการเพื่อแสดงรายการคำศัพท์ทั้งหมด แต่ทวีปต่าง ๆ ปะปนกับประเทศต่างๆในรายการแบนขนาดใหญ่รายการเดียว

ฉันจะแสดงรายการลำดับชั้นตามที่ได้กล่าวไว้ข้างต้น


2
ในกรณีที่ทุกคนต้องการ CHECKLIST แบบลำดับขั้น (ไม่ใช่คำถามที่นี่ แต่เกี่ยวข้องกับผู้ที่สร้าง UI แบบกำหนดเองสำหรับ taxonomies ลำดับชั้น) คำตอบที่ดีที่สุดคือการใช้ wp_terms_checklist () กับอนุกรมวิธานที่กำหนดเองของคุณ
jerclarke

คำตอบ:


19

ใช้wp_list_categoriesกับ'taxonomy' => 'taxonomy'อาร์กิวเมนต์มันถูกสร้างขึ้นสำหรับการสร้างรายการหมวดหมู่แบบลำดับชั้น แต่จะสนับสนุนการใช้อนุกรมวิธานที่กำหนดเอง ..

ตัวอย่าง Codex:
แสดงคำศัพท์ในอนุกรมวิธานที่กำหนดเอง

หากรายการกลับมาดูเป็นไปได้คุณอาจต้องใช้ CSS เล็กน้อยเพื่อเพิ่มการขยายไปยังรายการดังนั้นคุณจึงสามารถเห็นโครงสร้างลำดับชั้นได้


สิ่งนี้สามารถย้อนกลับ? แสดงลูกก่อน ..
จีโอ

43

ฉันรู้ว่านี่เป็นคำถามที่เก่ามาก แต่ถ้าคุณต้องการสร้างโครงสร้างที่แท้จริงของคำศัพท์นี้อาจเป็นวิธีที่มีประโยชน์สำหรับคุณ:

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

การใช้งานมีดังนี้:

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

var_dump($categoryHierarchy);

3
นี่เป็นสิ่งที่ดีจริงๆ ฉันจะเปลี่ยนสิ่งหนึ่งที่: $into[$cat->term_id] = $cat;เข้าไป$into[] = $cat;มี ID ของคำเป็นกุญแจสำคัญในอาร์เรย์เป็นที่น่ารำคาญ (คุณไม่สามารถได้รับองค์ประกอบแรกอย่างง่ายดายโดยใช้ 0 กุญแจ) และไร้ประโยชน์ (คุณแล้วการจัดเก็บ$catวัตถุและคุณสามารถรับประชาชนได้ การใช้term_idทรัพย์สิน
Nahuel

หากเหมือนฉันคุณกำลังพยายามใช้ฟังก์ชั่นนี้กับหมวดหมู่ย่อยคุณจะต้องผ่าน ID ของระดับที่คุณอยู่ในปัจจุบันเพื่อให้สามารถใช้งานได้ แต่มันทำงานได้ดีขอบคุณ @ popsi
Ben Everard

ว่างานขอขอบคุณ
Luca Reghellin

10

ฉันไม่รู้ถึงฟังก์ชั่นใด ๆ ที่ทำในสิ่งที่คุณต้องการ แต่คุณสามารถสร้างบางอย่างเช่นนี้:

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

ฉันยังไม่ได้ทดสอบสิ่งนี้ แต่คุณสามารถเห็นสิ่งที่ฉันได้รับ สิ่งที่รหัสข้างต้นจะทำคือให้สองระดับเท่านั้น

แก้ไข: อ่าใช่คุณสามารถใช้ wp_list_categories () เพื่อทำสิ่งที่คุณต้องการ


อันที่จริงมันมีประโยชน์มากเพราะฉันต้องมีลิงก์ที่กำหนดเอง (ที่มี GET param) ในลิงก์คำศัพท์ซึ่งดูเหมือนจะเป็นไปไม่ได้ด้วยวิธี wp_list_categories ()
mike23

1
ใช่วิธีนี้จะให้การควบคุมเอาต์พุตของคุณมากขึ้น แต่คุณสามารถค้นหาและแทนที่บิตของเอาต์พุตwp_list_categories()เพื่อเพิ่มในพารามิเตอร์ GET ของคุณ หรือสร้างตัวกรองที่ดียิ่งขึ้นเพื่อให้ฟังก์ชันเพิ่มบิตที่คุณต้องการ อย่าถามฉันว่าคุณทำตามที่ผมยังไม่ได้รับสามารถรับหัวของฉันรอบมัน :(
เบรดี้

3
ผมขอแนะนำให้ใช้หมวดหมู่ที่กำหนดเองวอล์คเกอร์ด้วยwp_list_categoriesถ้าคุณต้องการควบคุมมากขึ้นกว่าการส่งออกมันจะทำให้รหัสของคุณมากนำมาใช้ใหม่มากขึ้น ..
t31os


3

ในขณะที่ฉันกำลังมองหาสิ่งเดียวกัน แต่เพื่อรับเงื่อนไขของหนึ่งโพสต์ในที่สุดฉันก็รวบรวมมันและมันได้ผลสำหรับฉัน

ให้ทำอะไร:
•ได้รับชื่อเงื่อนไขการจัดเรียงทั้งหมดสำหรับโพสต์ที่เฉพาะเจาะจง
•สำหรับอนุกรมวิธานเชิงลำดับชั้นที่มีสองระดับ (เช่นระดับ 1: 'ประเทศ' และระดับ 2: 'เมือง') จะสร้าง h4 ด้วยระดับ 1 ตามด้วยรายการ ul ของระดับ 2 และสิ่งนี้สำหรับทุกรายการระดับ 1
•หากอนุกรมวิธานไม่ได้เป็นลำดับชั้นมันจะสร้างเพียงรายการ ul ของรายการทั้งหมด นี่คือรหัส (ฉันเขียนให้ฉันดังนั้นฉันจึงพยายามที่จะเป็นสามัญที่สุดเท่าที่จะทำได้ แต่ ... ):

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

ดังนั้นในที่สุดคุณก็เรียกใช้ฟังก์ชันด้วยสิ่งนี้ (เห็นได้ชัดว่าคุณแทนที่ my_taxonomy โดยคุณ): finishingLister('my_taxonomy');

ฉันไม่เสแสร้งว่ามันสมบูรณ์แบบ แต่อย่างที่บอกไปแล้ว


3

รหัสต่อไปนี้จะสร้างรายการแบบหล่นลงพร้อมเงื่อนไข แต่ยังสามารถสร้างองค์ประกอบ / โครงสร้างอื่น ๆ โดยแก้ไขตัวแปร $ outputTemplate และแก้ไขบรรทัด 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>';  

1

ฉันมีปัญหานี้และไม่มีคำตอบที่นี่สำหรับฉันด้วยเหตุผลใดเหตุผลหนึ่ง

นี่คือเวอร์ชันที่อัปเดตและใช้งานของฉัน

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

และการใช้งาน:

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

1

ฉันใช้ @popsi code ที่ใช้งานได้ดีจริง ๆ และทำให้มันมีประสิทธิภาพมากขึ้นและอ่านง่าย:

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

การใช้งาน:

$sorted_terms = sort_terms_hierarchicaly($terms);

-1

ตรวจสอบให้แน่ใจว่าhierarchical=trueมันถูกส่งผ่านไปยังของคุณget_terms()สาย

ทราบว่าเป็นค่าเริ่มต้นดังนั้นจริงๆเพียงให้แน่ใจว่ามันไม่ได้รับการแทนที่จะเป็นhierarchical=truefalse


สวัสดีชิปใช่ 'ลำดับชั้น' เป็น 'จริง' โดยค่าเริ่มต้น
mike23

คุณสามารถให้ลิงค์ไปยังตัวอย่างสดของผลลัพธ์ได้หรือไม่?
Chip Bennett

แสดงความคิดเห็นในคำตอบที่เหลือเกือบสองปีที่ผ่านมา? จริงๆ? ที่จริงแล้วมันเป็นคำตอบที่นำเสนอแม้ว่าคำพูดเป็นคำถาม ฉันควรจะแก้ไขมันให้เป็นข้อความแทนที่จะเป็นคำถามหรือไม่?
Chip Bennett

get_terms()จะส่งคืนรายการเงื่อนไขทั้งหมด (ตาม OP ที่ระบุไว้) แต่ไม่ใช่รายการลำดับชั้นที่แสดงความสัมพันธ์ระหว่างผู้ปกครอง / เด็กตามที่ร้องขอ
jdm2112

-1

ที่นี่ฉันมีรายการเลือกแบบเลื่อนลงสี่ระดับพร้อมรายการแรกที่ซ่อนอยู่

<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
โปรดอธิบายสาเหตุที่สามารถแก้ปัญหาได้
fuxia

ฉันคิดว่าเหตุผลก็คือมันเป็นปัญหาที่เกี่ยวข้อง ฉันพบว่าโพสต์นี้พยายามที่จะหาวิธีรับรายการตรวจสอบลำดับชั้นตามสไตล์หมวดหมู่และฉันถูกล่อลวงให้เพิ่มคำตอบที่นี่ตอนนี้ที่ฉันคิดออกแล้ว ฉันไม่คิดว่าเพราะเมื่อคุณชี้ให้เห็นมันไม่ได้ตอบ OQ
jerclarke
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.