Làm thế nào để hiển thị một danh sách thuật ngữ phân cấp?


34

Tôi có một phân loại phân cấp được gọi là "vị trí địa lý". Nó chứa các lục địa ở cấp độ đầu tiên, và sau đó là các quốc gia cho mỗi quốc gia. Thí dụ :

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

v.v.

Sử dụng get_terms () Tôi đã quản lý để đưa ra danh sách đầy đủ các thuật ngữ, nhưng các lục địa bị lẫn lộn với các quốc gia, trong một danh sách phẳng lớn.

Làm thế nào tôi có thể xuất ra một danh sách phân cấp như trên?


2
Trong trường hợp bất kỳ ai cũng cần một CHECKLIST phân cấp (không phải câu hỏi ở đây nhưng có liên quan đến những người xây dựng giao diện người dùng tùy chỉnh cho phân loại phân cấp), câu trả lời tốt nhất là sử dụng wp_terms_checklist () với phân loại tùy chỉnh của bạn.
jerclarke 23/2/2016

Câu trả lời:


19

Sử dụng wp_list_categories với 'taxonomy' => 'taxonomy'đối số, nó được xây dựng để tạo danh sách danh mục phân cấp nhưng cũng sẽ hỗ trợ sử dụng phân loại tùy chỉnh ..

Ví dụ về Codex:
Hiển thị các thuật ngữ trong phân loại tùy chỉnh

Nếu danh sách trở lại trông phẳng, có thể bạn chỉ cần một chút CSS để thêm phần đệm vào danh sách, vì vậy bạn có thể thấy cấu trúc phân cấp của chúng.


Điều này có thể được đảo ngược? Hiển thị trẻ em trước ..
Arg Geo

43

Tôi nhận ra, đây là một câu hỏi rất cũ, nhưng nếu bạn có nhu cầu xây dựng một cấu trúc thuật ngữ thực tế , đây có thể là một phương pháp hữu ích cho bạn:

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

Cách sử dụng như sau:

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

var_dump($categoryHierarchy);

