WordPress Theme From Scratch - Category.php & Tag.php

Today we are going to learn about Category.php and Tag.php as we continue this Let’s Build A WordPress Theme From Scratch tutorial series. This will be a fairly short and simply tutorial because these two template files are very straight forward. As I am sure you know by now, WordPress allows you to add categories and tags onto posts. I have already shown you how to display those on the home.php template and the single.php template. If you are actually building along with this WordPress theme tutorial you probably noticed that categories and tags are links. When you click on a specific tag or category they display all the posts that are within that specific category or tag. I’m sure you can see what is coming next.

This is the seventh article in the Let’s Build A WordPress Theme From Scratch Series.

Category.php and Tag.php

We need to build two template files that will tell WordPress how you want these filtered category posts and tag posts displayed. So if you want the filtered posts from one specific category to display as a list of titles in an unordered list, then you would use category.php to write the html to display that. If you wanted the filtered posts from one specific tag to display as a blockquote with only the excerpt you would use tag.php to write the html to display that.

To make it a little easier on myself I always build these two pages the same. I also build them to look exactly like my posts would display on my home.php template file. I do this because for the most part people like to see similar things displayed similarly. So if you are on the page that displays all of the posts from that website and then you filter the query by selecting to see only one category, you would probably want the page to refresh looking the same way but with only the posts from that category you selected. This for developers makes our process much easier because we don’t have to build each page over again. Work smarter not harder.

Let’s look at the code for each of these template files from our sample WordPress Theme.

Category.php

<?php get_header(); ?>

    <div class="wrap_1280">
        
        <div class="page-content-title-wrapper">

            <div class="wrap_1280">

                <?php if (have_posts()) : ?>

                <h2 class="page-content-title"><?php single_cat_title(__('Category Archives For: '), true); ?></h2>

            <div class="clearfix"></div>

            </div>

        </div>
        
        <div class="main-content">
            
            <?php get_sidebar(); ?>
            
            <div class="left-page-content col-lg-10 col-md-10 col-sm-9 col-xs-12">
                
                <div class="container">
                    
                    <div class="row" id="ms-container">
                        
                        <?php while (have_posts()) : the_post(); ?>
                        
                            <div class="ms-item row col-lg-6 col-md-6 col-sm-6 col-xs-12">
                                
                                <div class="blog-page-content">
                                    
                                    <?php if (has_post_thumbnail()) : ?>
                            
                                        <figure class="article-preview-image">
                                            
                                            <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
                                            
                                        </figure>
                                    
                                    <?php else : ?>
                                    
                                    <?php endif; ?>
                     
                                        <h2><a href="<?php the_permalink(); ?>" class="category-title-link"><?php the_title(); ?></a></h2>
                            
                                        <div class="category-post">

                                            <h6 class="article-meta-extra">
                                                
                                                    <?php if (has_category() && !has_category('Uncategorized')) : ?>
                                                
                                                        <?php the_category('  |  '); ?> |  
                                                        
                                                    <?php else : ?>
                                                        
                                                    <?php endif; ?>
                                                        
                                                Posted on <?php the_date(get_option('date_format')); ?> at <?php the_time(get_option('time_format')); ?> by <?php the_author_posts_link(); ?>
                                                
                                            </h6>

                                           <?php the_excerpt(); ?>

                                        </div><!-- END CATEGORY POST -->

                                        <?php if (has_tag()) : ?>

                                            <p class="tags"><?php the_tags('', ' '); ?></p>

                                        <?php else : ?>

                                        <?php endif; ?>

                                        <a href="<?php the_permalink(); ?>" class="btn btn-blue btn-block">Read More</a>

                                </div><!-- END EACH BLOG-->
                            </div>
                    
                        <?php endwhile; ?>
                        
                        <?php else : ?>

                        <article class="no-posts">

                            <h1>No posts were found.</h1>

                        </article>
                        
                        <?php endif; ?>
                        
                    </div>
                    
                </div>

                <div class="clearfix"></div>

                <div class="article-nav clearfix">
                    
                    <p class="article-nav-next pull-right"><?php previous_posts_link(__('Newer Posts »')); ?></p>
                    
                    <p class="article-nav-prev pull-left"><?php next_posts_link(__('« Older Posts')); ?></p>
                    
                </div>
                
                <div class="clearfix"></div>
                
            </div>
            
        <div class="clearfix"></div>
        
        </div><!-- END MAIN-CONTENT -->
        
    </div><!-- END wrap_1280 -->

