A custom post type slots into the exact same template hierarchy from earlier in this section — it just extends the naming pattern with the post type's own slug.
| Requested URL | Files checked, in order |
|---|---|
| A single project | single-project.php → single.php → index.php |
The projects archive (/projects/) | archive-project.php → archive.php → index.php |
| A project_type term archive | taxonomy-project_type.php → taxonomy.php → archive.php → index.php |
<?php get_header(); ?>
<main>
<?php while ( have_posts() ) : the_post(); ?>
<article>
<h1><?php the_title(); ?></h1>
<?php if ( has_post_thumbnail() ) : ?>
<?php the_post_thumbnail( 'large' ); ?>
<?php endif; ?>
<?php the_content(); ?>
</article>
<?php endwhile; ?>
</main>
<?php get_footer(); ?>Nothing here is new — it's the same shape single.php used earlier. WordPress reaches for this file automatically purely because of its name; there's no extra registration step to make it apply only to projects.
<?php get_header(); ?>
<main>
<h1><?php post_type_archive_title(); ?></h1>
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php the_excerpt(); ?>
</article>
<?php endwhile; ?>
<?php endif; ?>
</main>
<?php get_footer(); ?>post_type_archive_title() is the post-type equivalent of the_title() for an archive listing — it outputs the plural label set back in CPT UI ("Projects"), without hardcoding it into the template.
Requires "Has Archive" to be on
This file is only ever used if Has Archive was enabled for the post type in CPT UI. If it was left off, /projects/ doesn't exist as a route at all, and this file sits unused — worth checking that setting first if an archive page seems to be missing.
With content types, taxonomies, and their templates all working, this closes out the CPT UI part of the section. From here, the focus shifts to giving those content types real structured data beyond a title and a body — Secure Custom Fields.