A More Flexible Grid Layout for Genesis

Sridhar Katakam has challenged me to do a spontaneous followup post to my last one, A Lazy Coder’s Grid Loop for Genesis. I’m building a simple shop page for a client, so I’m borrowing my own code to set up a similar, but more flexible grid layout for her loop.

By more flexible, I mean that I started wondering how to handle the grid if she wanted to change the layout. If you’re a Genesis Framework (affiliate link) user, you know that you can choose your site layout settings, so that your entire site can have a sidebar on the right, or on the left, or have two sidebars, or none at all. You may also know that you can override your sitewide settings on any given post or page as well. And, if you have a custom post type and are using the Genesis Archive settings, you can actually change your layout for your custom post archive.

Single Sidebar Grid Layout
Single Sidebar Grid Layout
I may build the site assuming that she’ll show her shop page with a single sidebar on the right, since that’s how we might set up the entire site. In that case, I would probably set up her grid loop to have three columns, because I think the spacing will suit that. If she decides that she wants to change her shop page to be full width, though, three columns will look a little funky, partly because of the size of her images, partly because it will just be really spread out. And if she wants to use that second sidebar? Total crowding.

I could be bossy and remove the layout options from her site altogether, but it feels a little highhanded and right now, I’m not interested in taking that away. So I thought I’d look into making the grid layout itself be flexible. Turns out, this is pretty doable, not only for a shop page, but it could also easily be incorporated into the code I shared in the last post. Here’s an animation of what the grid layout will look like with different archive layout options selected:
Flexible Grid Layout for Genesis
I’m going to share some code here, so if you’re an email subscriber or are using a feed reader, here’s the direct link for the code.

Simple Shop Flexible Grid Layout

The first part of my code is in a custom archive.php file, because that’s my project for today. If you would rather use it for your posts (sitewide), you would be working instead in your functions.php file, as we did last time. Here’s my archive file:

<?php
/**
* Archive page for products (custom post type).
*
*/
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 );
remove_action( 'genesis_entry_content', 'genesis_do_post_image', 8 );
remove_action( 'genesis_entry_footer', 'genesis_post_meta' );
add_filter( 'genesis_pre_get_option_content_archive', 'rgc_do_full_content' );
function rgc_do_full_content() {
return 'full';
}
add_filter( 'genesis_pre_get_option_content_archive_limit', 'rgc_no_content_limit' );
function rgc_no_content_limit() {
return '0';
}
add_filter( 'post_class', 'rgc_grid_post_class' );
function rgc_grid_post_class( $classes ) {
global $wp_query;
if ( ! $wp_query->is_main_query() ) {
return $classes;
}
$term = $wp_query->get_queried_object();
$layout = genesis_site_layout( $term );
$number = 2;
$column_class = 'one-half';
if ( in_array( $layout, array( __genesis_return_sidebar_content(), __genesis_return_content_sidebar() ) ) ) {
$number = 3;
$column_class = 'one-third';
}
elseif ( __genesis_return_full_width_content() === $layout ) {
$number = 4;
$column_class = 'one-fourth';
}
$classes[] = 'grid ' . $column_class;
if ( 0 == $wp_query->current_post % $number ) {
$classes[] = 'first';
}
return $classes;
}
add_action( 'genesis_entry_header', 'rgc_posts_grid', 5 );
function rgc_posts_grid() {
global $post;
if ( $image = genesis_get_image( 'format=url&size=product' ) ) {
printf( '<div class="grid-image"><a href="%s" target="_blank" rel="bookmark"><img src="%s" alt="%s" class="aligncenter" /></a></div>', get_permalink(), $image, the_title_attribute( 'echo=0' ) );
}
else {
printf( '<div class="grid-image"><a href="%s" target="_blank" rel="bookmark"><img src="%s" alt="%s" class="aligncenter" /></a></div>', get_permalink(), get_bloginfo( 'stylesheet_directory' ) . '/images/blank.jpg', the_title_attribute( 'echo=0' ) );
}
}
genesis();
view raw archive-product.php hosted with ❤ by GitHub