<?php get_footer(); ?>

Tag.php

<?php get_header(); ?>

    <div class="wrap_1280">
        
        <div class="page-content-title-wrapper">

            <div class="wrap_1280">

                <?php if (have_posts()) : ?>

                <h2 class="page-content-title"><?php single_tag_title(__('Tag archives for: '), true); ?></h2>

            <div class="clearfix"></div>

            </div>

        </div>
        
        <div class="main-content">
            
            <?php get_sidebar(); ?>
            
            <div class="left-page-content col-lg-10 col-md-10 col-sm-9 col-xs-12">
                
                <div class="container">
                    
                    <div class="row" id="ms-container">
                        
                        <?php while (have_posts()) : the_post(); ?>
                        
                            <div class="ms-item row col-lg-6 col-md-6 col-sm-6 col-xs-12">
                                
                                <div class="blog-page-content">
                                    
                                    <?php if (has_post_thumbnail()) : ?>
                            
                                        <figure class="article-preview-image">
                                            
                                            <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
                                            
                                        </figure>
                                    
                                    <?php else : ?>
                                    
                                    <?php endif; ?>
                     
                                        <h2><a href="<?php the_permalink(); ?>" class="category-title-link"><?php the_title(); ?></a></h2>
                            
                                        <div class="category-post">

                                            <h6 class="article-meta-extra">
                                                
                                                    <?php if (has_category() && !has_category('Uncategorized')) : ?>
                                                
                                                        <?php the_category('  |  '); ?> |  
                                                        
                                                    <?php else : ?>
                                                        
                                                    <?php endif; ?>
                                                        
                                                Posted on <?php the_date(get_option('date_format')); ?> at <?php the_time(get_option('time_format')); ?> by <?php the_author_posts_link(); ?>
                                                
                                            </h6>

                                           <?php the_excerpt(); ?>

                                        </div><!-- END CATEGORY POST -->

                                        <?php if (has_tag()) : ?>

                                            <p class="tags"><?php the_tags('', ' '); ?></p>

                                        <?php else : ?>

                                        <?php endif; ?>

                                        <a href="<?php the_permalink(); ?>" class="btn btn-blue btn-block">Read More</a>

                                </div><!-- END EACH BLOG-->
                            </div>
                    
                        <?php endwhile; ?>
                        
                        <?php else : ?>

                        <article class="no-posts">

                            <h1>No posts were found.</h1>

                        </article>
                        
                        <?php endif; ?>
                        
                    </div>
                    
                </div>

                <div class="clearfix"></div>

                <div class="article-nav clearfix">
                    
                    <p class="article-nav-next pull-right"><?php previous_posts_link(__('Newer Posts »')); ?></p>
                    
                    <p class="article-nav-prev pull-left"><?php next_posts_link(__('« Older Posts')); ?></p>
                    
                </div>
                
                <div class="clearfix"></div>
                
            </div>
            
        <div class="clearfix"></div>
        
        </div><!-- END MAIN-CONTENT -->
        
    </div><!-- END wrap_1280 -->

<?php get_footer(); ?>

Sorting Out The Changes

There are only three things I need to point out about these two bits of code. The first thing you will notice is that the Loop has been split up just a little bit. The if statement has been separated from the while statement. This is the proper procedure on these two template files because we need to say ‘if there are posts’ and then we need to use two new functions we haven’t touched on yet. For the category.php template file we will use single_cat_title(); function which will query/display the name of the specific category that was selected/clicked on. So essentially what we want to do is have a title at the top of the page that says “Here are the posts in the BLANK category”. In the code example above I use the verbiage ‘Category Archives for: ‘. You will notice that is passed in as the first parameter. Also in the code above, I have a specified div that displays this title before the main content. You can design/style this anyway you wish. Then the Loop continues where it originally was on home.php but now starts with the ‘while’ statement. All of this also applies to tag.php except we use the function single_tag_title(); instead of single_cat_title();.

Short, But Sweet

It doesn’t take much to explain these two file templates so we are done and moving on to footer.php next week. As always, if you guys need any clarification on anything please contact me and I will be happy to explain further.

Team Treehouse – Learn PHP for WordPress

If you are serious about learning to develop custom themes in WordPress, I highly recommend you join Team Treehouse. They have a full video course on everything WordPress development, including a course on specifically writing PHP for WordPress.