Custom Layout Options in Genesis

Genesis comes with a great feature called Layout Options. This allows content creators to specify the layout of the specific page or post they’re writing. By default it comes with all the different ways you can display one, two, or three columns.

You can unregister the defaults, and you can create your own layout options.

I used this on a recent project to create an Archives layout option. When this is selected, the page content is replaced with a thumbnail and excerpt of three children pages (example).

There’s two steps: register the layout, then use it in your theme.

Register A New Layout

Here’s what I used to create a layout called Sidebar/Content Archive. Place this in your functions.php file:

/**
 * Create Archive Layout
 * @author Bill Erickson
 * @link http://www.billerickson.net/wordpress-genesis-custom-layout/
 */
function be_create_archive_layout() {
	 genesis_register_layout( 'sidebar-content-archive', array(
		'label' => __('Sidebar/Content Archive', 'genesis'),
		'img' => get_bloginfo('stylesheet_directory') . '/images/layout-sidebar-content-archive.gif'
	) );
}
add_action( 'init', 'be_create_archive_layout' );

The first parameter is the layout slug, and the second parameter is an array that contains the label and the image.

Implementation

To figure out what layout a current page is using, use this function: genesis_site_layout();

Once you’ve registered a new layout, you need to decide what you’re going to do with it. In my case, I wanted the Sidebar/Content Archive layout to replace the loop with a listing of children pages. So, I removed the default loop and created a custom one that checked the page layout.

<?php
/**
 * Custom Loop for Archive Layout
 * @author Bill Erickson
 * @link http://www.billerickson.net/wordpress-genesis-custom-layout/
 */
function be_archive_layout_loop() {
	$site_layout = genesis_site_layout();
	if ( 'sidebar-content-archive' == $site_layout ) {
		be_archive_loop();
	} else {
	genesis_standard_loop();
	}
}
remove_action('genesis_loop', 'genesis_do_loop');
add_action('genesis_loop', 'be_archive_layout_loop');

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson

