Full Width Landing Pages in Genesis

Many of the websites in my portfolio use a full width approach for their homepages and landing pages. See my article on building landing pages with ACF for more information on how we build them.

On pages like this, Genesis outputs a lot of markup you don’t need. It includes divs for .site-inner .wrap, .content-sidebar-wrap, .content, .entry ….

We could remove the styling from those elements so they don’t take up any space and then stick all the site content before or after it, but there’s a better way.

Don’t use the genesis() function.

What’s the first step in creating a theme file in Genesis? You create a file that looks something like this:

<?php
/**
* EA Genesis Child.
*
* @package EAGenesisChild
* @since 1.0.0
* @copyright Copyright (c) 2014, Contributors to EA Genesis Child project
* @license GPL-2.0+
*/
genesis();
view raw front-page.php hosted with ❤ by GitHub

But what does that genesis() function actually do? If you look in /genesis/lib/framework.php, you’ll see this. To summarize, it calls get_header(), then builds the main content area, then calls get_footer().

On pages like those described above, I only want the header and footer and then I’ll take care of the main content area. So, I start with a template file that looks like this:

<?php
/**
* EA Genesis Child.
*
* @package EAGenesisChild
* @since 1.0.0
* @copyright Copyright (c) 2014, Contributors to EA Genesis Child project
* @license GPL-2.0+
*/
// Remove 'site-inner' from structural wrap
add_theme_support( 'genesis-structural-wraps', array( 'header', 'footer-widgets', 'footer' ) );
/**
* Add the attributes from 'entry', since this replaces the main entry
*
* @author Bill Erickson
* @link http://www.billerickson.net/full-width-landing-pages-in-genesis/
*
* @param array $attributes Existing attributes.
* @return array Amended attributes.
*/
function be_site_inner_attr( $attributes ) {
// Add a class of 'full' for styling this .site-inner differently
$attributes['class'] .= ' full';
// Add an id of 'genesis-content' for accessible skip links
$attributes['id'] = 'genesis-content';
// Add the attributes from .entry, since this replaces the main entry
$attributes = wp_parse_args( $attributes, genesis_attributes_entry( array() ) );
return $attributes;
}
add_filter( 'genesis_attr_site-inner', 'be_site_inner_attr' );
// Build the page
get_header();
do_action( 'be_content_area' );
get_footer();
view raw front-page.php hosted with ❤ by GitHub

I’m removing ‘site-inner’ from the structural wrap because my content will go inside .site-inner and those elements will have their own internal .wrap‘s.

You only have to do this if you’ve defined the structural wraps you want in your theme already and included ‘site-inner’. If you don’t have add_theme_support( 'structural-wraps' ); in your child theme, Genesis will add wraps to everything except .site-inner (see /genesis/lib/init.php, line 63). So you can leave this part out, but you’ll probably want to adjust the styling of .site-inner in your stylesheet.

In the Genesis Sample Theme, they exclude the structural wrap for .site-inner but apply a max-width to .site-inner (see here). You’ll want this to be 100% wide on your page template, so update your styles accordingly.

Since we’re removing the <content> element which has Schema attributes, we’ll want to add those attributes to .site-inner (thanks to Sridhar Katakam for the recommendation).

I also place do_action( 'be_content_area' ); between the header and footer lines. While you could put your template file code directly between these two functions, all my other theme files are using hooks to place functionality in the theme so I’m using it here to be consistent.

Then I build the page. All my functions are hooked to ‘be_content_area’ and go above the “build the page” area, just like you’d put everything above the genesis() function in other templates.

Here’s what it looks like once I add the rotator from WebAssign’s homepage:

