¿Cómo obtener todos los hijos y nietos de un tipo de publicación jerárquica personalizada?

8

Necesito obtener todas las sub-publicaciones de una identificación principal (raíz) específica.

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

WP-Codex: la función get_post () tiene el parámetro post_parent pero no tiene el parámetro child_of.

La ventaja de la función get_pages () en combinación con el parámetro child_of es "... Tenga en cuenta que el parámetro child_of también buscará" nietos "de la ID dada, no solo descendientes directos." *

Paul Geisler
fuente

Respuestas:

11

Tendrá que recorrer esas publicaciones y luego hacer más consultas para cada publicación, repitiendo hasta que no encuentre publicaciones en una consulta.

p.ej

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

Sí, la función anterior se llama a sí misma, es una función recursiva. Continuará llamándose a sí mismo hasta que llegue a un punto en el que la publicación que se está mirando no tiene hijos, luego regresará sin llamarse a sí mismo, y toda la pila volverá a burbujear construyendo la matriz de hijos. Sería bueno hacer más investigaciones en esta área.

Tenga en cuenta que hay un costo inherente a lo que desea, independientemente de si usa funciones recursivas o no, que está relacionado con la cantidad de niveles de publicaciones que tiene. 5 niveles de publicaciones serán más costosas que 2, y no es una escala lineal. Es posible que desee utilizar transitorios para almacenar en caché su salida dependiendo de cómo lo haga.

Otra forma de reducir el costo es solo mirando hacia abajo en el árbol de publicaciones un cierto número de niveles, por ejemplo, nietos pero no bisnietos. Esto se puede hacer pasando un parámetro de profundidad y decrementándolo en cada llamada recursiva, asegurándose de devolver una matriz vacía al inicio si la profundidad es 0 o menor. Muchos tutoriales sobre funciones recursivas usan esto como un ejemplo.

Tom J Nowell
fuente
El problema con este código es que no le da el orden correcto; Primero obtengo todo el nivel superior, luego todo el segundo nivel después en una matriz aplanada. ¿Alguna pista sobre cómo solucionarlo?
dama_do_bling
Este código no estaba destinado a hacer eso, tiene un problema diferente que requiere una solución ligeramente diferente y una fuerte dosis de contexto
Tom J Nowell
0

Simplemente use get_page_children(). Funciona para cada tipo de publicación (no solo páginas) y es básicamente lo que @TomJNowell mostró en la otra pregunta, pero ya lo implementó Core.

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

La muestra anterior es como en el Codex. Es por eso que simplemente puede tomar el objeto de consulta global (o cualquier otro objeto de consulta) para usarlo como base de búsqueda.

emperador
fuente
Pero, ¿cómo se usa esto para un tipo de publicación diferente? No conseguir que funcione.
dama_do_bling
0

Use el siguiente shortcode para mostrar todos los hijos y nietos en vista jerárquica. Uso: [my_children_list] o [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
fuente