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(); |
Todd says
Thanks Bill! appreciate it
Easy Mark says
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.
Bill Erickson says
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).
Easy Mark says
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.
Bill Erickson says
Yes, that’s probably a good workflow
Adam Binder says
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 ๐
George says
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.
Bill Erickson says
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’.George says
Excellent! This is the perfect template.
Sridhar Katakam says
Hey Bill,
Any idea why the schema markup for .site-inner isnโt getting applied with this front-page.php? http://pastebin.com/raw.php?i=D4kPBVpx
Bill Erickson says
Looks right to me. Did you get it working? I saw you wrote a post about it here.
Adrian says
“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.
Bill Erickson says
In this post I’m recommending you edit the front-page.php file in your custom child theme, NOT in Genesis itself.
Jayson Antipuesto says
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.
Bill Erickson says
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.Jayson antipuesto says
Hi Bill,
Thanks for your quick respond. I only use the Default full width genesis template for my child theme.
I tried to use get_page_template_slug() function but its not returning anything. This is the code that i wrote – https://gist.github.com/anonymous/b5c07c4d9f3deb2f9abd. I would appreciate if you can help me with the code. Thanks in advance
Bill Erickson says
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()Jayson antipuesto says
Awesome, THANKS a TON! its working now – https://gist.github.com/anonymous/dbc0cf66f9681561ced5.
Thank you very much Bill, youre awesome! ๐
Ivan says
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.
Bill Erickson says
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.
Ivan says
Thanks a lot for sharing this. what technique would you recommend for creating featured pages on the front page in a grid.
Bill Erickson says
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.
Ivan says
Thanks a lot.
Jam Tangan Online says
i love that landing pages, thanks Bill!
Torben says
Hey Bill,
I was wondering why you don’t use genesis_markup and genesis_structural_wrap in your function above?
I changed your code a bit to this:
https://gist.github.com/elbsurfer/db9d9765b5b6aeed1e7a
Do you have any arguments to not do it like that?
Angie Vale says
If you are using the Genesis Accessible plugin : https://wordpress.org/plugins/genesis-accessible/ you will need to add into your front-page.php (where your “main content” starts) in order for the skip link to main content to work as the plugin normally adds this to .