If I have a loop running from a category query like :
<?php $the_query = new WP_Query('cat=1&showposts=50&orderby=title&order=asc');?>
<ul>
<?php while ($the_query->have_posts()) : $the_query->the_post();?>
<li>.. </li><?php wp_reset_query(); ?>
<?php endwhile; ?>
</ul>
How would I create an if clause that breaks the list at a certain interval, and starts a new one. So for example at the 10th post, return a </ul>
and start a new one <ul>
at 11.
This is incorrect but to illustrate my objective:
<?php $count =0;
while($count <=50){
if ($count == 9){
echo "<li><a href='<?php the_permalink(); ?>'>
<?php the_title(); ?></a></li></ul>";
}
elseif ($count == 10){
echo "<ul><li><a href='<?php the_permalink(); ?>'>
<?php the_title(); ?></a></li>";
}
else {
echo "<li><a href='<?php the_permalink(); ?>'><?php the_title(); ?></a></li>";
}
What is the correct way to include this logic into the loop?
Create Columns for your query and easy display
In themes is probably more useful to have something that fits well into template tags and the loop. My first answer didn’t focus on that much. Additionally I thought it’s a bit too complicated for a quick adoption.
An easier approach that popped into my mind was to extend “the loop” with columns and came to this solution so far:
A WP_Query_Columns object “extends” any standard WP query with colums that can be easily iterated over. The first parameter is the query variable and the second parameter is the number of items to be displayed per column:
To use it, just add the WP_Query_Columns class from this gist to your themes function.php.
Advanced Usage
If you need the column number you’re currently displaying (e.g. for some even/odd CSS classes, you can get that from the foreach as well:
And the total number of columns is available as well:
Twenty Ten Example
I could quickly hack twenty ten theme for a test and adding headlines above any loop this way. It’s inserted into loop.php, the beginning is the theme’s code:
For a longer answer:
(that is basically how I came to the stuff above, but explains better how to actually solve the problem with simple mathematic operations. My new solution is to iterate over something pre-calculated.)
It depends a bit how much you actually need to solve the problem.
For example, if the number of items per column equals one, this is very simple:
Even with that simple code, it can be seen that there are multiple decisions to be made:
The last question is pretty interestering for HTML output as you probably want to enclose not only items but also the column with html elements.
Luckily with code, we can set all these in variables and create code that always computes to our needs.
And sometimes even, we can not even answer every question from the beginning. For exmaple, the count of total items: Are there any, some, multiple, an exact count that matches up with an integer number of columns in total?
Even Jan Fabry’s answer might work in some cases (as my example above does for the one-item-per-column scenario), you might be interested in something that works for any number of items returned by WP_Query.
First for the math:
That code doesn’t run, so let’s put that up into a simple text example
This actually runs and does some output already:
This simulates already pretty well how it could look like in a wordpress template:
(I have not executed the last example in a WP environment, but it should be at least syntactically correct.)
This is more a general programming question, but here is the basic idea:
There’s no need to create a separate var for counting, as the query var already counts it at:
$wp_query->current_post
. Also, you need to account for the final entry in the list so you don’t have empty<ul></ul>
in your markup.Add the
get_columns_array()
function to your function.php. You can then easily iterate over your columns:In your theme you then foreach loop over the columns:
I set the default size of a column to 10. You can use the second parameter to set the size of a column on your own. Like to 7:
get_columns_array($post_count, 7);
.Here is another approach you can take: