Como obter todos os filhos e netos de um tipo de postagem personalizado hierárquico?

8

Preciso obter todas as sub-postagens de um ID pai (raiz) específico.

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

A função WP-Codex: get_post () possui o parâmetro post_parent, mas não o parâmetro child_of.

A vantagem da função get_pages () em combinação com o child_of paramenter é "... Observe que o parâmetro child_of também buscará" netos "do ID fornecido, não apenas descendentes diretos." *

Paul Geisler
fonte

Respostas:

11

Você precisará fazer um loop sobre essas postagens e, em seguida, fazer mais consultas para cada postagem, repetindo até encontrar nenhuma postagem em uma consulta.

por exemplo

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

Sim, a função acima chama a si mesma, é uma função recursiva. Ele continuará chamando a si próprio até chegar a um ponto em que a postagem que está sendo visualizada não tem filhos, depois retornará sem chamar a si mesma, e toda a pilha voltará a formar a matriz de filhos. Você faria bem em fazer mais pesquisas nessa área.

Observe que há um custo inerente ao que você deseja, independentemente de você usar funções recursivas ou não, que está atrelado a quantos níveis de postagens você possui. 5 níveis de postagens serão mais caros que 2 e não é uma escala linear. Você pode usar transitórios para armazenar em cache sua saída, dependendo de como fazer isso.

Outra maneira de reduzir o custo é apenas olhando para baixo da árvore dos postos um certo número de níveis, por exemplo, netos, mas não bisnetos. Isso pode ser feito passando um parâmetro de profundidade e diminuindo-o em cada chamada recursiva, certificando-se de retornar uma matriz vazia no início, se a profundidade for 0 ou menor. Muitos tutoriais sobre funções recursivas usam isso como um exemplo.

Tom J Nowell
fonte
O problema com esse código é que ele não fornece a ordem correta; Eu obtenho todo o nível superior primeiro, depois todo o segundo nível em uma matriz nivelada. Alguma pista sobre como consertar?
Dama_do_bling
Este código não se destinava a fazer isso, você tem um problema diferente, que exige uma solução ligeiramente diferente, e uma boa dose de contexto
Tom J Nowell
0

Basta usar get_page_children(). Funciona para todos os tipos de post (não apenas páginas) e é basicamente o que o @TomJNowell mostrou na outra pergunta, mas já implementado pelo núcleo.

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

A amostra acima é como no Codex. É por isso que você pode simplesmente usar o objeto de consulta global (ou qualquer outro objeto de consulta) para ser usado como base de pesquisa.

kaiser
fonte
Mas como você usa isso para um tipo de postagem diferente? Não fazê-lo funcionar.
Dama_do_bling
0

Use o próximo código de acesso para exibir todos os filhos e netos na exibição hierárquica. Uso: [my_children_list] ou [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' );
Adam Pery
fonte