Comments

  1. Jamie says

    great job on that project!

    would you mind sharing a little how you added the ‘intro box’ as you have done such a beautiful clean job with the coding? it would be a great help

  2. Campbell McArthur says

    Hi Bill,

    Is there a way to have the genesis Archives page to display a compact Archives by Year/Month that displays like this>>

    2011: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
    2010: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
    2009: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

    I have been searching for a way to do this for 3 weeks now and the only reference that I can come up anything related to this specifically is 2 Plugins which are both outdated and have not been maintained for 3-4 years – Smart Archives > http://hypertext.net/lab/smartarchives/demo/
    The other is Compact Archives > http://rmarsh.com/plugins/compact-archives/

    I have actually contact the Dev of Compact Archives and asked for assistance to get the PHP code for my functions file but He has some terminal Illness for the past 3 years now for that reason he does not do it anymore.. Sad.

    Thank you Bill,

    Cam

    • Bill Erickson says

      While it’s doable, coming up with the actual code is beyond the scope of what I offer for free through the blog (it would take a while to come up with it).

      Just because those plugins are old doesn’t necessarily mean they are outdated. I’d start by installing those plugins and see how they’re built, and see if there’s any deprecated functions or things that could be done better now.

  3. Tim Osborn says

    Hi Bill,

    Thanks for your great resources – what is the difference between a Genesis Layout and a WP post template? I understand that a layout has a funky thumbnail, but besides this, I’m not sure why I’d use a Layout.. I usually unregister all but the fullwidth and either a left or right sidebar.

    TIA, Tim

    • Bill Erickson says

      Technically a Genesis layout is simply a class on the body tag and it determines which sidebars are loaded. It gives you an easy way to define the different ways a page can be displayed. I usually disable all the three column layouts and only leave Full Width Content, Content Sidebar, and Sidebar Content.

      Personally I think page templates are best when there’s actually different functionality associated with it. For instance, the Archive page template displays a sitemap. So if I want to change the functionality or content displayed on the page, I usually use a page template. But if I want to change the layout (how the page content is displayed, rather than changing the content itself), I’ll use Genesis layouts.

      You can also add your own layouts, and in template files force a certain layout to be used. So if I build a “Landing” page template, I’ll often put this in the theme file to ensure it is a full width page: https://gist.github.com/2710376

  4. Fred says

    Hi Bill,

    In Thesis I am able to define a Custom CSS Class in the custom.css file and then use it on a per-page basis to turn on and off features. Is there an analogous way to do this in Genesis?

    Much thanks,

    Fred

    • Bill Erickson says

      Yes there is. When editing a post or page, go to the Layout Settings metabox. You can specify a body class and/or a post class.

  5. Cal says

    Hey Bill,

    I’m trying to set up a new template where there are three rows. The first row is full width, the second row includes content to the left and sidebar to the right. The bottom row is full width again. Do you know if there is a tutorial or documentation on this somewhere? I checked the Genesis documentation, but couldn’t find anything.

    Thanks!

    • Bill Erickson says

      The easiest way to do that is with Column Classes, assuming that sidebar you mentioned is page-specific and meant to be editable in the page content: https://gist.github.com/3427180

      If you want the middle column to be the full post editor and its sidebar to be the actual sidebar, you’ll need to do the following:
      1. Create a metabox with two wysiwyg’s: Top Content and Bottom Content
      2. Hook into genesis_before_content_sidebar_wrap and genesis_after_content_sidebar_wrap to display the respective post meta fields.

  6. Richard Buff says

    Bill, this looks like a great way to automatically list subpages with thumbnail and excerpt on the parent page, which is something I need to do very often (also that subpages widget is really cool). However, sometimes client information isn’t quite so structured. For example, a client’s navigation may be requested to be setup as:

    About (parent)
    -Our Hours (subpage)
    -Our Staff (subpage)
    -Email Us (subpage)

    But then they might also want:

    Contact (parent)
    -Directions (subpage)
    -Email Us (subpage)

    As you can see, the Email Us page appears in two different locations. On the backend, it can’t be the child of two different pages. So is this dynamic method of listing child pages on the parent page feasible in this case? Would I need to manually create the thumbnail/excerpt content on the parent page instead?

    • Bill Erickson says

      The easy solution would be to create two Email Us pages, one under each top level item. If you only wanted a single (canonical) URL, make one redirect to the other. So you’d create a page About > Email Us and that redirects to Contact > Email Us.

      A more complicated but flexible solution would be to use Posts 2 Posts plugin to create a post type linke (pages_to_pages), and connect the subpages you want displayed. This way you could include content from anywhere in the site – it doesn’t have to be a subpage of the current page. You’re also able to limit it to specific pages – it doesn’t have to include all the current page’s subpages.

  7. Scott says

    Bill, thank you for this. This is some in-depth and high quality content and follow up – really appreciate it!

  8. Alex says

    Hey Bill,

    How can I add a new Layout Out Slug and show only the content?

    I added a new slug “full-middle-content” and “Content” on Label:
    genesis_register_layout( ‘full-middle-content’, array(
    ‘label’ => __(‘Content’, ‘genesis’),

    The problem I have is that the layout load the primary and secondary widget area and I only want to show the content. This is because I need two kinds of Full Width Layouts.

    Thank you!

    • Bill Erickson says

      You’ll want to place this in your theme:

      remove_action( 'genesis_after_content', 'genesis_get_sidebar' );
      add_action( 'genesis_after_content_sidebar_wrap', 'genesis_get_sidebar_alt' );

      Then add your own functions to those hooks that load the sidebar for the correct layouts. See the bottom of /genesis/lib/structure/layout.php

  9. Brian says

    Hi Bill,

    Quick question. I’m writing a custom template that goes and gets the child pages for the parent page. Then I loop through the child pages and write a tab on the parent page. This all works great, but I’d like to render the child pages layout including sidebars inside the tab. I’ve been using “get_the_content()” when I’m in the loop of my child pages, but it just renders the content of the child page, not the full layout. Is there a Word Press function or Genesis function that would render the child’s content including the sidebars as defined by that child’s layout?

    Thanks.

    • Bill Erickson says

      No, I don’t think there’s a good way to do that. You could call get_sidebar( 'primary' ); but it will be the parent page’s sidebar repeated for all the children because the parent is the primary queried object.

      You might be able to overwrite the global $wp_query with your own custom query and see if that helps. Don’t forget to run wp_reset_query(); when you’re done.