Objective: Query and loop through a page’s third-level “grandchildren” in a way that allows pagination.
Here’s the code that I’m using (pagination excluded):
// Get the ID of the first generation
$gen1_ids = $post->ID;
// Query for second generation IDs
$gen2 = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE $wpdb->posts.post_parent IN ($gen1_ids) AND $wpdb->posts.post_type = 'page' AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.ID ASC" ); // Test ordering by title
// Implode the results for further use
$gen2_ids = implode( $gen2,', ' );
// Now, query for third generation IDs using second generation IDs
$gen3 = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE $wpdb->posts.post_parent IN ($gen2_ids) AND $wpdb->posts.post_type = 'page' AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.ID ASC" );
$args = array(
'post__in' => $gen3,
'post_type' => 'page',
'post_status' => 'publish',
'posts_per_page' => 5,
'paged' => get_query_var('paged')
);
$results = null;
$results = new WP_Query( $args );
if( $results->have_posts() ) {
while ( $results->have_posts() ) : $results->the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>" class="img"><img src="#"></a>
<div class="text">
<h3><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h3>
<p>...</p>
</div>
</li>
<?php endwhile;
} /* end if */ ?>
<?php wp_reset_query(); // Restore global post data stomped by the_post(). ?>
I’ve adapted the code from an answer to a support question two years back on the WordPress.org forums. The code is working.
Is there a way that this can be done better?
You’re on the right track. You can do this with just one MySQL query instead of two by joining on the
post_parent
. Drop this function into your functions.php file, then in your template you can replace yourWP_Query
call with$results = wpse_84810_get_grandchildren();
, change your if clause to beif( $results && $results->have_posts() )
, then carry on with the rest of your template code.