Full Width Landing Pages in Genesis

A lot of sites I’ve developed recently use a full width approach for their homepages and landing pages. Examples: OutboundEngine, Bloomfire, Informal Cowboy, and WebAssign.

On pages like this, Genesis outputs a lot of markup you don’t need, like 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

genesis intermediate

Receive New Posts by Email

Comments

    1. This snippet is missing a comma after “footer-widgets”
      add_theme_support( ‘genesis-structural-wraps’, array( ‘header’, ‘footer-widgets’ ‘footer’ ) );

        1. Hey Bill,

          Thanks for writing about this…great way do this!

          Just a heads up, the comma is fixed in the first set of code, but missing from the full snippet on line 43.

  1. Great tutorial and great way to clean up the code. Makes completely sense to remove all that mark up. I have made a few full width landing pages but never thought to do it like this.

  2. Thanks a lot Bill.
    Why I never use this way before. You’re right, for a custom home page, without widget, that’s the best way, very clean.

  3. Thank you for sharing this Bill!
    I am so glad I came across your blog. Very helpful! Its not easy to find a WordPress pro.
    Well done.

  4. That’s a great approach Bill,
    I never thought about not using the genesis() function in a Genesis page template before now… Food for thought!

    Thank you.

  5. Hi Bill,

    I am working with full width images in Genesis where the image needs to load as either the featured image for the page/post or as a custom field. I think I have that part worked out but the image also needs to have text over it and be responsive where it doesn’t resize when it goes down to mobile but rather the sides need to crop. Not doing parallax on these either. I found a solution here (http://www.minimit.com/articles/solutions-tutorials/fullscreen-backgrounds-with-centered-content) that uses Javascript to get the image width and height and it centers the text. But it seems like a lot of hoops to jump through and I’m wondering if there’s a more elegant solution. On the Bloom Fire website (http://bloomfire.com/) you did what I am trying to do with the full width image at the bottom. I’m curious what your approach was for that.

  6. Hi Bill,

    I would like to ask about how the contents are placed? They are HTML + Content inside WordPress editor?

    Currently I am a fan of Visual Editor but my problem is the boxed layout of Genesis, and I want a full-width container.

    Regards,

    Patrick

  7. Hey Bill

    This is great! Are you using some kind of A/B testing for the landing pages or are the clients using something? I always thought that one could use a Genesis theme for a landing page fairly easily, it’s just the A/B testing I was unsure about.

    Thanks

    Todd

  8. Hi there, Bill:

    Firstly, I wanted to thank you for posting this. Much appreciated. My associate wants me to use Divi [insert favorite curse word here] because of creating full width content, so this article has given me some ammunition in my argument to stay with genesis.

    Also, I hope you will pardon the interruption. I had a couple of questions about some of your earlier posts. I would have responded in them, but commenting isn’t allowed in those posts. So, since I can’t post a question there, I hope you won’t mind if I ask you in this thread.

    Basically, in 2011, you wrote a turtorial on art of the blog on Building a Genesis Child Theme ( http://www.artofblog.com/building-a-genesis-child-theme/ ).

    Before I start digging through it, is that still the way you do things nowadays? Is there something you would change in your method today?

    With the release of WP 4, Geneis 2 and the prevalance of html5, I just wanted to know if you have updated the way you would build a genesis child theme. Maybe you have a more recent post somewhere on this?

    Or is all the information in that post from 2011 still applicable today?

    Thanks in advance, and sorry for taking this off course a bit.

    1. For the most part that’s still my workflow. I’ll usually work page-by-page, first building all the functionality for that page, then styling it. I also start from the most general pages and work my way to the more specific. This way my development matches the cascading styles (first I build site-wide styles, then page-specific ones).

      I usually start every project by building a Style Guide page. This lists all the styles the client can use through the main WordPress editor. It also shows any site-wide features, like call to actions or page-specific headers. I’ll build the functionality, then style this page.

      Then I move on to the blog archive and blog single pages. Then any specific page templates required, and finally finish with the homepage.

      I have a newer base child theme but it isn’t publicly available. It’s very similar to the old, public one (BE Genesis Child) except it has the theme_support for html5 features and an updated stylesheet that targets the HTML5 elements (I started with the Genesis Sample theme’s stylesheet and made a few modifications).

      1. Thanks so much for the updated information.

        So for someone like myself – who normally uses third-party plugins and edits the child-theme style sheet, it would be best to familiarize myself with the Geneis 2 Sample theme first, and then eventually look at your public Be Genesis Child to learn how you extended the functionality.

        Then follow the work-flow you outlined in your reply above (i.e., general functionality and styling to more specific functionality and styling).

        Thanks again for all your help and for your wonderful tutorials.

  9. Those sites are gorgeous. I’ve heard so many good things about genesis but have avoided using it because creating pages this nice always seem to be so difficult. You may have just inspired me to try again 🙂

  10. Bill, thanks for sharing. Using this template, won’t you miss the schema markup for the “mainContentOfPage” ? Correct me if i’m wrong or if it’s not really a problem. That’s exactly what i was looking for.

    1. Correct, the schema markup wouldn’t be applied to it. In this case I’d add the schema markup to .site-inner instead. Look in /genesis/lib/functions/markup.php for the genesis_attributes_content() function. Copy this over to front-page.php (or whatever file you’re using for the above implementation), delete the blog and search microdata, then change the filter’s hook from ‘genesis_attr_content’ to ‘genesis_attr_site-inner’.

  11. “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.”

    Building a template like this means you need to edit the front-page.php file directly if you add your markup code between the header and footer lines. I have read that it is frowned upon to edit the wordpress template.php files directly, do you agree with this? Or does using hooks offer more flexibility?

    Personally I don’t mind editing the template.php file directly in wordpress, especially for custom sites. My concern is the user of the website, if I sell a theme for example, I’d want to make it simple for them to edit the front landing page if they wished too.

  12. Hi Bill,

    Thanks for this awesome article about creating a custom full width template in genesis.

    I’m just wondering, how can i check pages if its using a full width or not template? Im creating a custom function and want to hook it up on every page that use the full width template and i cant seem to find any info about this.

    1. Well the simplest solution is to place your function in the custom page template you make, so it only runs whenever that template is being used.

      Alternatively, you can use the get_page_template_slug( $post_id ) function in WordPress.

        1. It will only return something if you’re using a page template. You said you’re using the default page template (so no page template), so it is properly not returning anything.

          If you’re looking for the genesis layout (ex: full-width-content), use genesis_site_layout()

  13. Hi Bill,
    Thank you very much for this tutorial and all the great stuff in your blog.
    I would like to ask you something about OutboundEngine website you have mention since I am trying to achieve the same layout with Genesis.
    The content there flows like this

    <div id="flex-content-0" class="flex content-image content-left color-light"……..

    <h2

    So, I would like to ask you if you have used a plugin to generate <div id="flex-content-…. or it is a custom HTML cosing in each page.

    Also what would be your opinion on the best way to add featured pages in as a grid on the front page. I am trying to promote three pages on the front page and look like bloomfire's Our Leadership section.

    Thanks in advance.

    1. I’m using Advanced Custom Fields to manage the fields in the backend, and a custom coded template file for outputting the display. See the Flexible Content section of this post for more information.

        1. When editing the front page, have a metabox that lets you select pages. ACF has a page link field which works well for this. It stores the pages as an array of page id’s, so just loop through them in your template and build the grid.

    1. The only thing I can think of that would cause that is having one too many </div>’s in your first function.

  14. Bill this seems great but I am a bit confused and am wondering you might have any advice on a project I am working on. I need to accomplish something like you achieved here: https://bloomfire.com where there are full width sections within the main content area and other parts are not full width. It’s driving me nuts trying to figure out how to achieve this. Any help would be greatly appreciated.

    1. That’s exactly what this tutorial guides you through – creating full width content areas. What specific issue are you having?

  15. Bill,

    I wanted to give a genuine THANKS! for your code guides, Bill, especially this one. I’m embarking on my own design journey here, and I wouldn’t be where I’m at without the help of experts like yourself, Chris Coyier @ https://css-tricks.com, and Brad Dalton @ http://wpsites.net. Thanks so much for the help, guys!

    Best,

    Sean

  16. Thanks for this- I’ve already used it in several projects. I’m just wondering- in the dashboard of the actual page, would you leave the content box there? Wouldn’t it make sense to use that box for some of the content (text)?
    If I would want to use that box for some of the home page text- how would that be included into this new template? I tried add_action (‘genesis_entry_content’, ‘genesis_do_post_content’); but nothing registers..

    Thanks!

    1. I usually remove the editor from the backend and use a metabox for managing all the section’s content for two reasons:
      1) A single interface (metabox) is easier to use than multiple interfaces (editor + custom metabox)
      2) No one section in the design is obviously “the content”.

      But if your design does have an obvious single content area, then yeah, use the editor in the backend and insert the main page content on the frontend.

      The reason the code you’re trying isn’t working is that you’re using a hook that doesn’t run on this page. We removed the genesis() function, so all the genesis hooks are not running. You’ll want to use the new hook, be_content_area. Also, you’ll probably want to create your own function for it since you’ll need wrapping HTML. Ex: https://gist.github.com/billerickson/6873322915ea8a63015b

  17. Great post Bill. If I want to add the page content from the editor into be_content_area would I just use the_content(); or is there a more complete/correct way to call it in Genesis?

      1. Hi Bill, do you have any thoughts on how best to use this layout on an entire site, whilst keeping any other important markup in such as .article and .entry-content? Would I just use genesis(); and leave all the standard WP markup in then re-size .site-inner in my CSS, or are we still able to filter out any unwanted markup to achieve this in a more cleaner way? Thanks

        1. Why would you need the .article or .entry-content classes? You can add them if you like but they aren’t important. The schema data is what’s important and that has been added back.

          Another approach is to leave all the Genesis markup as-is and treat .site-inner as a single section of the page. You can then hook additional sections in before it (on genesis_after_header) or after it (on genesis_before_footer). For instance, if you were simply adding another full-width section with a contact form before the footer I’d just hook it to genesis_before_footer.

          The above approach should only be used for multi-section pages where all of the sections are of equal importance. That’s why we’re applying the schema attributes from .entry to the entire .site-inner.

  18. The only reason I would leave .entry-content is because a lot of my css is relative to .entry-content. This could be changed on a new project but on something existing I was hoping to keep that in place. I thought there may be away to leave .article class=”x” and .entry-content in.

    I do currently use the genesis_after_header hook on some projects but always seem to get validation warnings about the position of section headings so assumed this was not the ‘best practice’ way to do it if all content is equally important.

        1. No, I don’t see a value in using <article> over <div>, but you can use it for consistency with the rest of your website.

  19. In your two examples, the be_site_inner_attr function has different contents. Is there a reason for that, or did you perhaps update one of them and forget to update the other?

    1. Fixed it! Yeah, I had updated the first one but forgot to update the second. Previously I was manually specifying the schema. Later I changed this to automatically use whatever schema was supposed to be on .entry. This way if schema requirements change and Genesis is updated, this area also gets the updated schema.

  20. Hey Bill, thanks for taking the time and writing this article. A noobie like myself can always learn from the pros.

  21. Thanks for the tip. I’ve been looking to make landingspages for my websites, so I need this (or genesis dambuster plugin that seems to do something like this too). After having a clean slate like this, the landingspage or frontpage of course must be constructed.

    The genesis themes I have looked at seem to favour widgetized page templates for that, in stead of pagebuilders or shortcodes like non-genesis themes. Is that your follow up solution too, or just custom coding the page in the text editor using classes?

    It seems to me that using widgets for landingspages beside the frontpage would mean having a lot of widget area’s and a page widgetizer plugin or a specialised template for every landingspage. So a wysiwyg/drag&drop pagebuilder comes to mind as a convinient and flexible solution. I’m thinking perhaps beaver builder or a more specialised plugin like optimizepress that can a/b test and optin too. What is your position on that?

    I will keep reading and learning. Your website is a great source. Thanks for that.

    Cheers, Hans

    1. I think widget areas should only be used for site-wide (or section-wide) content, like a sidebar or footer. Page-specific content should all be on the “Edit Page” screen.

      For the most part I avoid shortcodes. If I do plan to use shortcodes, I use Shortcode UI to improve their usability in the visual editor.

      When I’m building landing pages, I always use a custom metabox so that all the relevant fields are easy to manage. For instance, for this website here is what the backend looks like: https://cl.ly/371o1H112J2G I’ll either use CMB2 or ACF depending on the requirements.

      1. Thanks for the tips and pointers, Bill. I like what your saying about widgets and shortcodes and agree with that. On another website I work with a premium theme that uses a lot of shortcodes, and the css isn’t that good, so they let you add “clear: both”-divs and whitespace before headings and so on to get it right. I don’t like that at all. However the result, it means making too large a commitment to that specific theme and gives no wysiwyg experience, even though just like page builders it enables a lot of more advanced display elements like counters and accordeons. Having forms to build the shortcode gives no help when it has to be changed also, and they let you enter the post-id’s for some shortcodes too.

        I very much like your lean and user friendly solution, although it requires some skills to set up (I don’t know yet how to add those tabs-layout and an upload-button for media in the backend f.i.). I have looked at the FrontPage of your website too, and saw how focused and clear it is, with social proof and such. It’s a great way to pre-select your audience, when you know how and have a clear offer. I learn a lot from that kind of examples. 🙂

        On the other hand your metabox-solution seems to be a commitment too, to a specific page-design and structure, and needs coding skills every time the page structure has to change, f.i. when new fields need to be added. So perhaps there is room for a method that uses advanced wysiwyg-editing, like Beaver Builder does or Live Composer. At least if they get it right and are able to build a lean and fast loading result on the frontend of the website. In that way they would enable more flexibility, testing and prototyping without the need of coding skills.

        Beaver builder even seems to do some things within the scope of what you say. At least, as I understand it now, Beaver Builder puts (a copy of) the basic pagecontent in the post itself, so it will stay available when BB is disabled or deleted.

        I don’t know if they use shortcodes without showing them, but after deactivation there are none visible. I’ve read somewhere they use meta and generate minimized css to store the page and present it in a lean way. And one gets some prebuild page templates to get started.

        I will surely use try your method, with many thanks for sharing. I hadn’t seen such a solution yet. And perhaps I will try out Beaver Builder too, and see how that works. Thanks for being generous with your knowledge. Much appreciated.

  22. 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

  23. 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!

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

  24. 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?

  25. 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

  26. 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

  27. 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

    1. 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.

  28. don’t think

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

    is needed anymore, Bill.

  29. 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

  30. 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!

Leave a comment