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.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
|
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.
Sticky Posts
If you amend the query arguments for a grid on the blog archive page to only include posts from a certain category, tag or taxonomy, and find that sticky posts stop working, add the following code to fix it:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
A Better and Easier Grid Loop
It should be noted that the grid loop code above is for when you want to create a second loop on the page, or make use of some custom query loop that won’t produce the same posts as what would naturally have appeared there anyway.
If you do just want to style the existing posts, then take a look at a new tutorial from Bill Erickson, as he explains about a better and easier grid loop.
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.
Bill, thank you for your answer on how to remove a featured post. After two hours of searching articles and forums I’m grateful to have found your article.
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
So, I set the number of posts to display (in Settings -> Reading) to 1, and it (mostly) works now. I still have the issue with pages 2 through x showing the wrong number of posts. Anyone else see this?
Hi Dave- I have this same issue with the grid loop- it is showing correctly on the homepage of my site when I set the number to 7 (it is showing the first full post and then 6 excerpts underneath) but on the other pages it is showing 7 posts in two columns so it looks off balance. Did you ever find a solution for this? Thank you!
Sorry, no I didn’t. I just asked the client to live with it until I can figure it out. Maybe Bill or Gary have come up with something.
Hi Dave and Marina,
I have the exact same issue with the grid loop…. Have you found a solution for this? I’m working on a site which I will be putting online soon…. Thanks, Helen
Hi Helen,
Unfortunately, no. We’ve ended up using Types & Views for this kind of thing now. In some cases it’s like shooting a raccoon with a bazooka* when a pellet gun would do, but it gets the job done.
*Note: no wildlife or livestock have been harmed in the building of our websites.
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.
Thanks for sharing snippet.
–0–
Hi @aski:
I have checked sample theme, there is no ‘one-quarter’ class, it should be ‘.one-fourth’
Ah, of course it should palPalani – code updated, thank you!
Thank you palPalani and Gary.
Hi Gary,
The detailed explanation that you have provided here is simply awesome. Thanks for the help. I have a quick question. I would like to add a few widgets as part of thye grid loop. like say, after the featured section I have two widgets then two blogs of content then widgets again.
Is this even possible and can you help me figure this out.
Not easily Eddie. The actual output is left to
genesis_grid_loop()which does the actual looping through each post. You’d have to roll your owneddie_custom_grid_loop()where you tookgenesis_grid_loop()as the starting point, and then tweaked it to output widget areas after a certain number of posts, and finally amending the code above to call your grid loop function instead of the one in Genesis.Thanks for your Genesis grid code and explanation.
I had the Genesis grid working but would like to have 3 or more columns instead of just 2. I put your code in the child functions.php file and plan to have the grid on a page template so I modified the following to the template name.
return ( is_page_template(‘portfolio-place.php’) );
I am getting this: Sorry, no posts matched your criteria. (I am working locally so I can’t post a link.)
Any help is appreciated. Thanks!
Just when you ask for help you figure it out! I used the regular genesis code from the studiopress.com site and added classes to it for styling on the page template. I modified ‘more’ to remove it, added ‘cat’ to display only certain categories, removed the image after the title and added it above, and removed the post meta and post info.
0,
‘feature_image_size’ => 0,
‘feature_image_class’ => ‘alignleft post-image’,
‘feature_content_limit’ => 0,
‘grid_image_size’ => 0,
‘grid_image_class’ => 0,
‘grid_content_limit’ => 0,
‘more’ => ”,
‘posts_per_page’ => 9,
‘cat’ => ’3,7,8,11,13,14,15,22′
) );
} else {
genesis_standard_loop();
}
}
function child_grid_loop_image() {
if ( in_array( ‘genesis-grid’, get_post_class() ) ) {
global $post;
echo ”.get_the_post_thumbnail($post->ID, ‘child_thumbnail’).”;
}
}
/** Remove the post info and meta from grid loop **/
remove_action( ‘genesis_before_post_content’, ‘genesis_post_info’ );
remove_action( ‘genesis_after_post_content’, ‘genesis_post_meta’ );
add_action(‘genesis_before_post_title’, ‘child_grid_loop_image’);
// Add some extra post classes to the grid loop so we can style the columns
add_filter( ‘genesis_grid_loop_post_class’, ‘child_grid_loop_post_class’ );
/** Add column classes to style **/
function child_grid_loop_post_class( $grid_classes ) {
global $_genesis_loop_args, $loop_counter;
// Alter this number to change the number of columns – used to add class names
$columns = 3;
// Be able to convert the number of columns to the class name in Genesis
$fractions = array( ”, ‘half’, ‘third’, ‘fourth’, ‘fifth’, ‘sixth’ );
// Only want extra classes on grid posts, not feature posts
if ( $loop_counter >= $_genesis_loop_args['features'] ) {
// Make a note of which column we’re in
$column_number = ( ( $loop_counter – $_genesis_loop_args['features'] ) % $columns ) + 1;
// Add genesis-grid-column-? class to know how many columns across we are
$grid_classes[] = sprintf( ‘genesis-grid-column-%d’, $column_number );
// Add one-* class to make it correct width
$grid_classes[] = sprintf( ‘one-’ . $fractions[$columns - 1], $columns );
// Add a class to the first column, so we’re sure of starting a new row with no padding-left
if ( 1 == $column_number )
$grid_classes[] = ‘first’;
}
return $grid_classes;
}
genesis();
Then in the style.css file I added the following code and removed the odd and even code. It is not pretty yet but it is working!
/* Portfolio grid
———————————————————— */
#content .genesis-grid {
float: left;
margin: 0;
border: 1px #fff solid;
background: #e1e1e1;
min-height: 450px;
padding: 15px 0 10px 3%;
}
#content .genesis-grid-column-1 {
clear:left;
padding-left: 0;
}
.size1of2 {
width: 48%;
}
.size1of3 {
width: 31%;
}
.size1of4 {
width: 22.5%;
}
.size1of5 {
width: 17.4%;
}
.size1of6 {
width: 14%;
}
/* Above widths assume 0 left padding on the first column, 3% left padding on all
subsequent columns, and a total sum of 99% to avoid browser rounding errors */
I would like to adjust the responsive design to drop from 3 columns to 2 and then to 1 instead of dropping from 3 to 1. It may not look good on a tablet as is.
Great article. I am attempting to apply this to the idea of creating a page that lists a set of child pages (of that page) with excerpts and stumped as to what to do to make that happen.
I can’t seem to get it to display anything except posts… how do you modify this code to make it work for pages displaying children and children excerpts?
Thanks
Chris
You would just need different query args, with results that had a parent ID the same as the current post (Page) ID. See the codex on WP_Query to know what query args are available.
Thanks… will look into it.
Would there be a way to add a widget inside of the grid loop? I am trying to have the first post go 100% width, then have a widget with social icons and a subscribe button go 100% and then have 4 more posts in a grid going 50% each. Hopefully that makes sense
I know that I can add a widget above or below the grid using this tutorial: http://www.briangardner.com/home-widget-area-eleven40/ but it does not help me to add a widget area between posts 1 and 2.
Thanks!
You can do something close to Brian’s tutorial, but hook into
genesis_after_post. You’ll need a conditional and check against a global – I *think* Genesis has one called$loop_counter, but I’m pretty sure there’s a WP global one too.Where do you put the global $loop_counter in that code?
Thanks Gary and Bill for all you do for the Genesis and WP community. This was very helpful, and very well explained.
I have a grid loop that has 4 featured posts (that I make semi-static with sticky posts) and then 6 normal recent posts. First, I would like to only display the post title and featured post image on every featured post in the grid loop, but would like the remaining recent posts of the grid loop as default. Secondly, I would like to add an html wrapper around the first two featured posts and the last two featured posts (I would prefer to avoid javascript). Is there a way to do this? Any help would be wonderful and well appreciated.
Hi Gary,
I have a question: How can i styling with css code in genesis grid loop, i can add element into column by use “#content .genesis-grid-column-1 {” with column 1 and “#content .genesis-grid-column-2 {” with column 2, so i can add some style like background-color, shadow, font-size …. but the problem is i can’t change contain in features post grid area (i created page with 2 column and 1 post featured on front), beacause i don’t know what class base on “features”, i think.
Please help me solve this problem.
Thank you Gary.
Gary,
How would I modify code to use in a page template?
David
Thanks for the code! It’s working great so far.
One question: How can I target my post classes when using add_action and remove_action?
For instance, let’s say I want my featured post to have an excerpt, but I want my grid posts to hide the excerpt.
Thanks,
- Mike
thanks alot Gary, i have had series of issues regarding my sticky post in the genesis eleven40 child themes, but this post had just solved the problem.
Thank you Gary. I’m trying to add a new query arg to the main query but I’m not sure where to put it. Can you help? Thank you!
Nevermind – this is exactly what I was looking for! Thank you.
I cannot get this to work – the query args just aren’t ‘taking’. The other grid args are working fine. The grid is showing up. The only thing that is NOT working are the query args. Posts per page, orderby, and order. I’m using this in an archive page… if that makes any difference?
This part seems to take into account the grid args only? Not the query_args?
function child_do_grid_loop() { global $wp_query; // Grid specific arguments $all_args = child_grid_loop_arguments(); $grid_args = $all_args['grid_args']; // Combine with original query $args = array_merge( $wp_query->query_vars, $grid_args ); // Create the Grid Loop genesis_grid_loop( $args ); }In my Genesis Theme Settings, I have asked it to exclude a specific category ID from showing on the blog template. However, this code doesn’t seem to respect that. I’m trying to figure out how I add a !in_category query to the child_grid_query. Thanks for your help!!