web-dev-qa-db-ja.com

カスタム分類法の直接の子を取得します

私は広範囲にグーグルして最善を尽くしましたが、以下のコードでカスタム分類法の最初のレベルの子を動作させることはできません。親レベルのみが表示されます。私が達成しようとしているのは以下のとおりです。

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

誰かがこの獣で私を助けることができるなら、あなたは私のおかしい人ヒーローになるでしょう!

_ edit _ (Pieterの回答に基づく詳細情報):

これは出力されているものです(すべての親):

親1

- 親1

- 親2

- 親3

- 親4

親2

- 親2

- 親1

- 親3

1
Guit4eva

ここには2つの問題があります。1つはパフォーマンスの問題、もう1つはdebugを有効にした場合に大量のエラーが返されるという大きな問題です。

ここでのパフォーマンスの問題は、あなたが用語を入手している最初の例です。ここでの目標は、トップレベルの用語のみを取得することであり、それでもすべてを取得することです。トップレベルの用語だけを取得するには、引数に'parent' => 0を追加するだけです。すべての用語が最上位レベルの用語になり、すべての用語が親として0を持つため、if ( $term->parent == 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() を使っているのですか。 get_terms()を使用して用語を取得したので、$childはすでに用語のプロパティを保持しています。

  • ここで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;
}
3
Pieter Goosen

このコードをチェック

$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はid(および整数)になると仮定します。

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

here

0
Saurabh Shukla