How to Add Existing Taxonomies to WordPress Custom Post Types

This article covers how to add existing taxonomies to a custom post type, and how to make that custom post type show up in those taxonomies’ archive pages.

Last week, we debuted Courses, a new way for us to thoroughly teach topics in WordPress development. Courses are just regular old posts for now, but we’re transitioning them into being their own custom post type. This has a number of advantages, such as making it easier to have a “Courses-only” archive page.

However, even though they’ll be their own custom post type, we want Courses to make use of three of our existing WordPress taxonomies:

  1. category, WordPress’s default category taxonomy,
  2. post_tags, WordPress’s default tags taxonomy, and
  3. difficulty, a custom difficulty taxonomy that we’ve registered ourselves.

Moreover, we want Courses to mix with our other post types in archive pages. If, for example, you click “Intermediate” to find all of our content that’s at Intermediate difficulty, we want our Intermediate Courses to show up right alongside our regular Intermediate articles.

This turns out to have several steps to it. So this week, we’re going to cover how to add existing taxonomies to a custom post type, and how to make that custom post type show up in that taxonomy’s archive pages. Enjoy!

The Code

Below is the complete code we’ll be looking at today. This would be best as the only file in a standalone plugin. For more on registering plugins see our article on the topic.

// 1. Register post type add_action( 'init', 'wpshout_register_cpts' ); function wpshout_register_cpts() { 	$  args = array( 		'public' => true, 		'label'  => 'Courses', 		'has_archive'  => true, 		'rewrite'  => array( 'slug' => 'courses' ), 		'supports' => array(  			'title', 			'editor', 			'author', 			'thumbnail', 			'excerpt', 			'comments', 			'revisions' 		), 	); 	register_post_type( 'course', $  args ); }  // 2. Add existing taxonomies to post type add_action( 'init', 'wpshout_add_taxonomies_to_courses' ); function wpshout_add_taxonomies_to_courses() { 	register_taxonomy_for_object_type( 'category', 'course' ); 	register_taxonomy_for_object_type( 'difficulty', 'course' ); 	register_taxonomy_for_object_type( 'post_tag', 'course' ); }  // 3. Make Courses posts show up in archive pages add_filter( 'pre_get_posts', 'wpshout_add_custom_post_types_to_query' ); function wpshout_add_custom_post_types_to_query( $  query ) { 	if(  		is_archive() && 		empty( $  query->query_vars['suppress_filters'] ) 	) { 		$  query->set( 'post_type', array(  			'post', 			'course' 		) ); 		return $  query; 	} } 

The big takeaway is that adding taxonomies to custom post types requires three distinct steps.

The code above does three things, in order:

  1. Register the “Courses” custom post type with the necessary attributes.
  2. Add three existing taxonomies—category, post_tag, and our custom taxonomy difficulty—to the Courses post type.
  3. Cause Courses to show up in archive pages, so that a search by category, difficulty, and so on will include Courses results.

None of these three pieces is exceptionally difficult—it’s knowing that you need to do all three of them that was the big takeaway for me, and hopefully for you. Let’s look at each piece in more detail.

1. Registering Courses with register_post_type()

This section uses WordPress’s init hook to run a call to register_post_type() with a number of arguments given by an $ args array. If you’ve never registered a custom post type before, check out the Codex’s description of register_post_type() itself. The $ args-and-a-function-within-a-WordPress-hook setup is absolutely core to WordPress, and register_post_type() isn’t too hard to understand if you’re familiar with that pattern.

The one thing I want to mention is that manually including a 'supports' parameter within $ args was necessary for us. If you leave it out of $ args entirely, your custom post type has some properties by default, but doesn’t have some (like excerpts) that we wanted. And if you include just 'supports' => 'excerpts', then it’ll turn off everything else—like post titles, authors, or content. So we felt it necessary to list every standard feature we want our Courses to have:

'supports' => array(  	'title', 	'editor', 	'author', 	'thumbnail', 	'excerpt', 	'comments', 	'revisions' )

2. Adding Existing Taxonomies to the Courses Custom Post Type

This simple section uses three calls to register_taxonomy_for_object_type() to register the category, post_tag, and difficulty taxonomies for Courses. These three lowercase strings are the “slugs” for the Category, Tag, and Difficulty taxonomies. We had to look them up for Category and Tag (since those are WordPress default taxonomies), and we knew that we’d given Difficulty the difficulty slug when we’d registered it.

The end result looks like this:

wordpress taxonomies on custom post type

Click to enlarge

Credit to Pippin Williamson for this section’s basic code. As a note, Pippin recommends that you use the plugins_loaded hook rather than the init hook if you’re doing this in a plugin; however, we tried this, and only init worked for us.

3. Using pre_get_posts() to Add Courses to Archive Pages

This last piece is essential if you want users to be able to actually click, for example, “Intermediate” and see a list of all Intermediate posts and Courses. It uses a function that hooks into WordPress’s important pre_get_posts hook (which we’ll be explaining in detail soon!) to modify the query on every archive page such that both posts and courses are included.

Here is the function’s code again, with logic written in more detail as comments:

function wpshout_add_custom_post_types_to_query( $  query ) {	 	if(  		// If we're trying to generate an archive page, and 		is_archive() &&  		// If the query hasn't already been modified to ignore 		// filters like the one we're writing 		empty( $  query->query_vars['suppress_filters'] ) 	) {  		// Then set the query to fetch posts of type 		// both "post" and "course" 		$  query->set( 'post_type', array(  			'post', 			'course' 		) );  		// And return the modified query 		return $  query; 	} }

The final result (on a staging site I keep locally) looks like:

Archive page with mixed post types

Click to enlarge

(Credit for this basic code pattern to CSS-Tricks. Note that we changed their is_category() || is_tag() check to just is_archive(), which covers all types of archives pages, including, for example, author pages.)

Now You Know How to Add Taxonomies to Custom Post Types

Thanks for reading. Again, each step in this process is somewhat simple, but knowing you have to do all three was a bit of an “Aha” moment as I did this myself.

As always, we’d love to read questions or comments below!

Original Article Posted On: WPShout

Be the first to comment on "How to Add Existing Taxonomies to WordPress Custom Post Types"

Leave a comment

Your email address will not be published.