Horizontally Sequenced Display Order for WordPress Posts in Two Columns
Most WordPress-powered blogs display posts in sequential order within a single column. Like this, for example:
But what if you wanted to display your posts in two columns, sequentially ordered from left to right? For example:
This is easily accomplished using two default loops and the rewind_posts()
function. The first loop will display the posts in the first column, while the second loop will display the posts in the second column. To do this, we use PHP’s modulus operator to filter out every other post from the first loop, which will display posts as follows:
- the first most recent post
- the third most recent post
- the fifth most recent post
..and so on. Meanwhile, the second loop will feature all of the posts that were filtered out of the first loop:
- the second most recent post
- the fourth most recent post
- the sixth most recent post
and so on, depending on the specified number of displayed posts. As you can see, this configuration divides the posts into “odd” and “even” groups. Note that there is nothing inherently “odd” or “even” about the posts in either group; we are arbitrarily assigning “oddness” and “evenness” based on location of each post within the default sequence. Thus, posts with odd-numbered ID
s may appear in the “even” loop and vice versa. having said that, let’s examine the code that will make this happen:
<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) == 0) : $wp_query->next_post(); else : the_post(); ?>
<div id="left-column">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>
</div>
<?php endif; endwhile; else: ?>
<div>Alternate content</div>
<?php endif; ?>
<?php $i = 0; rewind_posts(); ?>
<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>
<div id="right-column">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>
</div>
<?php endif; endwhile; else: ?>
<div>Alternate content</div>
<?php endif; ?>
With that code in place, oddly numbered posts will appear within a division identified with an attribute of id="left-column"
. Likewise, even-numbered posts will appear within a division identified with an attribute of id="right-column"
. Thus, we may apply the following CSS to position the divisions as two adjacent columns:
div#left-column {
width: 333px;
float: left;
clear: none;
}
div#right-column {
width: 333px;
float: right;
clear: none;
}
Of course, when it comes to configuring the WordPress loop and styling your page with CSS, anything is possible. Feel free to experiment and adapt this technique to suit your own diabolical purposes ;) For now, let’s continue with an explanation of the functionality behind this dual-loop technique.
Technical Breakdown
Perhaps the most straightforward way to explain the dual-loop code is to break it down line-by-line via comments placed within the code itself:
// initiate the default wordpress loop as usual
<?php if (have_posts()) : while(have_posts()) :
// set a count variable to increase with each loop
$i++;
// test the variable modulus against a zero value
// odd values return true, even values return false
// see proceding discussion for more information
if(($i % 2) == 0) :
// skip to next post if variable is an even number
$wp_query->next_post();
// display the post if variable is an odd number
else : the_post(); ?>
// open a division for the left column
<div id="left-column">
// display the title of the post
<h1><?php the_permalink(); ?></h1>
// display the post content
<?php the_content(); ?>
// close the division
</div>
// close the first if statement
<?php endif;
// close the loop
endwhile;
// if there are no posts that meet the criteria
else: ?>
// display some alternate content
<div>Alternate content</div>
// close the second if statement
<?php endif; ?>
// reset the count variable to zero
<?php $i = 0;
// reset the loop
rewind_posts(); ?>
// the second loop is essentially the same as the first
// the only difference is that we are testing the count variable against a non-zero value to display only even numbers
<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>
// and of course a unique div id for the right column
<div id="right-column">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>
</div>
<?php endif; endwhile; else: ?>
<div>Alternate content</div>
<?php endif; ?>
As for the crazy PHP modulus operator ( %
), suffice it to say that its purpose is to test the oddness or evenness of the $i
variable. The modulus operator returns the numerical remainder resulting from the division of the $i
variable by the specified number (“2
” in this case). In the first loop, because all even post numbers are evenly divisible by two, the modulus is equal to zero and thus the evenly numbered posts are skipped until the next loop. In the second loop, the odd post numbers are not evenly divisible by two, resulting in a non-zero numerical remainder. Thus, in the second loop, we test that the modulus is not equal to zero, thereby skipping the oddly numbered posts. Perhaps this numerical pattern will help clarify the concept:
- Post #1: $i = 1 [remainder of 1/2 = 1]
- Post #2: $i = 2 [remainder of 2/2 = 0]
- Post #3: $i = 3 [remainder of 3/2 = 1]
- Post #4: $i = 4 [remainder of 4/2 = 0]
- Post #5: $i = 5 [remainder of 5/2 = 1]
- Post #6: $i = 6 [remainder of 6/2 = 0]
- Post #7: $i = 7 [remainder of 7/2 = 1]
- Post #8: $i = 8 [remainder of 8/2 = 0]
From this we can see how testing the modulus against zero (or non-zero) results in two groups of (odd and even) numbers. For more mental torture, here is more information on the PHP modulus operator. But enough of this boring math stuff — let’s move on, shall we?
Pure CSS Method
As the astute reader may have observed, displaying two columns of horizontally sequenced posts is also possible using a single, default WordPress loop and a little bit of CSS. Consider the following code:
<div id="container_division">
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="post-block">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>
</div>
<?php endwhile; else: ?>
<?php endif; ?>
</div>
With each post enclosed within a “post-block
” division (i.e., <div
class="post-block">
), we can achieve a two-column post-display similar to that generated via the dual-loop method by declaring a width for each of the post blocks and then placing them within a fixed-width container division. Or, to express this idea visually:
With all of the post-block divisions floated to the left, they will automatically “stack” according to the diagram. Here’s an example of CSS that would make this work:
div.post-block {
width: 333px;
float: left;
clear: none;
}
div#container_division {
width: 700px;
}
As useful as this “pure-CSS” technique happens to be, it is not as flexible as the dual-loop version. Independently functioning loops provide greater control over layout and thus greater design flexibility. For example, using two individual loops, the post columns need not appear side-by-side, but may be placed anywhere on the page.
Peace Out
That’s it for this Perishable Press tutorial. If you have any questions, concerns, or criticisms, please share them in the comments section for this article. As always, thanks for reading! :)
58 responses to “Horizontally Sequenced Display Order for WordPress Posts in Two Columns”
Drop me an email (using one of the methods below) describing your desired loop structure and I will see if I can come up with something for you.
Regards,
Jeff
I’ve been at the crossroads PHP vs CSS solution. I went the PHP way and the steps are pretty much the same as your tutorial. The only difference is instead of dual-looping posts, I used it on displaying two-columned Categories.
Check it out: http://www.hotelsandtravel.org
I am building a WP theme. Your tutorial has quite solved my troubles :) but I am still missing something.
This image should clarify what I’m trying to do: http://img352.imageshack.us/img352/5196/examplewr6.jpg
Basically Post1 is my latest post in the blog. It’s shown big while posts from 2 onwards use a different style and are listed in two columns. Posts 2 and 3 get to show title and excerpt with their own style. Posts from 4 to 11 show only the title (with a third different style).
In your tutorial you have created two loops in order to list the posts in two columns..do I need 5 loops to achieve my goal?
Hey Stefano,
I think 5 loops would be the way to go, and it should keep things simple.
Hi Michael,
the idea of the 5 loops seems great but I keep on getting errors while tweaking my loops.
What i’m doing is:
1. tell the first loop to show the first post only(which will be my ‘featured’ post).
2. tell loop 2 to show post 2 and loop 3 to show post 3. The two articles are displayed side by side.
3. tell loop 4 to show even posts starting from post 4.
4. tell loop 5 to show odd posts starting from post 5.
(A visual scheme linked in my previous message).
I thought I could achieve this result by using the loop structure shown above adding strings such as numberposts= and offset= but apparently I know too little of php to figure out how to use those..could anyone please help out to put these guys in place?
tnx
I mean…I am pretty sure I could use this code for the first 3 loops:
MYCONTENT
But cannot use this to loops 4 and 5 as they should load the residual posts in horizontal sequence (Even and Odd)…and have offsets.
@Stefano: I think three loops (at most) should be all that you need to accomplish this layout. If you are still needing help with this, send an email and I will do my best to help you out. :)
Cheers,
Jeff
Would it be possible to have 3 columns?
Like this?
—post 1— —post 2— —post 3—
—post 4— —post 5— —post 6—
Why the need for all this counting and columns.
I imagined there would be away to achieve this result by telling the loop to display:inline.
Anyone found a way to do this?
@Martin: In the article, I discuss a way to display horizontal posts using CSS only. Basically, rather than using
display:inline;
or some fancy loop configuration, you simply float each post block in the same direction and setclear
tonone
. There is a bit more to it than that, so you might want to read the article for a better explanation.oops! sorry for my lack of tenacity in not even reaching the end of your article! Thanks for your speedy reply.
Any ideas about the 3 column thing?