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(); |
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(); |
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(); |
Ajay says
Hello,
I am working on a project with Genesis theme, your post is really helpful for me.
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
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.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?
Bill Erickson says
You can use the `genesis_do_breadcrumbs()` function to display breadcrumbs wherever you like.
Nathan says
lol, I thought I had to hook it… that makes sense. Thanks, Bill!
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
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.
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.
Daniel Emerson says
That did the trick! Thanks for your time Bill, I really appreciate it.
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.
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
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!
David Hedley says
Sorry Bill, my comment stripped out the word ‘article’.
Bill Erickson says
Yes, I’d recommend using the genesis_before_footer hook, that’s the simplest approach. Alternatively you could follow the approach listed above where you remove genesis(). Inside the be_content_area hook, you could add your own
<article>
as a full width section, with full with sub-sections. Something like this: https://gist.github.com/billerickson/bc31346186d0b43b9f5090205cb1c29dDavid Hedley says
Great, thanks Bill…