Fun with template tags: header, footer, sidebar, and template_part

Yes, does look like a lot but they all share a few things in common. Not just the fact they have a do_action before the file is loaded but they also use locate_template in order to load the file.

The functions look fairly similar:

function get_*( $name ){
	do_action( 'get_*', $name );

	$templates = array();
	$name = (string) $name;
	if ( '' !== $name )
		$templates[] = "*-{$name}.php";

	$templates[] = '*.php';
	locate_template( $templates, true );
}

The slight difference is get_template_part.

function get_template_part( $slug, $name ){
	do_action( "get_template_part_{$slug}", $slug, $name );

	$templates = array();
	$name = (string) $name;
	if ( '' !== $name )
		$templates[] = "{$slug}-{$name}.php";

	$templates[] = "{$slug}.php";
	locate_template( $templates, true, false );
}

Now, what’s pretty neat is that you can hook to these template tags. Let’s say we wanted to break down our header file into sections. For example, a header file that looks little like:

</head>
<body <?php body_class(); ?>>
<div class="site hfeed">
<?php get_header( 'nav' ); ?>
<?php get_header( 'featured' ); ?>

Let’s say we wanted to add some widgets before the navigation area. Some would create a child theme, some would edit the file directly, while we will use a hook. Some code will go along way. Take the following snippet for example.

add_action( 'after_setup_theme', 'reg_newbar' );
function reg_newbar(){
    register_sidebar( array(
        'name'          => __( 'Extra widget area', 'text-domain' ),
        'id'            => 'above-nav',
        'description'   => __( 'Displays above the top navigation area.', 'text-domain' ),
        'before_widget' => '<aside id="%1$s" class="widget %2$s">',
        'after_widget'  => '</aside>',
        'before_title'  => '<h3 class="widget-title">',
        'after_title'   => '</h3>',
    ) );
}
add_action( 'get_header', 'my_new_widget_area' );
function my_new_widget_area( $name ){
	// display the sidebar if header-nav.php
	echo '<div class="widget-area">';
	if( 'nav' == $name ){
		dynamic_sidebar( 'above-nav' );
	}
	echo '</div>';
}

Let’s walk through it a little bit. The first thing we do is create an action hook in order to register our new widgetized area. The callback function reg_newbar does this for us. Fairly simple, right? The next hook is the get_header part. Now the cool part is that if you hook to a specific template being loaded. What this means is you can add something above the get_header() calls.

Lets’ take the above example. I’ve created a header-nav.php file that simply uses wp_nav_menu and above that will create a widget area. We will use a child theme to create an additional widget area. The markup will be:

<body class="post single post-13">
<div class="widget-area">
    <!-- any widgets that are active in the above-nav area -->
</div>
<!-- header-nav.php file -->

I’ve include a few comments to show what happens and how. The thing to remember is that any code you add without checking will load before the template file is loaded. So let’s say we added a random <span> tag like:

add_action( 'get_header', 'my_new_widget_area' );
function my_new_widget_area( $name ){
	echo '<span>I will appear before all <code>get_header()</code> calls<span>';
	// display the sidebar if header-nav.php
	echo '<div class="widget-area">';
	if( 'nav' == $name ){
		dynamic_sidebar( 'above-nav' );
	}
	echo '</div>';
}

So in the above it will appear like:

<span>I will appear before all get_header() calls<span>
<!html>
<!-- head stuff -->
<span>I will appear before all get_header() calls<span>
<!-- header-nav.php -->
<span>I will appear before all get_header() calls<span>
<!-- header-featured.php -->

Pretty cool right? Cool part is that you can enqueue styles and scripts that way as well. Let’s take a look at a little more complex sample, yeah?

// in the index.php file
get_template_part( 'content', get_post_format() );
// in the functions.php file
add_action( 'get_template_part_content', 'gallery_stuff', 10, 2 );
function gallery_stuff( $slug, $name ){
	if( is_singular() && ( $name == 'gallery' ) ){
		wp_enqueue_script( 'gallery', get_template_directory_uri() . '/js/gallery.js', array( 'jquery' ), '', true );
		wp_enqueue_style( 'gallery-ui', get_template_directory_uri() . '/css/gallery-ui.css' );
	}
}

That code should be fairly simple and self-explanatory. All it does is create a hook get_template_part( 'content' ), checks if the get_post_format is gallery and if it is singular. If these are true then we will add the gallery script and CSS to the enqueue list. Even cooler is being able to add depending on the format:

get_template_part( 'content', get_post_format() );
// in the functions.php file 
add_action( 'get_template_part_content', 'jc_post_format_extra', 10, 2 );
function jc_post_format_extra( $slug, $name ){
	switch ( $name ):
		case 'gallery':
			if( is_singular() ){
				wp_enqueue_style( 'gallery-ui', get_template_directory_uri() . '/css/gallery-ui.css' );
				wp_enqueue_script( 'gallery', get_template_directory_uri() . '/js/gallery.js', array( 'jquery' ), '', true );
			}
			break;
		case 'link':
		echo 'Neat little find: ';
			break;
		case 'status';
		echo  "Totally feeling:";
			break;
		default:
		echo 'Post:';
	endswitch;
}

In the above we use a switch statement to our advantage. The reason for the above example is that line 1 is used by many themes that base their start from _s. If you really want to extend the post format support then by all means use the above code and expand on it. In fact, I highly encourage you to do it.

Published by

Jose

Born in El Salvador. Loves to read, write, draw, paint, build, test, typography, hike, photography, art, design, sewing, and many other things.