How to Create a WordPress Custom Post Types Archive
Custom post types are a great solution for publishing content that wouldn’t be shown in its best light with a default post type. This could be because the default post type lacks some custom features or fields that would make it stand out from other pages and posts. Examples where a custom post type can really make a difference include portfolios, events, albums, properties, and many more. Fortunately, creating custom post types is easier than ever, whether you prefer using WordPress plugins or code.
Besides creating custom post types, we mustn’t forget to create their archives as well. Without a custom archive template file, the content that is displayed on the archive pages is determined by your theme’s default archive.php file. This means the archives for your custom posts might appear blog-like, with key features missing for each custom post item or needlessly long sidebars with unrelated content. So, if you put in the effort to make a custom post type, you shouldn’t falter before making a WordPress custom post type archive to match. Using the information in this article, you’ll be able to edit the archive of any custom post type and realize your planned design.
How to create a WordPress custom post types archive
Before we begin, we need to mention that this article represents a coding overview of a custom post archive page. As such, it’s best suited for intermediate and advanced WordPress users. Nevertheless, we will thoroughly explain all the key points so the article will be easy to follow along. We split the main part of the article into two sections, the first explains the steps that need to be taken beforehand, and the second showcases a simple coding example of a custom post type archive. So, let’s dive in.
Understanding the prerequisites
To be able to create a WordPress custom post type archive, you need to have several things already sorted. To start, you need to register your custom post type using the register_post_type() function. When doing so, you must add at least the $post_type argument, which serves as the default slug of your custom post type. You also need to set the has_archive argument to true, to enable an archive page for this custom post type. And, to make it all work, you should put the code into a separate function and hook it onto a suitable hook. The register_post_type() function description indicates that post type registration shouldn’t be hooked before the init action hook.
To illustrate all this, we’re sharing a very basic example of how you can register a movie as a custom post type. You can see the code below.
function qode_register_custom_post_type() { register_post_type( 'movie', array( 'labels' => array( 'name' => esc_html__( 'Movies', 'your-translate-domain' ), 'singular_name' => esc_html__( 'Movie', 'your-translate-domain' ) ), 'public' => true, 'has_archive' => true, ) ); } add_action( 'init', 'qode_register_custom_post_type' );
Within it, we set the $post_type to movie, made the custom post publicly viewable, and enabled the archive page functionality. Doing this made the archive page available for us to use. This page will have your-website-url/movie (where the movie is the slug of our custom post type) as its URL. If you register a custom post type with a different slug, your URL will show the appropriate slug in place of the movie from our example.
After enabling the archive page for your custom post type, you need to create the custom code that displays content on that page. To do this properly, you’ll need to have some understanding of the WordPress template hierarchy. The appropriate template hierarchy for custom post archives is given below in descending order.
-
archive-{$post_type}.php
-
archive.php
-
index.php
This means the custom post archive page you previously enabled will show the content of the archive.php file, or the index.php file if the former isn’t present in your theme. If you are satisfied with the output of these pages, then you don’t need to code your custom post archive. But, if you aren’t satisfied, then you should create a file titled archive-{$post_type}.php and fully adapt the output of the custom post archive page. Please note, the {$post_type} part of the file name should be replaced with the slug of the custom post type you registered. Given our example above, the correct file name would be archive-movie.php.
Next, you should add the code that displays different parts of your custom post type into that file. If you aren’t sure where to start, you can copy the content of the archive.php file of your current theme and edit the code to suit your needs. Alternatively, you can use the example code we prepared for this article or modify it to better suit your site.
After creating the file and inserting the code into it, the last important step is knowing where to upload it for your archive page to work properly. In most cases, the newly created archive-{$post_type}.php file should be uploaded directly inside the directory of your currently active theme, be it parent or child. Those are the two default locations where WordPress can locate template files.
Excepting those, if you want to add the file to a subdirectory of either default location or into a site-specific plugin you created or its subdirectory, you will need additional coding. To be specific, you will need to make use of the archive_template filter hook to specify the exact path to the uploaded template file. This particular filter hook is a part of a larger, dynamical set of filter hooks called {$type}-template that allows you to specify the exact path to the template file for a given type (e.g. archive_template, category_template, home_template, single_template, etc.).
In any case, to create a WordPress custom post type archive template, you will need to know how to use an FTP client to upload a file to the server. As such, you should brush up on your knowledge of FTP if you are feeling rusty. Additionally, we recommend making a backup of your website as a safety precaution. Once you’ve done that, proceed as described below.
Creating a WordPress custom post type archive using code
For this article, we prepared an example that displays the archive page for the movie custom post type, which we covered in our tutorial on custom post types. If you haven’t read that article already, you can look at it now for a more detailed breakdown of the steps that precede making an archive page for custom post types.
After that, we can move on to the code we created. It represents the content of the archive-movie.php file, which is responsible for the display of the movie archive page—the archive page with the URL our-website-url/movie.
<?php get_header(); ?> <main id="main" class="content-wrapper"> <div class="posts-section"> <?php if ( have_posts() ) { ?> <div class="archived-posts"> <?php while ( have_posts() ) { the_post(); ?> <div class="archive-item"> <?php if ( has_post_thumbnail( get_the_ID() ) ) { ?> <div class="top-section"> <div class="movie-thumbnail"> <a href="<?php the_permalink(); ?>"> <?php the_post_thumbnail( 'large' ); ?> </a> </div> </div> <?php } ?> <div class="bottom-section"> <div class="movie-title"> <a href="<?php the_permalink(); ?>"> <h3><?php the_title(); ?></h3> </a> </div> <?php $excerpt = get_the_excerpt(); $excerpt = _substr( $excerpt, 0, 100 ); $short_excerpt = _substr( $excerpt, 0, strrpos( $excerpt, ' ' ) ); if ( ! empty( $short_excerpt ) ) { ?> <div class="movie-excerpt"> <p itemprop="description" class="qodef-e-excerpt"> <?php echo esc_html( $short_excerpt ); ?>…</p> </div> <?php } ?> </div> </div> <?php } ?> </div> <?php wp_reset_postdata(); } else { ?> <div class="archived-posts"><?php echo esc_html__( 'No posts matching the query were found.', 'your-translate-domain' ); ?></div> <?php } ?> </div> </main> <?php get_footer(); ?>
Please note, when you’re copying this code, you’ll need to remove the underscore (“_”) from both instances of “_substr” to ensure that it will work properly. So your code should have $excerpt = substr and $short_excerpt = substr instead.
Now, let’s examine the composition of this code.
To start, we’ll examine it in a more simplified form. As you can see below, we displayed the header and footer using the get_header() and get_footer() functions that call the respective footer and header templates. Then, in the main part of the page, a simple WordPress Loop is displayed. Finally, if there are no movies that can be shown (for example, they haven’t been published), a message stating No movies matching the query were found. will appear.
<?php get_header(); ?> <main id="main" class="content-wrapper"> <div class="posts-section"> <?php if ( have_posts() ) { ?> <div class="archived-posts"> <?php while ( have_posts() ) { the_post(); ?> <!-- Some code here--> <?php } ?> </div> <?php wp_reset_postdata(); } else { ?> <div class="archived-posts"><?php echo esc_html__( 'No movies matching the query were found.', 'your-translate-domain' ); ?></div> <?php } ?> </div> </main> <?php get_footer(); ?>
As for the main part of the code, it displays the appropriate movie information for each published movie item. More precisely, using the code shown below, we displayed the movie’s featured image, title, and a shortened excerpt. Furthermore, both the movie title and featured image are linked to the movie’s page. The featured image is displayed in size ‘large’, which is one of the image sizes that are registered in WordPress by default. Finally, the excerpt is shown up to the last whole word before the 100 character limit and it ends with the ellipsis symbol(…). Needless to say, these three items will be shown only if you inserted them. You would do that using the WordPress interface for each movie item.
<div class="archive-item"> <?php if ( has_post_thumbnail( get_the_ID() ) ) { ?> <div class="top-section"> <div class="movie-thumbnail"> <a href="<?php the_permalink(); ?>"> <?php the_post_thumbnail( 'large' ); ?> </a> </div> </div> <?php } ?> <div class="bottom-section"> <div class="movie-title"> <a href="<?php the_permalink(); ?>"> <h3><?php the_title(); ?></h3> </a> </div> <?php $excerpt = get_the_excerpt(); $excerpt = _substr( $excerpt, 0, 100 ); $short_excerpt = _substr( $excerpt, 0, strrpos( $excerpt, ' ' ) ); if ( ! empty( $short_excerpt ) ) { ?> <div class="movie-excerpt"> <p itemprop="description" class="qodef-e-excerpt"> <?php echo esc_html( $short_excerpt ); ?>…</p> </div> <?php } ?> </div> </div>
This code represents a simple, yet helpful, example. You can use it directly or improve on it if needed. Once you create a suitable code, the archive-{$post_type}.php file (in our case the archive-movie.php file) with the code should be uploaded to the server via FTP. Whether you upload it to the directory of the theme you are currently using, or one of the other locations we discussed in the previous section is up to you. After that, you should review the results.
It is likely that the resulting display of the archive page won’t fit your site perfectly. To make it more visually pleasing and better suited to the overall design, you will need to add some CSS code for stylization purposes. However, this code is created on a case-by-case basis as it depends on the stylization rules that are already present on your site thanks to the theme you are using. As such, you will need to create the appropriate CSS code on your own.
To help you do this, we will share the CSS code we created for this article. It was created for our website, which uses the Lekker theme, so it aims to match that particular style. So, you shouldn’t copy this code for use without changing it beforehand.
.archived-posts { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -ms-flex-wrap: wrap; flex-wrap: wrap; margin: 0 -10px; } .archive-item { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; -ms-flex-preferred-size: 100%; flex-basis: 100%; padding: 0px 10px 30px; } @media (min-width: 1025px) { .archive-item{ -webkit-box-flex: 1; -ms-flex: 1 1 33%; flex: 1 1 33%; } }
When you create the CSS code that would suit your website, you need to know where to safely place it. For a wide range of WordPress users, the appropriate location would be inside the Appearance > Customize > Additional CSS section, as it is the default spot for inserting website-related CSS. However, more advanced WordPress users can opt to put the CSS into a separate file, upload it to the server, and enqueue it using the wp_enqueue_style() function. You can find more details on how to do that in our article on enqueueing custom scripts and styles.
Finally, you should now have a custom post archive page that will be perfectly adjusted to your needs. In the case of our example, you can see how the movie archive page turned out on the screenshot below.
Final Thoughts
In this article, we discussed everything you need to know to create a WordPress custom post type archive page using code. That includes registering the custom post type with appropriate arguments that enable an archive page, creating the appropriately named template file with the coding example we supplied as a starting point, and uploading the file into an appropriate location on the server. Apart from that, you will also need to insert the appropriate information for each custom post item that you want to be shown on the archive page. Finally, you will need to adjust the stylization of your new custom post type archive page so it matches the rest of your site. Given everything we covered, we are confident that you will be able to use these instructions, regardless of what kind of custom post type you create, to make an archive page for yourself. Finally, you can bookmark this article in case you need to refresh your knowledge at any point in the future.