Building archives page for custom post types

In WordPress, you can view the archive page of a particular post type by putting the post type ID at the end of URL:

http://localhost:8888/dosth/{post_type_id}

For example:

http://localhost:8888/dosth/dosth_reviews

But when registering a post type, if you have specified the “rewrite” argument with the “slug” as its sub-argument, WordPress will use the slug for the archive instead of post type ID

So, you can no longer access the archive of the custom post type by using its post type ID, instead, you have to use the slug you have provided for the rewrite argument.

http://localhost:8888/dosth/{slug_of_the_post_type}

In the case of our “dosth_reviews” custom post type, we have provided “reviews” as the slug.

So, the archive URL is:

http://localhost:8888/dosth/reviews

Common, let’s open the above URL in the browser to check out reviews archive.

And Bang! 404 page.

We did not create a template file for 404 error page. So, as usually, WordPress is using the index.php file to render it.

Anyway, For some reason, WordPress doesn’t know about “reviews” slug yet!

The reason behind this is, whenever we change the default URL structure of a page, post or even custom post type, we have to flush the rewrite rules.

In our case, the default URL structure for the archive of our “dosth_reviews” post type is:

http://localhost:8888/dosth/dosth_reviews

But, we have changed it to:

http://localhost:8888/dosth/reviews

So, we have to flush the rewrite rules for WordPress to take this change into effect!

You can achieve this in a number of ways, but the easiest way is clicking on the “Save Changes” button on the Permalinks screen of the admin dashboard.

So, go to Admin Dashboard -> Settings -> Permalinks

And click on the “Save Changes” button at the bottom of the page.

If you now go back to the browser and refresh the same URL, you’ll see the archive of reviews.

http://localhost:8888/dosth/reviews

Neat, isn’t it?

However, We don’t want our Reviews archive page to look like our blog, isn’t it?

So, let’s create a template file specific to the “dosth_reviews” post type.

If you take a look at the WordPress Template Hierarchy,  It is clear that all we have to do is create an archive template file in the following naming format:

archive-{post_type_id}.php

Remember, always keep WordPress Template Hierarchy as reference.

Alright, switch back to the code editor and create a template file called:

archive-dosth_reviews.php

And put the following code in it:


<?php
/**
 * The template for displaying archive of Reviews
 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package Dosth
 */
get_header();
?>
<div class="content-container">
    <h1 class="page-title"><?php the_archive_title(); ?></h1>    
    <div class="reviews-container">
        <div class="nd-dosth-reviews">
            <?php if ( have_posts() ): ?>
                <?php while( have_posts() ): ?>
                    <?php the_post(); ?>
                    <div class="review">
                        <blockquote>
                            <?php the_content(); ?>
                            <footer>
                                <cite><?php the_title(); ?></cite>
                                <span class="review-from">
                                    <?php printf( __( 'from %s', 'nd_dosth' ), get_field('source') ); ?>
                                </span>
                            </footer>
                        </blockquote>
                    </div>
                <?php endwhile; ?>
                <?php the_posts_pagination(); ?>
            <?php else: ?>
                <p><?php _e( 'No Reviews found', 'nd_dosth' ); ?></p>
            <?php endif; ?>
        </div>
    </div>
</div>
<?php get_footer(); ?>

Again! Nothing new in the above code. I copied the entire code from archive.php file and removed:

  1. Sidebar
  2. Bootstrap HTML container

That’s all. 

And I stole the Loop code from the parts/reviews.php file and removed the class called “make-it-slick” from the “reviews-container” div element.

Everything else is the same.

The the_posts_pagination() the function will work for custom post types too! Seriously, any custom post type.

And It works great! How convenient?

Also, this time, I wrote a modular CSS for reviews. No matter where you display them on the site, the reviews will always look the same.

“Hey! I don’t really like the word Archives in the heading, is there any way to remove it?”

Oh, yeah! Nice question. 

Yes! There is a solution. Currently, we are using the_archive_title() function to output the title of our reviews archive.

Go ahead and replace the_archive_title() with:


post_type_archive_title();

Note: This function only works the custom post type archives. Not for the default archives like category, tag, etc.

Here is updated code for archive-dosth_reviews.php file:


<?php
/**
 * The template for displaying archive of Reviews
 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
 *
 * @package Dosth
 */
get_header();
?>
<div class="content-container">
    <h1 class="page-title"><?php post_type_archive_title(); ?></h1>    
    <div class="reviews-container">
        <div class="nd-dosth-reviews">
            <?php if ( have_posts() ): ?>
                <?php while( have_posts() ): ?>
                    <?php the_post(); ?>
                    <div class="review">
                        <blockquote>
                            <?php the_content(); ?>
                            <footer>
                                <cite><?php the_title(); ?></cite>
                                <span class="review-from">
                                    <?php printf( __( 'from %s', 'nd_dosth' ), get_field('source') ); ?>
                                </span>
                            </footer>
                        </blockquote>
                    </div>
                <?php endwhile; ?>
                <?php the_posts_pagination(); ?>
            <?php else: ?>
                <p><?php _e( 'No Reviews found', 'nd_dosth' ); ?></p>
            <?php endif; ?>
        </div>
    </div>
</div>
<?php get_footer(); ?>

And here is the output in the frontend:

Cool, right?

The thing is, you have to do a good amount of research on the web for a reliable solution.

Most of the time, StackOverflow is going to be your best friend forever.

“Also, I want to remove the default words from the archive page titles.”

Did you mean the words like “Category:” from the category archive page title?

“Yep! That’s right!”

Alright! It’s easy. 

We will do that in the next lesson.