Introducing get_template_part() for modular WordPress

Why did we put the header code of the website in a separate file?

“The header code is same on every page of the site!”

Correct!

If you notice, the posts section of the Blog posts index page and archive pages look exactly the same too. This is because of the code inside the Loop in both index.php and archive.php is exactly the same.

Once we have enough maturity as a theme developer, we should start looking for the duplicate code inside our theme and modularize it to avoid some duplicate maintenance work in the future. 

So, Just like the header code, let’s move the Loop code inside both index.php and archive.php to a separate file.

WordPress allows us to create modular template parts by providing us with an invaluable get_template_part() function.

This function is similar to get_header(). While get_header() looks for files starting with header.php and loads them in other template files, the get_template_part() function gives us the freedom to load any kind of PHP file inside other template files.

First of all, let’s create a new directory called “parts” inside our theme directory. And inside this directory, create a file called blog-index.php.

You can name the directory and the file whatever you want. 

Here is the updated directory structure:

Next, from the index.php file, copy all the code inside the Loop to the newly created blog-index.php file.

Here is the final code for blog-index.php file:


<div class="blog-post">
    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
    <?php if ( has_post_thumbnail() ) :
        $featured_image = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'dosth-blog-thumbnail' ); ?>
        <div class="blog-post-thumb">
            <a href="<?php the_permalink(); ?>"><img src="<?php echo $featured_image[0]; ?>" alt='' /></a>
        </div>
    <?php endif; ?>
    <?php the_excerpt(); ?>
    <a class="read-more-link" href="<?php the_permalink(); ?>"><?php _e( 'Read More', 'nd_dosth' ); ?></a>
    <?php $categories = get_the_category(); ?>
    <?php if ( ! empty( $categories ) ) : ?>
        <div class="posted-in">
            <span><?php _e( 'Posted In', 'nd_dosth' ); ?></span>
            <a href="<?php echo get_category_link( $categories[0]->term_id ); ?>"> 
                <?php echo $categories[0]->name; ?>
            </a>
        </div>
    <?php endif; ?>
</div>

Next, remove the above code from both index.php and archive.php files.

And here is the updated Loop of both index.php and archive.php files after removing the above code:


<?php if ( have_posts() ): ?>
    <?php while( have_posts() ): ?>
        <?php the_post(); ?>
        
    <?php endwhile; ?>
    <?php the_posts_pagination(); ?>
<?php else: ?>
    <p><?php _e( 'No Blog Posts found', 'nd_dosth' ); ?></p>
<?php endif; ?>

Finally, put the following line of code right underneath the the_post() function call inside both index.php and archive.php files.


<?php get_template_part( 'parts/blog', 'index' ); ?>

And if you now check out the “Blog” page and archive pages in the browser, everything works as usual.

Anyway, here is how the get_template_part() function works.

This function accepts two parameters called $slug and $name

For example, if you are trying to load a file called comments.php, you only have to provide the $slug parameter like this:

<?php get_template_part( 'comments' ); ?>

But, if you are trying to load a file called blog-index.php have to provide both the $slug and $name parameters like this:


<?php get_template_part( 'blog', 'index' ); ?>

See? We are not including the .php extension.

Also, you can not load the file name that has an underscore( _ ) in it, for example: blog_index.php, it just doesn’t work! So make sure to only hyphens in the filenames.

Anyway, if you are trying to load a file from a sub-directory of your theme, you have to prepend the sub-directory name before the slug:

For example, in our case, inside our index.php file, we are trying to load the blog-index.php file that is located inside a sub-directory called “parts”:

parts/blog-index.php

So, we are prepending the directory name before the slug:

<?php get_template_part( 'parts/blog', 'index' ); ?>

Easy, right?

Also, if the directory name and the slug portion of the file name are same, for example, if you are trying to load the following file:

content/content-page.php

You can simply combine the directory name and slug like this:


<?php get_template_part( 'content', 'page' ); ?>

Similarly, if you are trying to load the file whose directory name and the file name is the same, for example:

content/content.php

You can include it in the following way:


<?php get_template_part( 'content' ); ?>

get it?

In fact, if you open up the latest default theme that comes with WordPress, this is what You’ll see.

Important Note: You can load the same template part any times in the same file. The get_template_part() function uses PHP’s require instead of require_once

That’s all. That’s pretty much how you can modularize template parts in WordPress.

In the next lesson, we will see how to modularize Dynamic Sidebars.