계층 적 용어 목록을 표시하는 방법?


34

'지리적 위치'라는 계층 구조 분류법이 있습니다. 여기에는 첫 번째 수준의 대륙이 포함 된 다음 각 국가의 국가가 포함됩니다. 예 :

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

기타

get_terms ()를 사용하여 전체 용어 목록을 출력했지만 대륙은 하나의 큰 플랫 목록으로 국가와 섞여 있습니다.

위와 같은 계층 목록을 어떻게 출력 할 수 있습니까?


2
누구든지 계층 적 CHECKLIST (여기서는 문제가 아니지만 계층 적 분류법을위한 사용자 정의 UI를 작성하는 사람들과 관련이있는)가 필요한 경우 가장 좋은 대답은 사용자 정의 분류법과 함께 wp_terms_checklist ()를 사용하는 것입니다.
jerclarke

답변:


19

인수 wp_list_categories와 함께 사용하면 'taxonomy' => 'taxonomy'계층 적 카테고리 목록을 작성하기 위해 작성되었지만 사용자 정의 분류법 사용도 지원합니다.

코덱 예 :
사용자 지정 분류 체계로 용어 표시

목록이 평평하게 보이면 목록에 패딩을 추가하기 위해 CSS가 약간 필요하기 때문에 계층 구조를 볼 수 있습니다.


이것을 되돌릴 수 있습니까? 어린이를 먼저 표시하십시오.
Arg Geo

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개체를 당신은 ID를 얻을 수 있습니다 사용하여 term_id속성을.
나우

나처럼이 기능을 하위 수준의 범주에 적용하려는 경우 현재 작동중인 수준의 ID를 전달해야합니다. 그러나 @popsi 덕분에 잘 작동합니다.
벤 에버 라드

감사합니다
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 매개 변수 포함)가 필요하므로 wp_list_categories () 방법으로는 불가능한 것처럼 보입니다.
mike23

1
예,이 방법을 사용하면 출력을보다 효과적으로 제어 할 수 있습니다. 그러나 wp_list_categories()GET 매개 변수를 추가하기 위해 출력을 찾아서 대체 할 수 있습니다. 또는 함수가 원하는 비트를 추가 할 수 있도록 필터를 구성하는 것이 좋습니다. 아직 내 머리를 get 지 못 했으므로 어떻게하는지 묻지 마십시오. (
Brady

3
출력을 더 잘 제어하려면 사용자 지정 범주 워커 를 사용하는 것이 좋습니다. wp_list_categories코드를 훨씬 더 재사용 할 수 있습니다.
t31os


3

내가 똑같은 것을 찾고 있었지만 한 게시물의 용어를 얻으려고 마침내 마침내 이것을 컴파일했고 그것은 나에게 효과적입니다.

역할 :
• 특정 게시물에 대한 분류 이름의 모든 용어를 가져옵니다.
• 두 가지 수준 (예 : level1 : 'country'및 level2 : 'cities')을 가진 계층 적 분류 체계의 경우 level1 다음에 ul 목록 level2와 모든 level1 항목에 대해 h4를 만듭니다.
• 분류 체계가 계층 구조가 아닌 경우 모든 항목의 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 코드를 사용했고 더 효율적이고 읽기 쉽게 만들었습니다.

/**
 * 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=true그래서 정말, 단지 확인이 될 오버라이드 (override)되지 않았 음을 수, 기본값입니다 false.


Hi Chip, 예 '계층 적'은 기본적으로 '참'입니다.
mike23

실제 출력 예에 대한 링크를 제공 할 수 있습니까?
칩 베넷

거의 2 년 전에 남은 답변에 대해 언급하고 있습니까? 정말? 사실, 그것은 이다 질문으로 표현 된 경우에도 제안 된 답변. 질문이 아니라 진술로 편집해야합니까?
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.