There is really not much to it, and even less styling. The high points are:

  • First, we’re removing the post info, post meta, and the post image.
  • Then we’re using the filters to show the full content, and skip the content limit … that would show otherwise. (You may want to do something different for yours–my shop content is really going to be this short, but you might want to just remove the post content altogether like we did for Tim’s grid last time.)
  • Skipping to the end, we’re using pretty much the same image replacement function as we did last time, although I’ve registered and am using a different image size.

The meat of today’s work is the post_class filter we’re building starting at line 23. We’re defining some variables up front:

  • $term: the current queried object
  • $layout: uses $term to retrieve the current page’s layout, which is using either the sitewide setting, or what we chose on the Archive Settings page.
  • $number: the number of columns we want to set initially
  • $column_class: the pre-defined column class which matches the number (so for 2, we use one-half)

Our two conditionals check the archive page layout and redefine the $number and $column_class accordingly. If the user selects a layout with one sidebar instead of two, we change to 3/one-third; if they select layout with no sidebars at all, we change to 4/one-fourth. It’s only in lines 46-50 that we actually get down to the work of finally defining the post classes. The cool thing is that we can change the variables as often as we want above, but the real work only has to be done once.

Since the column classes have handled most of the work of styling for me already, I can get away with doing just a bit of styling to make this work. My example above has just a border and a bit less spacing than the default entry styling.

/* Grid
--------------------------------------------- */
.entry.grid {
margin-bottom: 24px;
padding: 24px;
border: 1px solid #ddd;
border-radius: 0;
font-size: 16px;
text-align: center;
}
.grid .entry-title {
font-size: 24px;
}
view raw style.css hosted with ❤ by GitHub

The awesome thing about this setup is that if you’re using my Lazy Coder’s Loop for all of your posts, instead of just an archive page as I am here, your grid layout will adapt to whatever settings you choose for any given archive or taxonomy page. So if you set our site layout setting to show just one sidebar, but want to change certain categories to show two, or none at all, your grid will still work!

Special thanks to Gary Jones for cleaning up my sloppy conditionals, and to Sridhar for forcing me to blog about it. Also, if you noticed the Featured Product widget in the sidebar of the screenshot, that’s done using the awesome Featured Custom Post Types Widget by the fabulous Jo Waltham.

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

  1. November 11, 2014

    Thanks for this tutorial. I haven’t read the one this is based on yet, but will definitely do so. I’m giving a lecture on custom post types in the WordPress class I teach tonight, and this will be a good example to show of an adaptable grid archive. Keep up the good work.

  2. November 11, 2015

    Thanks for sharing your blog posts =). I don’t understand how you set this grid up. Your posts doesn’t really explain how to set up the grid layout. I’m trying to set up the same grid layout. Can you please help. Will copying and pasting your code on the page I want the grid layout to be on work?

    • November 16, 2015

      The tutorial is PHP and CSS, so it’s not going to be added directly to any page in your WordPress admin. You need to decide how you’re wanting to use it (my example is for a custom post type archive, for example), and then put the PHP in the appropriate place in your theme–might be archive-download.php, home.php, or functions.php, with modifications for your own use case. It won’t change the writing experience within WordPress at all.

  3. June 21, 2016

    Hi Robin,
    Could I do something like this for a custom page?
    For example, if I want a 2-column grid for youtube videos, creating a page called, say, videos.php?

    • June 22, 2016

      Jamie, I think you could do that if you set the videos up as a custom post type–that’s really what this tutorial is for. If you’re just trying to do it on a single page with a custom template, I think you’d need to implement it using custom fields, maybe, for the most flexibility. Doing a custom post type with a featured image, though, I think would be fairly straightforward with this.

  4. September 3, 2016

    Not sure how I missed this post before, but it’s a really cool way to offer a flexible grid. I’m gonna steal some of the code and adapt it to the flexbox grid I’ve been using.

    Thank for sharing!

  5. March 2, 2017

    This info is exactly what I was looking for. Thank you! The only thing I wish it included was how to determine how many cpt entries per page I want to have. For example I’d like to have let’s say… 21 entries before pagination begins.

    • March 5, 2017

      To do that, you’d want to use a function modifying the query itself. I usually do this with the `pre_get_posts` hook and modify the query there–just be aware that this code can’t go into a template file; it usually has to be somewhere like your functions.php file.

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