Comment obtenir tous les enfants et petits-enfants d'un type de message personnalisé hiérarchique?

8

J'ai besoin d'obtenir tous les sous-messages d'un identifiant parent (racine) spécifique.

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

WP-Codex: la fonction get_post () a le paramètre post_parent mais pas de paramètre child_of.

L'avantage de la fonction get_pages () en combinaison avec le paramètre child_of est "... Notez que le paramètre child_of récupérera également les" petits-enfants "de l'ID donné, pas seulement les descendants directs." *

Paul Geisler
la source

Réponses:

11

Vous devrez parcourir ces messages, puis effectuer plus de requêtes pour chaque message, en répétant jusqu'à ce que vous ne trouviez aucun message dans une requête.

par exemple

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

Oui, la fonction ci-dessus s'appelle elle-même, c'est une fonction récursive. Il continuera à s'appeler jusqu'à ce qu'il atteigne un point où le message regardé n'a pas d'enfants, puis il reviendra sans s'appeler, et toute la pile remontera en créant le tableau des enfants. Vous feriez bien de poursuivre vos recherches dans ce domaine.

Notez qu'il y a un coût inhérent à ce que vous voulez, que vous utilisiez ou non des fonctions récursives, qui est lié au nombre de niveaux de publications que vous avez. 5 niveaux de postes seront plus coûteux que 2, et ce n'est pas une mise à l'échelle linéaire. Vous souhaiterez peut-être utiliser des transitoires pour mettre en cache votre sortie selon la façon dont vous procédez.

Une autre façon de réduire le coût est de ne regarder dans l'arbre des poteaux qu'un certain nombre de niveaux, par exemple des petits-enfants mais pas d'arrière-petits-enfants. Cela peut être fait en passant un paramètre de profondeur et en le décrémentant à chaque appel récursif, en veillant à renvoyer un tableau vide au début si la profondeur est 0 ou inférieure. De nombreux didacticiels sur les fonctions récursives utilisent cela comme exemple.

Tom J Nowell
la source
Le problème avec ce code est qu'il ne vous donne pas de commande correcte; J'obtiens tout le niveau supérieur d'abord, puis tout le deuxième niveau après dans un tableau aplati. Un indice sur la façon de réparer?
dama_do_bling
Ce code n'a pas été conçu pour cela, vous avez un problème différent qui nécessite une solution légèrement différente et une bonne dose de contexte
Tom J Nowell
0

Utilisez simplement get_page_children(). Cela fonctionne pour chaque type de publication (pas seulement les pages) et est fondamentalement ce que @TomJNowell a montré dans l'autre question, mais déjà implémenté par core.

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

L'échantillon ci-dessus est comme dans le Codex. C'est pourquoi vous pouvez simplement prendre l'objet de requête global (ou tout autre objet de requête) pour l'utiliser comme base de recherche.

kaiser
la source
Mais comment l'utilisez-vous pour un autre type de message? Ne pas le faire fonctionner.
dama_do_bling
0

Utilisez le shortcode suivant pour afficher tous les enfants et petits-enfants dans une vue hiérarchique. Utilisation: [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
la source