Skip to content

Looping The Loop

scribu edited this page Sep 18, 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 = $my_connection_type->get_connected( $post->ID );

		// Display connected pages
		echo '<p>Related pages:</p>';
		echo '<ul>';
		foreach ( $connected->posts as $post ) {
			setup_postdata( $post );

			echo '<li>';
			the_title();
			echo '</li>';
		}
		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!

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)
$my_connection_type->each_connected( $wp_query );
?>

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

	<?php the_title(); ?>

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

$my_connection_type->each_connected() runs a single query, which is much more efficient.

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

Clone this wiki locally