<?php
/**
* EA Genesis Child.
*
* @package EAGenesisChild
* @since 1.0.0
* @copyright Copyright (c) 2014, Contributors to EA Genesis Child project
* @license GPL-2.0+
*/
/**
* Home Rotator
*
*/
function be_home_rotator() {
$slides = get_post_meta( get_the_ID(), 'be_slide', true );
if( $slides ) {
echo '<div class="home-rotator"><div class="wrap"><div class="flexslider"><ul class="slides">';
for( $i = 0; $i < $slides; $i++ ) {
$image = wp_get_attachment_image( get_post_meta( get_the_ID(), 'be_slide_' . $i . '_image', true ), 'be_slide' );
$title = esc_attr( get_post_meta( get_the_ID(), 'be_slide_' . $i . '_title', true ) );
$button_link = esc_url( get_post_meta( get_the_ID(), 'be_slide_' . $i . '_button_link', true ) );
if( $title ) {
if( $button_link )
$title = '<a href="' . $button_link . '">' . $title . '</a>';
$title = '<h2>' . $title . '</h2>';
}
$content = get_post_meta( get_the_ID(), 'be_slide_' . $i . '_content', true );
$button_text = esc_attr( get_post_meta( get_the_ID(), 'be_slide_' . $i . '_button_text', true ) );
$button = $button_text && $button_link ? '<p><a href="' . $button_link . '" class="button">' . $button_text . '</a></p>' : '';
$bg = get_post_meta( get_the_ID(), 'be_slide_' . $i . '_bg', true );
$class = $bg ? 'slide-caption white-bg' : 'slide-caption';
echo '<li>' . $image . '<span class="caption-wrapper"><span class="' . $class . '">' . $title . wpautop( $content ) . $button . '</span></span></li>';
}
echo '</ul></div></div></div>';
}
}
add_action( 'be_content_area', 'be_home_rotator' );
// Remove 'site-inner' from structural wrap
add_theme_support( 'genesis-structural-wraps', array( 'header', 'footer-widgets', 'footer' ) );
/**
* Add attributes for site-inner element, since we're removing 'content'.
*
* @param array $attributes Existing attributes.
* @return array Amended attributes.
*/
function be_site_inner_attr( $attributes ) {
// Add a class of 'full' for styling this .site-inner differently
$attributes['class'] .= ' full';
// Add the attributes from .entry, since this replaces the main entry
$attributes = wp_parse_args( $attributes, genesis_attributes_entry( array() ) );
return $attributes;
}
add_filter( 'genesis_attr_site-inner', 'be_site_inner_attr' );
// Build the page
get_header();
do_action( 'be_content_area' );
get_footer();
view raw front-page.php hosted with ❤ by GitHub

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. Ajay says

    Hello,

    I am working on a project with Genesis theme, your post is really helpful for me.

  2. Ahmad Fahrurroji says

    I’m searching about landing page for my genesis child theme and I find this post. It is so perfect for me and I want learn more about it to create the best one.

    Thanks bill

  3. Atila says

    Hello Bill, love your article! It is the look I want too. I am using Genesis sample theme. I have created a new template, and pasted in the code you provided here. However, the template does not appear when I try to select it on page/post menu (in the editor). I have also tried replacing all “be_” hooks with “genesis” but no luck there ether. Any other suggestion?

    Thanks in advance man!

    • Bill Erickson says

      You need to include /* Template Name: My Custom Template */ at the top if you want to use this as a page template.

  4. Nathan says

    Is there a method to call genesis’s breadcrumb feature within the content area (above the main content area and sidebar—typically ‘genesis_before_content’ is what I would use) when bypassing the genesis(); function?

  5. David Hedley says

    Hi Bill,

    When creating the various full-width content sections on the front page using this method, could I ask your advice on when to use the section tag and when to use a div? Also, one of these content sections will be a slider.

    Thanks!
    David

  6. Ben Blankley says

    Really useful article as usually Bill – thanks.

    To follow up on Angie’s comment earlier, as most of us (hopefully) turn on the accessibility features built into Genesis these days, is it good advice to add this:
    $attributes[‘id’] .= ‘genesis-content’;

    to the be_site_inner_attr function. That way the skiplinks will work as by default they link to an element with the ID of genesis-content?
    Thanks,
    Ben

    • Bill Erickson says

      Yes, that’s a great point. I’ve updated the code above to reflect that.

  7. Daniel Emerson says

    Hi Bill,

    I’ve been using this for a while so thank you for the tutorial. I’ve noticed after this last Genesis (2.5.1) and WordPress (4.8) update I’m getting this error on some of my sites on the home page:

    Warning: Missing argument 2 for genesis_attributes_entry(), called in /home/flysite/public_html/wp-content/themes/flysite/front-page.php on line 15 and defined in /home/flysite/public_html/wp-content/themes/genesis/lib/functions/markup.php on line 688

    If I comment out $attributes = wp_parse_args( $attributes, genesis_attributes_entry( array() ) );
    then the error goes away. I’m not the strongest PHP developer but just wanted to see if you knew what was going on.

    Thanks for your time.
    Daniel

    • Bill Erickson says

      That’s strange. The genesis_attributes_entry() function does not have a second argument.

    • Bill Erickson says

      Oh I see what the issue is. In 2.5.1 they added additional arguments to that function, and then they removed them in 2.5.2 (probably due to reported issues like this).

      Update to Genesis 2.5.2 and it should fix the issue for you.

  8. Sridhar Katakam says

    don’t think

    “`
    // Remove ‘site-inner’ from structural wrap
    add_theme_support( ‘genesis-structural-wraps’, array( ‘header’, ‘footer-widgets’, ‘footer’ ) );
    “`

    is needed anymore, Bill.

  9. Thomas Chang says

    Hello Bill,

    This is awesome tutorial. But I have one side question about the rotator part. Do you mind telling how to setup the rotator at backend, so that the code could output the slides on the front end?

    Thanks a lot,
    Thomas

  10. David Hedley says

    Hi Bill, if I wanted to create an inner page (rather than a landing page) that retained the genesis loop but allowed for a mix of full width sections and ‘structural sections, what would be the best way to achieve it? As an example, something like this: https://www.macair.co.uk/services/office-air-conditioning/. My first thought would be to hook into before_footer to add the bottom sections to the page which I’d use ACF for via custom fields, but then these will fall outside the scope of . Is there a way to inject a wrap around just the editor content but still allow full width sections created with something like ACF within the . Thanks!