One of the great things about WordPress is the template hierarchy. Basically WordPress looks for certain templates by name under specific page loads. Confused? OK, I’ll give an example. When the first page on your site is loaded (the front page) WordPress goes through some checks to see what page is being requested then which page should be delivered, then which template to use. It goes something like this.
- URL request for front page of site
- Check Database options to see if static page should be loaded or the latest posts
- If Static Page check these templates in order, load first template found
- front-page.php
- Custom Page Template defined in page options
- page-$slug.php
- page-$id.php
- page.php
- index.php
- If Latest Posts check these templates in order, load first template found
- font-page.php
- home.php
- index.php
You can see a really good info-graphic showing how all of this works in the WordPress Codex Article for the Template Hierarchy.
What does all of this have to do with a better home page?
Yep, you are one of those get to the point people. I can respect that. If you notice in the example I gave, front-page.php is the first file that WordPress looks for and the only file it looks for other than index.php for latest posts or a static front-page. Now, I often get asked in the forums “how can I keep the sidebars for the home page when I show a static page for my front page?” This question is especially prevalent in themes like Streamline 2.0 that show the latest posts below some custom home page sidebars.
Now you could create a custom page template and do all kinds of other jiggery things, or you can simply change the name of the home.php file to front-page.php.
If you do that with Streamline 2.0 (that is the theme I’m using on this site) and you select a static page for the front page, you will get the 4 custom sidebars to show up then the static page content. It’s like magic. Really sweet WordPress magic. mmmmmmmm
When should I use home.php
Well, I have heard that Otto of WordPress said never to use the home.php file. I don’t know if that is true. I tried finding the source but it doesn’t seem to be on his blogs or in the Codex. Admittedly, I only looked for like 10 minutes, but that is long enough to say I doubt he said “never ever under any circumstances use home.php.” Personally I think home.php makes sense in a few cases.
Fully Widgeted Home Page
If you are cutting out the standard loop completely I think you should use home.php. Otto might disagree with my on this point, but with the Genesis themes you are making your client/end user work harder if they want to switch to a static front page if you use front-page.php in this case. If you are putting the standard loop or grid loop in, then sure, use front-page.php, but if there is no way to show the static page content outside of a widget, use home.php. Then the users will have the expected usage of being able to show a static front page via the Reading Settings.
Customizing the Blog Page
There are times where you may want to customize the page where the latest posts are set to show. The home.php file will show on whatever page the latest posts are set to show on, so you can have a front-page.php or page template that affects a static page shown on the front page, then use the home.php file to create a template for the latest posts. This kind of scenario is something I do for clients when the need arises, but not something I have planned for any child themes. It is just the only other scenario where you really need a home.php file.
Well, there might be other times you want home.php files, but those are the two I can think of.
Better Home Page Code
While I have your attention, I get asked how to make a home page for Genesis all the time. So let’s do this thing. This page will have 3 sidebars above the content and sidebar and 4 sidebars under it. I’m only going to provide some super basic CSS, adapt the look to your needs.
Step One: Register Sidebars in functions.php file
Add this code to your child theme functions.php file. I’m registering 7 sidebars and quite frankly I want to make it as easy as possible to register a big group of them, so I’m using some fancy php to make it happen. You can certainly do it the old fashioned way as well.
$home_sidebars = array ( 'home-top-1' => 'Home Top 1', 'home-top-2' => 'Home Top 2', 'home-top-3' => 'Home Top 3', 'home-bottom-1' => 'Home Bottom 1', 'home-bottom-2' => 'Home Bottom 2', 'home-bottom-3' => 'Home Bottom 3', 'home-bottom-4' => 'Home Bottom 4', ); foreach( $home_sidebars as $id => $title ){ genesis_register_sidebar( array( 'id' => $id, 'name' => $title, ) ); }
You can also make the strings international if you need to localize it. That is a tutorial for another day though.
Making the better home page in front-page.php
Now that we have our 7 sidebars, it is time to call for them. First, make a front-page.php file and put it in the child theme directory. It goes in the same directory as the child theme style.css file. Edit the file to add this code
<?php add_action( 'genesis_before_content_sidebar_wrap', 'child_front_page_before_content_sidebar_wrap' ); /** * This function loads the three sidebars that will be used * after the content and sidebar of the front page. */ function child_front_page_before_content_sidebar_wrap() { global $paged; if( $paged >= 1 ) return; $home_sidebars = array ( 'home-top-1', 'home-top-2', 'home-top-3', ); $wrap = '1'; foreach( $home_sidebars as $id ){ if( $wrap && is_active_sidebar( $id ) ) { echo '<div class="home-top">'; $wrap = ''; } genesis_widget_area( $id, array( 'before' => '<div class="'. $id . ' widget-area">' ) ); } if( '' == $wrap ) echo '</div><!-- end .home-top -->'; } add_action( 'genesis_after_content_sidebar_wrap', 'child_front_page_after_content_sidebar_wrap' ); /** * This function loads the four sidebars that will be used * after the content and sidebar of the front page. */ function child_front_page_after_content_sidebar_wrap() { global $paged; if( $paged >= 1 ) return; $home_sidebars = array ( 'home-bottom-1', 'home-bottom-2', 'home-bottom-3', 'home-bottom-4', ); $wrap = '1'; foreach( $home_sidebars as $id ){ if( $wrap && is_active_sidebar( $id ) ) { echo '<div class="home-bottom">'; $wrap = ''; } genesis_widget_area( $id, array( 'before' => '<div class="'. $id . ' widget-area">' ) ); } if( '' == $wrap ) echo '</div><!-- end .home-bottom -->'; } genesis();
genesis() loads the framework and the two actions load the sidebars. I’m using loops for these since the code is being replicated. Because I want to only load the wrapping div if at least one of the sidebars is being used I use is_active_sidebar() to check it. The genesis_widget_area() function checks to see if the sidebar is active or not and will load the sidebar along with a wrapper div. In this case I told it to use the sidebar ID and widget-area as a class. The loop was left alone, it is a normal part of the genesis() function so the latest posts will show in the #content section if the reading settings are set to show the latest posts on the front page otherwise it will show whatever static page that is selected. It’s all super slick and down right pretty when you appreciate how simple the code is compared to what would be needed otherwise.
Style those widget areas
Right now if you use this code and don’t add any CSS it will display vertically, but we want 3 horizontal boxes at the top and 4 at the bottom right? So add this to your style sheet
/* Front Page ------------------------------------------------------------ */ .home-top, .home-bottom { clear: both; overflow: hidden; } .home-top .widget-area { float: left; margin: 20px 2%; width: 29%; } .home-bottom .widget-area { float: left; margin: 20px 1%; width: 23%; }
Now I have super simplified this to get it to work with pretty much any theme. To get borders and padding and other fancy stuff you will need to style it for that, but you also need to remember to adjust your width if you start fiddling with margins, padding, and borders.
This code can be adapted to pretty much any Genesis child theme and can be extended to include other sidebars, or even fewer sidebars fairly simply.
Paul says
Nick
The discussion you refer to happened on Google+
Here’s a screenshot of his explanation: http://min.us/mbectUAp1q
I don’t think I can link to a Google+ comment directly?
Here’s a link to the discussion:
https://plus.google.com/u/0/110334265798828836941/posts/dKtqTqDWRmT
I do the same as you, use front-page template for custom home pages, and home.php for custom blog index templates.
Sometimes I can just set a normal page as the home page if all I do is add a slider at the top. I find it’s easier for users to have a physical home page to edit.
nickthegeek says
Paul,
Thanks for the link. Looks like I was right. Otto (Samuel Wood in that link) wouldn’t say “never use home.php” but rather to use it when it should be used.
Zig says
Nick – great article!
One thing I noticed – looks like your code isn’t wrapping as quite a bit of it is cut off…at least in my browser it is.
It looks like your syntax highlighter container might be too wide.
Anyways, thanks for the clarification on when to use home vs front-page – a little more clear to me now!
nickthegeek says
The code isn’t supposed to wrap, it is intended to be easy to copy correctly. I can set it up to allow line wrapping, but that would require a flash toolbar for copying code.
Zig says
My bad! I was just trying to read it, not copy it. I copied it into a text doc and that let me read it.
Thanks again!
palPalani says
nice article!
i think, you need to change
if( $paged >= 1 )
in toif( $paged > 1 )
. otherwise bottom widgets won’t work.nickthegeek says
The pages value shouldn’t change from the top to the bottom. Did you test the code and have a problem? In my testing the code worked perfectly.
palPalani says
i just working with sample theme(localhost). i created front-page.php with your code. then i can able to see top widgets, but not bottom widgets. then i changed the condition then it works form me.
Ark says
..oh my it all sound so complicated to me! Why wouldn’t all Genesis themes have widgetized home area? ..at least my Eleven40. I tried to be open-minded and mess with code as it is suggested on http://www.briangardner.com/home-widget-area-eleven40 only to get an error that smth is wrong on 58th line .. and I had to reinstall everything.
nickthegeek says
Different theme have different purposes. It is easy to say “why can’t the all be widgeted?” when that is all you want, but when someone would rather have the grid loop, and someone would rather have regular blog posts, and someone else would rather have …. At some point someone has to write custom code to get what they want, so StudioPress creates different themes. It is understandable that you might want Eleven40 setup the way you want, but not everyone wants that. So I and other write good tutorials to try and help. If that doesn’t work I do know some good developers that are usually available for small custom projects like replacing the home page loop with a widget area.
ilona says
Nick, that is an awesome tutorial. Thank you so much. You solved three days of headache for me. I really appreciate it.
alan says
This is a very helpful tutorial – thanks so much!
One question: What tweaks would I need to make in the code to make these widgets appear WITHIN the main content section, so that any widget content doesn’t appear above or below the sidebar, but along side it where page content would normally go? I’m using the eleven40 child theme.
nickthegeek says
you would use the genesis_before_loop, genesis_loop, or genesis_after_loop hook for your action, all of which are inside the #content div so they will site next to the sidebar.
Gloria Antonelli says
Hi Nick, Thanks for the tutorial!
Found a small typo in the code.
$home_sidebars = array (
‘home-bottom-1’,
‘home-bottom-2’,
‘home-bottom-3’,
‘home-bottom-3’,
);
Last ‘home-bottom-3’, should be number 4.
nickthegeek says
Thanks, I fixed it. Funny no one caught it before.
Aditya says
Thank you so much nick…I was asking this thing to studio press support and they redirected me to you blog…..
Looking towards more great articles from you….
aditya says
My bottom widgets are not appearing I am using eleven40 theme !!!!
nickthegeek says
Thanks for commenting. This is something you should ask in the helpdesk of my.studiopress.com
aditya says
Ya first I asked this question to help desk at studio press and they told me to ask the same question in their forum.. so I done that and got reply of this link….
As I am following your tutorial to create front page it would be great why my bottom widget s are not showing up ?????
Laura says
This tutorial was a lifesaver!! I had been stuck for 3 days on home page customizations and this did the trick. It was very easy to follow and customize to fit my needs. Thank you!!!
Joy @ Five J's says
Do you have any idea at all why this code:
// CREATE NEW WIDGETIZED AREAS FOR HOMEPAGE
$home_sidebars = array (
‘home-top-1’ => ‘Home Top 1’,
‘home-top-2’ => ‘Home Top 2’,
);
foreach( $home_sidebars as $id => $widgettitle ){
genesis_register_sidebar( array(
‘id’ => $id,
‘name’ => $widgettitle,
) );
}
…would cause the Layout Settings on individual pages to be ignored? The code that seems to be causing the issue is whatever is in the first array.
If I remove both those lines in the array, leaving the array empty, the Layout Settings for the individual page are recognized and I can change the layout on a page to (for example) full width instead of the default.
I’ve swapped code from other sites that are working correctly, I’ve retyped the code, I’ve changed the names, I’ve deleted everything else in the functions file, etc, but I can’t figure out what is wrong and why that code is causing the Layout Settings to be ignored.
Any ideas at all?
nickthegeek says
It shouldn’t be affecting that unless something was left open. When I look at the code you psoted I do see some directional quotes (′) instead of the none directional quotes (‘) which would break things.
Sourabh says
Thanks for the tutorial , Nick.
Is there a simple way to make these widgets responsive, I mean, by adding any code to the ‘responsive’ section of the genesis style.css ?
nickthegeek says
Any time you set a specific width you can change that in the responsive section by using a % based width using the same selector.
Abhijit says
You are a genius! I am using the Balance theme and wanted to keep the top sidebar as is but display a static page below it instead of posts. Just copying the home.php and renaming it to front-page.php and setting the front page setting to Static page did the trick.
Thanks a lot. One question though. Does it matter if I leave the home.php file in the themes folder?
nickthegeek says
If you leave the home.php file the page you set as “latest posts,” if any page is set for that, will show the home.php file. Otherwise there isn’t an issue.