The lack of advanced permalink customization tools in the WordPress core is one of its biggest shortcomings. One limitation is the inability to include category slugs in custom post type permalinks.
Although you may easily add a category to the permalinks of built-in posts, custom taxonomies and post types do not allow it by default.
Adding a custom taxonomy slug to a custom post type's URL is not that straightforward. If you know how to code, you may do this by adding more rewrite rules with PHP code snippets. However, implementing this may not be the easiest option for typical WordPress user.
Instead of writing code yourself, a ready-made plugin like Permalink Manager can provide an out-of-the-box solution. This would make adding taxonomies to custom post type URLs much easier.
How to Add Custom Taxonomy in Custom Post Type Permalink?
Before we continue, have a look at the following sample to see how the plugin might help you in rearranging your permalinks. The below example has been simplified on purpose to clearly demonstrate how it works.
Original WordPress permalinks (custom post type items)
http://example.com/product/%product%
http://example.com/product/cotton-t-shirt/
http://example.com/car/ford-focus/
New permalinks item customized with Permalink Manager (custom post type items with tax slugs included)
http://example.com/%product_cat%/%product%
http://example.com/calvin-klein/tops/t-shirts/cotton-t-shirt/
http://example.com/diesel/ford/ford-focus/
The procedure is straightforward, and you should have no difficulty completing it. If you want to include custom taxonomy slugs in your WordPress permalinks, you'll need to go to the Permalink Manager section ("Tools -> Permalink Manager -> Permastructures").
Now, scroll down until you find the custom post type that you want to adjust. In this simple example, we are adding two taxonomies to the permalinks for the "Cars" post type ("Manufacturer" and "Fuel").
After that, you should insert the tags into the permastructure. The names of custom taxonomies are also the permastructure tags. If necessary, you may locate all of the possible permastructure tags in the "Permastructure tags" section.
The taxonomy slugs will be automatically incorporated in all new post URLs. If you want to use the new formats on existing URLs, you will need to regenerate them.
How to Remove Parent Category Slugs From Post Permalinks?
Each taxonomy registered with WordPress can be either hierarchical or nonhierarchical. The first one allows you have parent and child terms, same as with inbuilt categories. For example, you may have a custom taxonomy named "countries" and add parent term named "Europe" with child terms such as "Germany", "France", and "Italy". The second type (nonhierarchical) will function identically to post tags.
With SEO in mind, there are several cases when it may be preferable to keep the URLs of custom post type items as short as possible. The instructions below may be helpful if you want to add a single term slug to post permalinks but not the whole trail including their parent terms.
Depending on your requirements, you may either add a single slug of the highest-level parent or the lowest-level child.
- To use just the top parent slug, append the suffix "_top" to the end of the taxonomy permastructure tag.
For example, replace %product_cat% with %product_cat_top%. - In the latter case, the suffix added to the end of the tag should be "_flat" to use the slug of the lowest-level term.
For example, replace %product_cat% with %product_cat_flat%.
Initial permalink format
http://example.com/%product_cat%/%product%http://example.com/clothing/t-shirts/cotton/happy-ninja
http://example.com/clothing/jackets/leather/biker-black
New permalink format with top-parent term slug only
http://example.com/%product_cat_top%/%product%http://example.com/clothing/happy-ninja
http://example.com/clothing/biker-black
New permalink format with lowest-child term slug only
http://example.com/%product_cat_flat%/%product%http://example.com/cotton/happy-ninja
http://example.com/leather/biker-black
Primary Category Support
Permalink Manager is compatible with the "primary category" functionality of Yoast SEO, The SEO Framework, RankMath, and SEOPress. In summary, by default, the plugin replaces the "%taxonomy%" (e.g., %department%) tag in post permalinks with the slugs of actual categories' that are selected as the primary category.
Let us break it down using the most straightforwards examples possible. As you can see in the example below, the top-level category ("Sales") was chosen as the "primary category", and as a result, only its slug will be used in the URL for the post.
To make the difference clear, let us look at what happens when the lowest-level term is chosen. When the child category is selected, the slugs of all of its parent categories are included in the post URL, as shown in the screenshot below.
You may deactivate Permalink Manager's support for "primary category" in the plugin options. After you disable it, the default post permalink will use the lowest available category (including its parents, if available).
How to Modify Term Slug in Post Permalinks Programmatically?
If you know how to code, you can modify the category slug that is used when the post's default URL is generated. In particular, you may create a custom function that will replace the %taxonomy% tag (eg. %category%), which is dynamically populated with the slug of the category chosen for the post.
permalink_manager_filter_term_slug($slug, $selected_term, $post, $all_terms, $taxonomy)
Variable | Description |
---|---|
$slug | The slug or slugs trail used to replace %taxonomy% tag (eg. %category%) in default post permalinks (string) Example input: europe/central-europe/slovakia |
$selected_term | Term object chosen to be used in the default permalink of a post (WP_Term) |
$post | The post object for which the default permalink is generated (WP_Post) |
$all_terms | Array of all terms that are linked to the post that the default URL is generated for (WP_Term[]) |
$taxonomy | The name of the taxonomy (string) Example input: category |
How to Add Multiple Top-Parent Categories’ Slugs to Single Post Permalink?
Below is a simple example code snippet that demonstrates how you can use it to have Permalink Manager add the slugs of two top-parent categories to a single post permalink using the function. It may also be used for other post types and taxonomies if you modify it to your needs.
/**
* The snippet changes the category slug used when default custom permalink is generated for a post
*/
function pm_multiple_top_categories_in_uri($slug, $selected_term, $post, $all_terms, $taxonomy) {
	// Use the snippet only for ‘category’ slug in ‘post’ custom permalinks
	if(empty($post->post_type) || $post->post_type !== 'post' || $taxonomy !== 'category') {
		return $slug;
	}
	if(!empty($all_terms) && count($all_terms) > 1) {
		// Get only top-level categories
		$top_parent_terms = wp_filter_object_list($all_terms, array('parent' => 0));
		if(!empty($top_parent_terms) && count($top_parent_terms) > 1) {
			// Reset array keys
			$top_parent_terms = array_values($top_parent_terms);
			// We need two slugs, therefore the loop will repeat until $slugs_counter is “2”
			$top_parent_terms = array_slice($top_parent_terms, 0, 2);
			foreach($top_parent_terms as $top_parent_term) {
				if(empty($top_parent_term->slug)) { continue; }
				$new_category_slug = (empty($new_category_slug)) ? $top_parent_term->slug : "{$new_category_slug}/{$top_parent_term->slug}";
			}
		}
	}
	return (!empty($new_category_slug)) ? $new_category_slug : $slug;
}
add_filter('permalink_manager_filter_term_slug', 'pm_multiple_top_categories_in_uri', 10, 5);