Skip to content

Looping The Loop

scribu edited this page Oct 21, 2011 · 23 revisions

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.

The slow way

You could just copy the code you used for a single post:

<?php while ( have_posts() ) : the_post(); ?>

	<?php the_title(); ?>

	<?php
		// Find connected pages
		$connected = p2p_type( 'posts_pages' )->get_connected( $post->ID );

		// Display connected pages
		echo '<p>Related pages:</p>';
		p2p_list_posts( $connected );
	?>

<?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!

Using each_connected()

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_type( 'posts_pages' )->each_connected( $wp_query );
?>

<?php while ( have_posts() ) : the_post(); ?>

	<?php the_title(); ?>

	<?php
		// Display connected pages
		echo '<p>Related pages:</p>';
		p2p_list_posts( $post->connected );		
	?>

<?php endwhile; ?>

p2p_type( 'posts_pages' )->each_connected() runs a single query, which is much more efficient.

The only other difference is that instead of looping over $connected, we loop over $post->connected.