Получить прямых потомков пользовательской таксономии


Я много гуглил и старался изо всех сил, но я просто не могу заставить работать детей первого уровня пользовательской таксономии в приведенном ниже коде! Он отображает только родительский уровень. Чего я пытаюсь добиться, так это следующего:

Level 1  <--- at the moment, it only displays this level
  Level 2  <-- I want to display this level too
    Level 3  <-- but NOT this level

Это мой код до сих пор:

function my_dropdown_categories( $taxonomy, $current_selected = '', $include = null ) {
// Get all terms of the chosen taxonomy
$terms = get_terms($taxonomy, array('orderby' => 'name'));

// our content variable
$list_of_terms = '<select id="location" class="selectboxSingle" name="location">';

if ( ! is_wp_error( $terms ) ) foreach($terms as $term){

// If include array set, exclude unless in array.
if ( is_array( $include ) && ! in_array( $term->slug, $include ) ) continue;

$select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==

if ($term->parent == 0 ) {

    // get children of current parent.
    // $tchildren = get_term_children($term->term_id, $taxonomy); <- gets ALL children

    $uchildren =get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));

    $children = array();
    foreach ($uchildren as $child) {
        $cterm = get_term_by( 'id', $child, $taxonomy );
        // If include array set, exclude unless in array.
        if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
        $children[$cterm->name] = $cterm;
    }
    ksort($children);

    // PARENT TERM      
    if ($term->count > 0) {
      $list_of_terms .= '<option class ="group-result" value="'.$term->slug.'" '.$select.'>' . $term->name .' </option>';
    } else {
      $list_of_terms .= '<option value="'.$term->slug.'" '.$select.'>'. $term->name .' </option>';
    };

    // now the CHILDREN.
    foreach($children as $child) {
       $select = ($current_selected == $child->slug) ? "selected" : ""; // Note: child, not cterm
       $list_of_terms .= '<option class="result-sub" value="'.$child->slug.'" '.$select.'>'. $child->name.' </option>';
    } //end foreach
  }
}

$list_of_terms .= '</select>';

return $list_of_terms;
}

Если кто-нибудь сможет помочь мне с этим зверем, ты будешь моим чертовым героем!

РЕДАКТИРОВАТЬ (дополнительная информация основана на ответе Питера):

Это то, что выводится (все родители):

Родитель 1

--Родитель 1

--Родитель 2

--Родитель 3

--Родитель 4

Родитель 2

--Родитель 2

--Родитель 1

--Родитель 3

И т.д.

Author: Guit4eva, 2015-03-01

2 answers

У вас здесь две проблемы, одна из которых связана с производительностью, другая - большая проблема, которая должна возвращать кучу ошибок, если вы включите отладку

Проблема с производительностью здесь - ваш первый случай, когда вы получаете условия. Похоже, что ваша цель здесь - получить только условия высшего уровня, но вы получаете все. Я бы просто добавил 'parent' => 0 к аргументам, чтобы получить только термины верхнего уровня. Затем вы можете удалить условие, в котором вы проверяете if ( $term->parent == 0 ), потому что все термины будут терминами верхнего уровня, которые будут у всех есть 0 в качестве родителя термина, поэтому это условие всегда будет возвращать значение true

Ваша большая проблема связана с этим кодом, и я не понимаю вашей логики здесь

    $uchildren =get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));

    $children = array();
    foreach ($uchildren as $child) {
        $cterm = get_term_by( 'id', $child, $taxonomy );
        // If include array set, exclude unless in array.
        if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
        $children[$cterm->name] = $cterm;
    }
    ksort($children);

Вы правы, получив своих прямых детей, поэтому ваше заявление о $uchildren в порядке. С этого момента все идет наперекосяк

  • Почему вы используете get_term_by() здесь. $child уже содержит свойства термина, как вы использовали get_terms() для извлечения терминов.

  • Ты не такой просто неправильно используйте здесь get_term_by(), но ваши аргументы недействительны, и вы также передаете ему полный объект. Вы должны проконсультироваться с кодексом для правильного использования этой функции. В общем, этот раздел следует удалить из вашего кода

