-
Notifications
You must be signed in to change notification settings - Fork 261
Looping The Loop
Continuing from the Basic usage tutorial, let's say that you want to display the connected pages, not just for a single post, but for all posts in an archive.
You could just copy the code you used for a single post:
<?php while ( have_posts() ) : the_post(); ?>
<!-- Some standard stuff here, like the_title(); etc. -->
<?php
// Find connected pages
$connected = new WP_Query( array(
'post_type' => 'page',
'connected_from' => $post->ID
) );
// Display connected pages
echo '<p>Related pages:</p>';
echo '<ul>';
while ( $connected->have_posts() ) : $connected->the_post();
echo '<li>';
the_title();
echo '</li>';
endwhile;
echo '</ul>';
// Prevent weirdness
wp_reset_postdata();
?>
<?php endwhile; ?>
The only change I made was replacing get_queried_object_id()
with $post->ID
.
This will work as expected, but you're making at least one additional SQL query for each post. If you have 10 or 20 posts per page, that's a lot of extra queries!
On each request, WordPress automatically runs a query which finds the appropriate posts to display. These posts are stored in the $wp_query
global variable. That's where The Loop pulls it's data from.
Since we already have all the posts tucked away in $wp_query, couldn't we find all the connected pages for all the posts in one go?
Here's how that would look like:
<?php
// Find connected pages (for all posts)
p2p_each_connected( $wp_query, array(
'post_type' => 'page',
) );
?>
<?php while ( have_posts() ) : the_post(); ?>
<!-- Some standard stuff here, like the_title(); etc. -->
<?php
// Display connected pages
echo '<p>Related pages:</p>';
echo '<ul>';
foreach ( $post->connected as $post ) {
setup_postdata( $post );
echo '<li>';
the_title();
echo '</li>';
}
echo '</ul>';
// Prevent weirdness
wp_reset_postdata();
?>
<?php endwhile; ?>
p2p_each_connected()
runs a single query, which is much more efficient.
The only other difference is that the connected pages are now stored as an array in $post->connected
.
If you're creating your own custom loop or are using get_posts()
, you can specify an 'each_connected' query var, like so:
<?php
$my_query = new WP_Query( array(
'ignore_sticky_posts' => true,
'post_type' => 'post',
'each_connected' => array(
'post_type' => 'page',
)
) );
?>
Then, you would display them, almost exactly as before:
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
<!-- Some standard stuff here, like the_title(); etc. -->
<?php
// Display connected pages
echo '<p>Related pages:</p>';
echo '<ul>';
foreach ( $post->connected as $post ) {
setup_postdata( $post );
echo '<li>';
the_title();
echo '</li>';
}
echo '</ul>';
// Prevent weirdness
wp_reset_postdata();
?>
<?php endwhile; ?>