A Lazy Coder’s Grid Loop for Genesis

A few weeks ago, my friend Tim contacted me about doing a wee bit of a refresh on his website, Faith and Doubt. He wanted to change his site so that his posts display as a grid loop, with just the title and featured image, and no content. I thought this would be a fairly straightforward task to accomplish, and promptly disappeared down a rabbit hole trying to make it happen.

This is a tutorial for the Genesis Framework from StudioPress (affiliate link), because that’s what I use. However, with the right CSS and hooks, you could convert this for use with other themes, I would assume.

Lazy Coder's Grid Loop for GenesisThere is a grid loop function built into Genesis, but for me it was problematic because it doesn’t allow me the option to remove the post content entirely, which was one of Tim’s requirements. I found quite a few blog posts around the interwebs with other approaches to creating a grid loop, and none of them worked for me. I’m totally willing to accept that this is user error, and take the blame on it, but they simply didn’t work for me.

What finally set me on the path of enlightenment was a fairly simple tutorial from the excellent Sridhar Katakam. If you build Genesis websites and don’t subscribe to his blog yet, please pause and correct this deficiency immediately. I will wait.

Obviously, this wasn’t 100% of what I needed, but it certainly helped me move in the right direction. What I decided I wanted was to show the latest post in full on Tim’s front page, and then shift to the grid below that, and sitewide otherwise. I also wanted to make sure I had a full final row of posts on each page throughout the site, whether or not there was a full post at the top.

Set Up the Front Page

Many Genesis child themes have special front pages which are built with widgets for a special layout option. This front page file is different in that it only does one thing, which is to make sure that the first post’s content displays in full (if you’re using an RSS reader or are an email subscriber, you can see all the code here).

<?php
/**
* This file adds a front page. It forces the first post on the page to output
* as full content.
*
* @author Robin Cornett
* @package Genesis
* @subpackage Customizations
*
* source: http://sridharkatakam.com/display-full-post-content-first-post-category-pages-genesis/
*/
// Remove post image
remove_action( 'genesis_entry_content', 'genesis_do_post_image', 8 );
//* Full content for first post in category pages
add_action( 'genesis_before_entry', 'rgc_first_post_content' );
function rgc_first_post_content() {
global $wp_query;
if ( ! is_paged() && $wp_query->current_post == 0 ) {
add_filter( 'genesis_pre_get_option_content_archive', 'rgc_do_full_content' );
add_filter( 'genesis_pre_get_option_content_archive_limit', 'rgc_no_content_limit' );
}
}
// Set the content archives to full
function rgc_do_full_content() {
return 'full';
}
// Make sure the content limit isn't set
function rgc_no_content_limit() {
return '0';
}
genesis();
view raw front-page.php hosted with ❤ by GitHub

Set up Your Grid Loop

For everything else, you’ll want to add this to your functions.php file:

<?php
// add this to your functions.php file but do not include the opening tag!
//* Add new image sizes
add_image_size( 'home-middle', 332, 190, TRUE ); // unnecessary if you are already using Metro Child theme
add_action( 'genesis_before_entry', 'rgc_grid_posts' );
function rgc_grid_posts() {
global $wp_query;
if ( is_singular() || is_post_type_archive() ) {
return;
}
if ( $wp_query->current_post != 0 || is_paged() || ! is_home() ) {
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 );
remove_action( 'genesis_entry_content', 'genesis_do_post_image', 8 );
remove_action( 'genesis_entry_content', 'genesis_do_post_content' );
remove_action( 'genesis_entry_footer', 'genesis_post_meta' );
add_filter( 'post_class', 'rgc_grid_post_class' );
add_action( 'genesis_entry_header', 'rgc_posts_grid', 5 );
}
}
function rgc_grid_post_class( $classes ) {
global $wp_query;
if ( $wp_query->is_main_query() ) {
$classes[] = 'grid one-third';
if ( is_home() && ! is_paged() ) {
if ( 0 == ( $wp_query->current_post +2 ) % 3 ) {
$classes[] = 'first';
}
}
elseif ( 0 == $wp_query->current_post % 3 ) {
$classes[] = 'first';
}
}
return $classes;
}
function rgc_posts_grid() {
if ( $image = genesis_get_image( 'format=url&size=home-middle' ) ) {
printf( '<div class="grid-image"><a href="%s" rel="bookmark"><img src="%s" alt="%s" /></a></div>', get_permalink(), $image, the_title_attribute( 'echo=0' ) );
}
else {
printf( '<div class="grid-image"><a href="%s" rel="bookmark"><img src="%s" alt="%s" /></a></div>', get_permalink(), get_bloginfo( 'stylesheet_directory' ) . '/images/blank.jpg', the_title_attribute( 'echo=0' ) );
}
}
add_action( 'pre_get_posts', 'rgc_front_page_number_posts' );
function rgc_front_page_number_posts( $query ) {
if ( $query->is_home() && $query->is_main_query() && ! is_paged() ) {
$query->set( 'posts_per_page', 10 );
}
}
view raw functions.php hosted with ❤ by GitHub

