This post is an update to a previous post on the Genesis Grid Loop.
That previous post had some shortcomings, especially concerning the number of grid posts and the number of posts as set in Settings -> Reading. If they didn’t match, then WordPress would declare one or more pages at the end of the pagination for those query of posts as being a 404 Not Found. We needed a better solution, and between legendary Genesis developer Bill Erickson and myself, we’ve come up with one.
The Code
Here’s some starting code that you can customise. More explanation is given below the code.
Woah! That’s a ton more code, but it is a more stable solution as a base from which you can customise the how the grid loop works for you. Here’s the breakdown.
Explanation of The Code
child_is_doing_grid_loop()
This first function simply returns true or false. You can use the conditional tags to choose under which situations you want the grid loop to kick in. By default, we want it when it is not a single post (including custom post types), not a single page and not a single attachment. Luckily WordPress has a tag to cover all three of those at once. Every other time we want to use the grid loop.
child_grid_loop_arguments()
The second function is where you’ll want to fine tune how the grid appears. Most of the array values should be intuitively named. If you want to limit a template to show a particular query (i.e., posts from the same category), then you’d amend the $query_args here.
child_prepare_grid_loop()
You shouldn’t really need to touch much in this function. This basically says to swap out the default function for our grid loop function and also amend the post class so we can add some styling later.
child_grid_query()
This amends what the query would have been for this page, with our grid loop and query arguments. After checking that this is the main loop, that we are indeed supposed to be showing the grid loop, and we’re on the front end, then it grabs a copy of our arguments. To allow for featured posts on the first page, and to keep the balance right on pages after the first page, some logic is done, which you probably won’t need to edit. The result of this logic is then set on the main query.
child_do_grid_loop()
This function gets our grid loop arguments, the query arguments (as potentially amended by the logic in the previous function), and merges them together before sending them all off to Genesis, which does the actual database query, and starts echoing the markup and content for this grid posts.
child_grid_loop_post_class()
The previous version of this tutorial also included some styles to paste into your style.css file, to ensure that the grid posts appeared in the correct columns. We now do a bit more work here, and make use of the column classes that have been included with Genesis child themes since Genesis 1.5 was released. If you find the grid isn’t appearing correctly, copy the Column Classes section of the Genesis style sheet into your own theme style sheet.
Thanks for the code!
Everything about this is working great, except for assigning the number of posts per page. With ‘posts_per_page’ in query_args, I’m not getting the desired number of posts. Moving that argument to grid_args fixed the problem. Am I doing something wrong here?
Also, I’m curious about something else. If I want one feature at the top of the page and an even number of posts in two columns below, I’d set posts per page to 5. This works great on the first page of posts, but every subsequent page then has one lonely post at the bottom of the left column. Can this code be altered to determine whether the “home” page of the category is being displayed and adjust the number of posts accordingly?
I’ll have to do more testing when I get a chance (absolutely swamped right now). I think the issue might be that Genesis *incorrectly* applies posts_per_page => get_option( ‘posts_per_page’ ) as the default query args, so we’ll need to add it to both. Putting it in the grid_args will ensure those posts are displayed, and putting it in query_args will ensure you don’t get a 404 when trying to load the page.
For your second question, that logic should already be built into the code above. Let’s say you want 4 grid posts (2 columns with 2 rows) and 1 feature post. You set features to 1 and posts_per_page to 4.
Thanks for the reply, Bill (and thank you for everything else you do for the world of Genesis — we make heavy use of your advice).
I’d thought the logic would do what you’re describing – that is, not count the featured post into the second page of an archive – but it does.
Rather than try to explain all this here, I did a quick screencast: http://screencast.com/t/6L7me3xnr
In that video I show you that I get a 404 when I try to display the second set of posts. This video shows what happens when I change the Reading settings from showing at most 20 post to showing no more than 10 posts: http://screencast.com/t/50pWsmUN9
Hi,
Could you check if 4 columns work?
I changed the section Alter this number to change the number of columns – used to add class names to:
$columns = 4;
But then the grid shows only 1 column. When I set it to 2,3,5 or 6 it does show 2, 3, 5 or 6 columns. But 4 isn’t working.