3
Điều này thực sự tốt. Tôi sẽ thay đổi một điều: $into[$cat->term_id] = $cat;thành $into[] = $cat;ID của thuật ngữ vì khóa mảng gây khó chịu (bạn không thể lấy phần tử đầu tiên dễ dàng bằng phím 0) và vô dụng (bạn đã lưu trữ $catđối tượng và bạn có thể lấy id sử dụng term_idtài sản.
Nahuel

Nếu giống như tôi, bạn đang cố gắng áp dụng chức năng này cho cấp độ danh mục phụ, bạn sẽ cần chuyển ID của cấp độ mà bạn hiện đang làm việc này để hoạt động. Nhưng nó hoạt động độc đáo, cảm ơn @popsi.
Ben Everard

nó hoạt động, cảm ơn bạn
Luca Reghellin

10

Tôi không biết bất kỳ chức năng nào làm những gì bạn muốn nhưng bạn có thể xây dựng một cái gì đó như thế này:

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

Tôi chưa thử nghiệm điều này nhưng bạn có thể thấy những gì tôi đang làm. Những gì các mã trên sẽ làm là chỉ cung cấp cho bạn hai cấp độ

EDIT: ahh vâng, bạn có thể sử dụng wp_list_clists () để làm những gì bạn sau.


Trên thực tế, điều này khá hữu ích, vì tôi cần phải có các liên kết tùy chỉnh (với tham số GET) trên các liên kết thuật ngữ, điều này dường như không thể thực hiện được với cách làm wp_list_clists ().
mike23

1
Có phương pháp này sẽ cung cấp thêm quyền kiểm soát đầu ra của bạn. Nhưng bạn có thể thực hiện một số thao tác tìm và thay thế đầu ra wp_list_categories()để thêm vào các tham số GET của mình. Hoặc thậm chí tốt hơn là xây dựng bộ lọc cho hàm để thêm vào các bit bạn muốn. Đừng hỏi tôi làm thế nào vì tôi chưa thể hiểu ý mình :(
Brady

3
Tôi khuyên bạn nên sử dụng một trình đi bộ danh mục tùy chỉnh với wp_list_categoriesnếu bạn muốn kiểm soát đầu ra tốt hơn, nó sẽ làm cho mã của bạn có thể tái sử dụng nhiều hơn ..
t31os

6

Bạn có thể sử dụng wp_list_clists (), với đối số 'phân loại'.


3

Khi tôi đang tìm kiếm tương tự nhưng để có được điều khoản của một bài đăng, cuối cùng tôi đã biên soạn bài này, và nó hoạt động với tôi.

Những gì nó làm:
• nó nhận được tất cả các điều khoản của một tên phân loại cho một bài viết cụ thể.
• đối với phân loại chữ tượng hình với hai cấp độ (ví dụ: level1: 'country' và level2: 'city'), nó tạo ra một h4 với level1 theo sau là danh sách ul của level2 và cấp độ này cho tất cả các mục level1.
• nếu phân loại không phân cấp, nó sẽ chỉ tạo một danh sách ul của tất cả các mục. Đây là mã (tôi viết nó cho tôi vì vậy tôi đã cố gắng chung chung như tôi có thể nhưng ...):

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

Vì vậy, cuối cùng bạn gọi hàm này bằng (rõ ràng, bạn thay thế my_taxonomy bằng hàm của bạn): finishingLister('my_taxonomy');

Tôi không giả vờ nó hoàn hảo nhưng như tôi đã nói nó hiệu quả với tôi.


3

Đoạn mã sau sẽ tạo ra thả xuống với các thuật ngữ, nhưng cũng có thể tạo ra bất kỳ thành phần / cấu trúc nào khác bằng cách chỉnh sửa biến $ outputTemplate và chỉnh sửa các dòng str numplace:

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

Tôi đã có vấn đề này và không có câu trả lời nào ở đây làm việc cho tôi, vì lý do này hay lý do khác.

Đây là phiên bản cập nhật và làm việc của tôi.

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

Và cách sử dụng:

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

1

Tôi đã sử dụng mã @popsi đang hoạt động rất tốt và tôi đã làm cho nó hiệu quả hơn và dễ đọc hơn:

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

Sử dụng :

$sorted_terms = sort_terms_hierarchicaly($terms);

-1

Hãy chắc chắn rằng nó hierarchical=trueđược truyền choget_terms() cuộc gọi .

Lưu ý rằng đó hierarchical=truelà mặc định, vì vậy, thực sự, chỉ cần chắc chắn rằng nó đã không bị ghi đè false.


Xin chào Chip, theo mặc định, "phân cấp" là "đúng".
mike23

Bạn có thể cung cấp một liên kết đến một ví dụ trực tiếp về đầu ra?
Chip Bennett

Bình luận về một câu trả lời còn lại gần hai năm trước? Có thật không? Trên thực tế, đó một câu trả lời được đề xuất, ngay cả khi được nói như một câu hỏi. Tôi sẽ chỉnh sửa nó thành một tuyên bố, chứ không phải là một câu hỏi?
Chip Bennett

get_terms()sẽ trả về một danh sách đầy đủ các điều khoản (như OP đã nêu) nhưng không phải là danh sách phân cấp hiển thị mối quan hệ cha / con theo yêu cầu.
jdm2112 17/03/2016

-1

Ở đây tôi có danh sách chọn thả xuống bốn cấp với mục đầu tiên bị ẩn

<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
Hãy giải thích tại sao điều đó có thể giải quyết vấn đề.
fuxia

Tôi nghĩ logic là nó là một vấn đề liên quan. Tôi thấy bài đăng này đang cố gắng tìm ra cách để có được một danh sách kiểm tra phân cấp theo kiểu danh mục và tôi muốn thêm một câu trả lời ở đây mà bây giờ tôi đã tìm ra nó. Tôi sẽ không mặc dù bởi vì như bạn chỉ ra nó không trả lời OQ.
jerclarke 23/2/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.