Let’s unpack the code a bit. Depending on the child theme you’re using, you may have an image size in place which you can already use. Tim’s site is based off of the Metro Pro theme; since home-middle is an image size which he’s been using for over a year, I kept that in place and removed the other image sizes which were added by the theme. Your image sizes can be whatever you want, and named whatever you want, as long as you change the name in the image function further down as well.

What we’re doing first is setting our conditions for any of the work to happen. Basically, if we’re on a single post, page, custom post type, or a custom post type archive, we’re done and getting out of here. So, what’s left are all the category, tag, and archive pages.

Then we have to strip out all of the unnecessary elements–basically, most of the things which go into making a standard blog page. We’re removing the post content, the post image (we’ll add it back, don’t worry!), and the info and meta (the comments, dates, list of categories, etc.). Right now, our grid is a boring list of post titles.

We then add two functions of our own making: one to add a new post class to our grid posts, and one to build and handle the new grid output.

For the post class, we’re using column classes which are already built into most Genesis child themes, and then doing a bit of math to make sure all the posts in the left most column line up properly, making sure they have a class of .first applied to them. You could change the number of columns quite easily here, to be two columns (use one-half instead of one-third) or four (one-fourth). Just make sure you adjust the formulas accordingly. Notice that there are two parts to this, depending on whether the user is on the front page of the site or not, since only the front page of the site has the one full post.

Our next function adds the image back in. This is where you’ll want to change the image name if you’re not using home-middle. I also have set a fallback image to use in the grid if a featured image isn’t specified, or if a post doesn’t have any images at all, since that’s important to the layout. If you use the fallback image, make sure it’s the same size as the home-middle image setting, and upload it to your theme’s images folder.

The final bit changes the number of posts which show on the front page of the website. Since we’re doing three columns of posts throughout the site, we want the number of posts to be divisible by three (we picked twelve). However, the front page has that one full length post at the beginning, which counts as one of the twelve, which throws off the grid, so this query sets the front page to show ten posts: one full length, and nine in the grid.

Tim’s site is based on Metro Pro, so the styling for his grid posts are specific to that theme, but you can easily change it to match yours:

/* Grid -- styled to match Metro child theme
--------------------------------------------- */
.grid .entry-header {
margin: 0 10px 10px;
padding-bottom: 10px;
background: #fff;
}
.grid .entry-title,
.grid h2.entry-title a {
padding: 0;
background: none;
}
.grid .entry-title {
margin: 10px;
font-size: 18px;
line-height: 1.2;
text-transform: none;
}
.entry.grid {
margin-top: 24px;
margin-bottom: 24px;
padding-top: 10px;
padding-bottom: 0;
background: url(images/lines.png);
}
.grid-image {
overflow: hidden;
border: 10px white solid;
}
.grid img {
display: block;
float: none;
margin: 0 auto;
}
.grid a img:hover {
-webkit-transition: ease-out 8s;
-moz-transition: ease-out 8s;
-o-transition: ease-out 8s;
transition: ease-out 8s;
-webkit-transform: scale(1.2);
-moz-transform: scale(1.2);
-o-transform: scale(1.2);
transform: scale(1.2);
}
view raw style.css hosted with ❤ by GitHub

And that’s it! No need to create a custom loop or template, or do any fancy finagling to solve math to set up a layout. Navigating through pages of posts is seamless, because we didn’t change anything with it, and we’re using as much pre-existing code work as we can, because either we are lazy, or we are standing on the shoulders of giants, however you care to look at it.

Do something awesome. Tell a friend:

subscribe by email

If you're an email kind of person, that's totally cool. Go ahead and sign up here to get the latest blog entries in your inbox! No worries, I never share your address.
  • This field is for validation purposes and should be left unchanged.

Reader Interactions