Этот раздел должен выглядеть примерно так

    $uchildren =get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));

    $children = array();
    foreach ($uchildren as $child) {
        if ( is_array( $include ) && ! in_array( $child->slug, $include ) ) continue;
        $children[$child->name] = $child;
    }
    ksort($children);

РЕДАКТИРОВАТЬ

Вот полный рабочий код с исправленной парой ошибок. Пожалуйста, смотрите мои комментарии в коде для обновлений

function my_dropdown_categories( $taxonomy, $current_selected = '', $include = null ) 
{
    /*
     * Declare your variable first. Without this, your code has a bug if no terms are found
     */
    $list_of_terms = '';

    /**
    * Get all parent terms. Note we use 'parent' => 0 to only get top level terms
    *
    * @see get_terms
    * @link http://codex.wordpress.org/Function_Reference/get_terms
    */
    $terms = get_terms( $taxonomy, array( 'orderby' => 'name', 'parent' => 0 ) );

    /*
    * Use curlies here to enclose your statement. Also, check whether or not you have terms
    */
    if ( $terms && ! is_wp_error( $terms ) ) {

        /*
        * Moved this section inside your if statement. We don't want to display anything on empty terms
        */
        $list_of_terms .= '<select id="location" class="selectboxSingle" name="location">';

        foreach ( $terms as $term ) {

            // If include array set, exclude unless in array.
            if ( is_array( $include ) && ! in_array( $term->slug, $include ) ) continue;

            $select = ($current_selected == $term->slug) ? "selected" : ""; // Note: ==

            /*
             * Use the parent term term id as parent to get direct children of the term
             * Use child_of if you need to get all descendants of a term
             */
            $uchildren = get_terms( $taxonomy, array('hide_empty' => 0, 'parent' => $term->term_id ));

            $children = array();
            foreach ($uchildren as $child) {
                // If include array set, exclude unless in array.
                if ( is_array( $include ) && ! in_array( $child->slug, $include ) ) continue;
                $children[$child->name] = $child;
            }
            ksort($children);

            // PARENT TERM      
            if ($term->count > 0) {
                $list_of_terms .= '<option class ="group-result" value="'.$term->slug.'" '.$select.'>' . $term->name .' </option>';
            } else {
                $list_of_terms .= '<option value="'.$term->slug.'" '.$select.'>'. $term->name .' </option>';
            };

            // now the CHILDREN.
            foreach($children as $child) {
                $select = ($current_selected == $child->slug) ? "selected" : ""; // Note: child, not cterm
                $list_of_terms .= '<option class="result-sub" value="'.$child->slug.'" '.$select.'>'. $child->name.' </option>';
            } //end foreach

        }

        /*
        * Moved this section inside your if statement. We don't want to display anything on empty terms
        */
        $list_of_terms .= '</select>';

    }
    return $list_of_terms;
}
 5
Author: Pieter Goosen, 2015-03-02 14:27:00

Проверьте этот код

$uchildren =get_terms( 'category', array('hide_empty' => false, 'parent' => $term->term_id ));

$children = array();
foreach ($uchildren as $child) {
    $cterm = get_term_by( 'id', $child, $taxonomy );
    // If include array set, exclude unless in array.
    if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;
    $children[$cterm->name] = $cterm;
}

Эта строка

$cterm = get_term_by( 'id', $child, $taxonomy ); 

Предполагает, что $child будет идентификатором (и целым числом), тогда как:

foreach ($uchildren as $child) {

Дает нам объект

Это также является причиной того, что это работает не так, как вы хотите:

if ( is_array( $include ) && ! in_array( $cterm->slug, $include ) ) continue;

Отсюда мусор, который я разместил, но здравый смысл возобладал, пока...

Давайте сделаем самую забавную часть:

var_dump($term):

Обратите внимание на тип каждого свойства:

object(stdClass)(9) {
    ...
    ["parent"]=>
    string(1) "0"
    ...
}

Смотрите parent. Это строка. Я знаю, логически это должно быть целое число, но это строка. Это отстой, верно!

Итак, ваше условие if ($term->parent == 0 ) { не выполняется. Попробуйте вместо этого:

if ( empty( $term->parent ) ) {

Здесь

 0
Author: Saurabh Shukla, 2015-03-02 10:58:30