階層型カスタム投稿タイプのすべての子と孫を取得するにはどうすればよいですか?


8

特定の(ルート)親IDのすべてのサブ投稿を取得する必要があります。

get_posts( array( 'numberposts' => -1, 'post_status' => 'publish', 'post_type' => 'microsite', 'post_parent' => $root_parent_id, 'suppress_filters' => false ) );

WP-Codex:get_post()関数にはpost_parentがありますが、child_ofパラメータはありません。

child_ofパラメータと組み合わせた関数get_pages()の利点は、「... child_ofパラメータは、直接の子孫だけでなく、指定されたIDの「孫」もフェッチすることに注意してください。」*

回答:


11

これらの投稿をループして、各投稿に対してさらにクエリを実行し、クエリで投稿が見つからなくなるまで繰り返します。

例えば

function get_posts_children($parent_id){
    $children = array();
    // grab the posts children
    $posts = get_posts( array( 'numberposts' => -1, 'post_status' => 'publish', 'post_type' => 'microsite', 'post_parent' => $parent_id, 'suppress_filters' => false ));
    // now grab the grand children
    foreach( $posts as $child ){
        // recursion!! hurrah
        $gchildren = get_posts_children($child->ID);
        // merge the grand children into the children array
        if( !empty($gchildren) ) {
            $children = array_merge($children, $gchildren);
        }
    }
    // merge in the direct descendants we found earlier
    $children = array_merge($children,$posts);
    return $children;
}

// example of using above, lets call it and print out the results
$descendants = get_posts_children($post->ID);
echo '<pre>';
print_r($descendants);
echo '</pre>';

はい、上記の関数はそれ自体を呼び出します、それは再帰的な関数です。対象の投稿に子がないポイントに達するまで自分自身を呼び出し続け、その後自分自身を呼び出さずに戻り、スタック全体がバブルアップして子の配列を構築します。この分野でさらに調査を行うとよいでしょう。

再帰関数を使用するかどうかに関わらず、必要な投稿のレベル数に関連する固有のコストが発生することに注意してください。5レベルの投稿は2よりもコストがかかり、線形スケーリングではありません。これをどのように行うかによっては、トランジェントを使用して出力をキャッシュしたい場合があります。

コストを削減するもう1つの方法は、投稿のツリーを特定の数のレベルだけで調べることです。これは、深さパラメータを渡して、再帰呼び出しごとにデクリメントし、深さが0以下の場合は最初に必ず空の配列を返すことで実行できます。再帰関数に関する多くのチュートリアルでは、これを例として使用しています。


このコードの問題は、正しい順序が得られないことです。最初にすべてのトップレベルを取得し、次に2つのレベルすべてを1つの平坦化された配列で取得します。修正方法の手がかりはありますか?
dama_do_bling 2015

このコードはそれを行うことを意図しておらず、わずかに異なるソリューションと大量のコンテキストを必要とする別の問題があります
トムJノウェル

0

単に使用しますget_page_children()。これはすべての投稿タイプ(ページだけでなく)で機能し、基本的には@TomJNowellが他の質問で示したものですが、すでにコアによって実装されています。

$children = get_page_children( $post->ID, $GLOBALS['wp_query'] );

上記のサンプルは、Codexに似ています。そのため、グローバルクエリオブジェクト(またはその他のクエリオブジェクト)を検索ベースとして使用できます。


しかし、これを別の投稿タイプにどのように使用しますか?機能しない。
dama_do_bling 2015

0

次のショートコードを使用して、すべての子と孫を階層ビューで表示します。使用法:[my_children_list]または[my_children_list page_id = 123]

function my_children_list_func($atts, $content = null) {
    global $post;

    $a = shortcode_atts( array(
            'page_id' => ''
    ), $atts );

    $args = array( 
            'numberposts' => -1, 
            'post_status' => 'publish', 
            'post_type' => 'microsite', 
            'post_parent' => (isset($a['page_id']) && $a['page_id']) ? $a['page_id'] : $post->ID,
            'suppress_filters' => false 
    );

    $parent = new WP_Query( $args );

    ob_start();

    if ( $parent->have_posts() ) :?>
            <ul>
            <?php while ( $parent->have_posts() ) : $parent->the_post(); ?>
                    <li><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a>
                    <?php echo do_shortcode('[tadam_children_list page_id='.get_the_ID().']') ?>
                    </li>
            <?php endwhile;?>
            </ul>
    <?php endif; wp_reset_postdata();

    return ob_get_clean();
}
add_shortcode( 'my_children_list', 'my_children_list_func' );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.