Themes are a great way to showcase user content. Themes can often times add a bit of functionality to a site and that’s great! The hardest one to grasp is the use of a front page template. Yep, that can of worms. One of the common things I’ve noticed is authors creating two or more files with the same code. It hurts. The more common pattern of course is:

get_header();
	if ( get_option( 'show_on_front' ) == 'posts' ) {
        // If they want to show "Latests Posts"
		get_template_part( 'index', 'homepage' ) ;
	} elseif ( get_option( 'show_on_front' ) == 'page' ) {
        // otherwise we show the front page
		get_template_part( 'index' ) ;
	}
		
get_footer();

Or at least something close to that. They check in particular what the setting is. It’s this:

if ( get_option( 'show_on_front' ) == 'posts' ) { // code here }

That checks in particular what the user setting is. It basically says, if the user selected to use the latests post we run the following code. Usually it would be comprised of the amount of posts the user has set. Some like to show 5 post while some like showing 10. That doesn’t include stickies but I won’t get into that. That’s another can of worms not really worth opening right now.

There are several tutorials and other posts that are out there which can help you understand. One of my favorites is Chip Bennett’s on home page, front page, and templates. Really in-depth and a great starting point. If you don’t understand it, read it again. It will make sense eventually.

One thing I do find super weird is the way it checks. Not jump from the template hierarchy but in the way the query is as well. The core markup ( as of 4.3 ) is:

// @return bool True, if front of site.
public function is_front_page() {
    // most likely case
    if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
        return true;
    elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
        return true;
    else
        return false;
}

// @return bool True if blog view homepage.
public function is_home() {
	return (bool) $this->is_home;
}

It does two checks to make sure we are on the front of the site. Yeah a little odd but it does the trick. So, with that slight insight we can get a better understanding of how WordPress front-page, home, and index sort of fall into place.

Now, what can we do about it? The best method is using a filter. Yes. A filter. They are the lifeblood of any and all great themes and plugins. Use them like they are going out of style. Okay, perhaps a little extreme but they are super useful. I know that some people will be hesitant at first but once you get the hang of them and what to look for it will be a game changer for how you code.

The filter we’ll use is the get_query_template filter. This function/filter is found in the wp-includes/template file. The function is simplistic in nature and is filterable to your choosing. The code is:

function get_query_template( $type, $templates = array() ) {
	$type = preg_replace( '|[^a-z0-9-]+|', '', $type );

	if ( empty( $templates ) )
		$templates = array("{$type}.php");

	$template = locate_template( $templates );

	return apply_filters( "{$type}_template", $template );
}

So, let us break it down a little. This function accepts two arguments. The first one is required to be passed because it needs to know what file to look for otherwise it will give an error. The second one is an optional array of templates to look for. From there it will use locate_template to look first in the child theme for the file and if it doesn’t find it there it will use the parent folder to locate the template. Finally, we have our filter!

This is the fun part. In order to use the filter, we first have to know what template we would like to override. In our case it is the front-page.php; though it does something a little odd, in that it removes the - so we need to use frontpage as the template name. So the filter hook would look like:

add_filter( 'frontpage_template', 'jc_frontpage_template' );

Super simple, right? Now to write out the logic, or our callback function. In that function all we have to return is a string of where our replacement file is. Let’s say that we have a landing page that we would like to use. Just don’t forget to document that otherwise people may get confused on the unexpected behavior. In order to do so we can use something like:

function jc_frontpage_template( $template ){
	if ( is_home() ){
		get_home_template();
	} else {
		return locate_template( 'templates/landing.php' );
	}
}

Pretty sweet, right? I think so. So, go, explore those filters, break things and learn from it.