web-dev-qa-db-ja.com

カスタム分類法、get_the_terms、親>子の順にリスト表示

print_r(get_the_terms( $post->ID, 'taxonomic_rank' ));を使って表示できる階層的なカスタム分類法があります。

Array
(
    [46] => stdClass Object
        (
            [term_id] => 46
            [name] => Aplocheilidae
            [slug] => aplocheilidae
            [term_group] => 0
            [term_taxonomy_id] => 53
            [taxonomy] => taxonomic_ranks
            [description] => 
            [parent] => 39
            [count] => 1
            [object_id] => 443
        )

    [47] => stdClass Object
        (
            [term_id] => 47
            [name] => Aplocheilus
            [slug] => aplocheilus
            [term_group] => 0
            [term_taxonomy_id] => 54
            [taxonomy] => taxonomic_ranks
            [description] => 
            [parent] => 46
            [count] => 1
            [object_id] => 443
        )

    [39] => stdClass Object
        (
            [term_id] => 39
            [name] => Cyprinodontiformes
            [slug] => cyprinodontiformes
            [term_group] => 0
            [term_taxonomy_id] => 52
            [taxonomy] => taxonomic_ranks
            [description] => 
            [parent] => 0
            [count] => 1
            [object_id] => 443
        )

)

この分類法は常に次の形式を取ります。 注文 (親)> 家族 (注文の子)> サブファミリー (家族の子)

次の行を印刷できるように、これらの分類法を正しい順序で表示するための迅速で簡単な方法はありますか? Order: <order>, Family: <family>, Sub-family: <sub-family>

前もって感謝します

6
dunc

これを行うにはおそらくより良い方法がいくつかありますが、3つの単純なforeachループをいつでも実行できます。

うまく機能し、良い出発点として役立つはずの関数例を書きました。

function print_taxonomic_ranks( $terms = '' ){

    // check input
    if ( empty( $terms ) || is_wp_error( $terms ) || ! is_array( $terms ) )
        return;

    // set id variables to 0 for easy check 
    $order_id = $family_id = $subfamily_id = 0;

    // get order
    foreach ( $terms as $term ) {
        if ( $order_id || $term->parent )
            continue;
        $order_id  = $term->term_id;
        $order     = $term->name;
    }

    // get family
    foreach ( $terms as $term ) { 
        if ( $family_id || $order_id != $term->parent )
            continue;
        $family_id = $term->term_id;
        $family    = $term->name;
    }

    // get subfamily
    foreach ( $terms as $term ) { 
        if ( $subfamily_id || $family_id != $term->parent ) 
            continue;
        $subfamily_id = $term->term_id;
        $subfamily    = $term->name;
    }

    // output
    echo "Order: $order, Family: $family, Sub-family: $subfamily";

}

それをあなたのfunctions.phpファイルに入れて、これをテンプレートの中で次のように使用しましょう。

print_taxonomy_ranks( get_the_terms( $post->ID, 'taxonomic_rank' ) );

注:同じ配列を3回ループさせるのはちょっとばかげて聞こえますが、その一方で、読みやすく、拡張しやすく、保守しやすい、迅速で簡単な解決策です。

6
Michal Mau

Mauglyのアプローチはもう少し読みやすいように見えますが、配列に対してループを3回実行することは私には正しくないようです。だからここにいくつかのために読みにくいかもしれませんが3回ループを実行せずに動作しますちょうど別のアプローチです。

function print_taxonomy_ranks( $terms ) {
    // if terms is not array or its empty don't proceed
    if ( ! is_array( $terms ) || empty( $terms ) ) {
        return false;
    }

    foreach ( $terms as $term ) {
        // if the term have a parent, set the child term as attribute in parent term
        if ( $term->parent != 0 )  {
            $terms[$term->parent]->child = $term;   
        } else {
            // record the parent term
            $parent = $term;
        }
    }

    echo "Order: $parent->name, Family: {$parent->child->name}, Sub-Family: {$parent->child->child->name}";
}
4

少し古い話題ですが、それでも関連性がありますそれはまだ完全な痛みであると思います。

参照として2つの配列を受け取るこの再帰関数を使用しています。 [term_id] => term_object->children->child_terms_array->children->child_terms_arrayの構造を持つ配列を作成します。

<?php
function sort_terms_hierarchically( array &$terms, array &$into, $parent_id = 0 ) {
    foreach ( $terms as $i => $term ) {
        if ( $term->parent == $parent_id ) {
            $into[$term->term_id] = $term;
            unset( $terms[ $i ] );
        }
    }

    foreach ( $into as $top_term ) {
        $top_term->children = array();
        $this->sort_terms_hierarchically( $terms, $top_term->children, $top_term->term_id );
    }

}

$terms = get_the_terms( 'taxslug', $post );
$sorted_terms = array();
sort_terms_hierarchically( $terms, $sorted_terms );

// Will log the nested arrays of term objects.
error_log( print_r( $sorted_terms, true ) );

これが私がこれまでに見つけた唯一の解決策であり、オブジェクトという用語を維持し、あらゆる量のネストで機能します。

3

投稿に複数のカテゴリグループと、親カテゴリ内の複数の子でタグ付けできる状況があったので、階層にそれを反映させたいと思いました。私はまた、ほんの数行のコードが欲しかったのです。

$terms = get_the_terms($id, 'department_categories');
foreach($terms as $key => $term){
    if($term->parent != 0){
        $terms[$term->parent]->children[] = $term;
        unset($terms[$key]);
    }
}

基本的に、カテゴリの親を見つけた後、それを子として親のobjに移動してから、配列内の元の位置から削除します。私はこれを複数の兄弟、子供たち、そして異なるレベルのカテゴリーを使ってテストしました。

「プラグイン」ではなく論理的な手引きを求めているだけの場合に、他の誰かがこれを便利に使えることを願っています!

3

ありがとうMaugly、

これは私の修正版のコードで、パーマリンクという用語が含まれています。

function print_show_location( $terms = '' ){

// check input
if ( empty( $terms ) || is_wp_error( $terms ) || ! is_array( $terms ) )
    return;

// set id variables to 0 for easy check 
$country_id = $state_id = $city_id = 0;

// get country
foreach ( $terms as $term ) {
    if ( $country_id || $term->parent )
        continue;
    $country_id  = $term->term_id;
    $country_slug = $term->slug;
    $country = '<a href="'.get_term_link($country_slug, 'location').'">'.$term->name.'</a>';
}

// get state
foreach ( $terms as $term ) { 
    if ( $state_id || $country_id != $term->parent )
        continue;
    $state_id = $term->term_id;
    $state_slug = $term->slug;
    $state = '<a href="'.get_term_link($state_slug, 'location').'">'.$term->name.'</a>';
}

// get city
foreach ( $terms as $term ) { 
    if ( $city_id || $state_id != $term->parent ) 
        continue;
    $city_id = $term->term_id;
    $city_slug = $term->slug;
    $city = '<a href="'.get_term_link($city_slug, 'location').'">'.$term->name.'</a>';
}

// output
echo "$city, $state - $country";

}
1
Adam Forst