Comments

    • November 7, 2014

      I have not tried that plugin, thanks, Sri! And thank you for all of the links, too. Definitely more ways to tackle this than I thought at first.

  1. December 10, 2014

    I’m trying to find a way to get the powerpress shortcode to work in the grid loop so the embedded players will be displayed with each of the posts in the grid.. I’m running minimum pro and the home page has a 2 col. grid with the teasers for the latest posts displaying but the grid loop entry content is being displayed instead of the post excerpt which has the shortcode

    Will using the above approach work? Or is there another way to get the players embedded in each teaser?

    • December 10, 2014

      Hey James! Minimum Pro, from what I remember, uses the Genesis Grid Loop function, which is pretty nifty, but I ran into trouble trying to modify it much–for instance, removing the entry content completely, which is how I ended up here. I’m guessing that’s where you are as well, so yes, I think with some modifications, this could work for you. You’ll want to remove the genesis_loop lines from the Minimum Pro front page, and then what you will need is probably more of the code in the functions.php file in this post, but in your front page, I think. Then you should be able to add in the entry excerpt using the genesis_entry_content hook. It will probably take some trial and error, but I think that it should work. Good luck!

  2. February 15, 2015

    Thanks so much for this, I’m new to Genesis, what seems like such a simple request proved somewhat elusive…
    Your solution works great for me
    Thanks for sharing!

  3. October 16, 2015

    Hi,
    I am also using genesis eleven pro child theme for my blog and want to change the homepage style from grid post to normal. Can you guide me how to make this?

    • October 16, 2015

      I would look in the home.php file for that theme. If you comment out the first two lines:

      remove_action( 'genesis_loop', 'genesis_do_loop' );
      add_action( 'genesis_loop', 'eleven40_grid_loop_helper' );

      then you should have the standard posts loop back. HTH

  4. January 8, 2016

    Great solution. I tried the Genesis Grid plugin and Bill Ericksons solution, but I prefer yours.

    How would I remove the first featured post, so just the columns display?

    • January 8, 2016

      Well, you’d start with ditching the front page specific code, which handles the modifications for that first post, so you wouldn’t need the front-page.php from here at all. In the functions.php above, I’d change line 16 to if ( is_archive() || is_home() ) {, remove lines 33-37, and make sure to change that elseif to just an if, and that should more or less do it, I would think. Good luck!

  5. January 21, 2016

    Hi great tutorial. I currently am using metro pro. I was wondering if I had to do this to get 2 columns for the middle home part or if there was another way to achieving that. I wanted to show 2 columns per category. Currently it shows middle left category and middle right. Thanks

    • January 22, 2016

      Since the home-middle section of Metro’s front page has widget areas, I don’t think this is the solution you want for that. If you set up the left and right areas with the number of widgets/posts you want in each, you should be able to make them show as two columns with the appropriate CSS. Hope that helps–

  6. March 10, 2016

    Hi Robin, thank you SO much for this tutorial – this is exactly what I needed and I’ve been looking everywhere something to point me in the right direction. I have a question for you – for the first post, instead of the full text, I just wanted a larger picture, the post title, and an excerpt posted. I’ve been able to get the larger picture to appear, but I’m having an issue getting the title/excerpt to appear under the image. Do you have any suggestions? Thanks!

    • March 10, 2016

      Hey Carrie! Probably to get the excerpt on the first post, rather than the full content, you need to modify the rgc_do_full_content() function to return excerpts instead of full:

      function rgc_do_full_content() {
      return 'excerpts';
      }

      Hope that helps!

  7. October 7, 2016

    Hi Robin, this tutorial has been so helpful, I’ve used it for one of my clients’ site.
    Now I’m using it on my own site with some modifications: I want to display three full content posts and have some html code before the grid post section that says “More posts”. I’ve been trying to figure this out myself without luck. Could you help pointing out the solution? Thanks so much!!

    • October 7, 2016

      To change the number of posts that show the full content, you’d want to adjust the count in line 22 of front-page.php, and then line 16 of functions.php. You might also have to tinker with the post class function, as the division there may not work with the new numbers.

  8. August 20, 2017

    Hey Robin, I love the code. Thank you it works great!

    Now I had this idea, to show a different amount of posts on the first page (one full post only three or six additional grid image posts) than on the following pages (e.g. 24 grid image posts)

    I thought, I had figured it out, using offset after line 61
    else {
    $query->set( ‘offset’, 7 );
    $query->set( ‘posts_per_page’, 24 );
    }

    This produces the right optical output on the website but unfortunately it also “cuts” the newest 7 posts in my wordpress dashboard… Any other idea?

    Thanks in advance! Best wishes from Germany

    • August 20, 2017

      Probably what would be best to do is to return early on in the function if the view is in the admin. Something like this right after the function opens should help:

      if ( is_admin() ) {
      return;
      }

      Hope that helps you get started!

  9. November 19, 2017

    Wow, this is a very useful post. I used it in a totally different child theme and it works out of the box; didn’t have to edit anything.
    I am just wondering what I need to do if I want to make it 4 columns instead of 3. Could you give any pointers please? Thank you.

    • November 20, 2017

      Never mind, I figured it out. I’m just wondering if it’s possible to add header image to the page. How can I do that?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Bars Code Check chevron-down chevron-left chevron-right chevron-up Envelope Laptop Search Times Facebook GitHub Google Plus Instagram LinkedIn Pinterest Twitter WordPress Logo Wordpress Simple