How to add term name to slug?

By default permalink of custom post type (CPT) has only slug of the post-type and title of the post. There are cases post type should be contain term names.

Add term name to slug for custom post type

Problem: We have some CPT e.g. resource, it has slug resources/download-center and taxonomy resource_category. We should be, that this CPT has permalink /resources/term-name/post-title/ , also archive page /resources/.

Solution: Let's go step by step.

Step 1: In the function where we registered CPT instead 'rewrite' => [ 'slug' => 'resources/download-center' ] write next 'rewrite' => [ 'slug' => 'resources/%cat%' ].

Step 2: In the function.php add code:

<?php
// Replace Slug From URL Post Type Resource
add_filter( 'post_type_link', 'replace_slug', 1, 3 );
	
function replace_slug( $post_link, $id = 0 ) {
	$post = get_post( $id );
		
	if( $post->post_type == 'resource' ) {
		if ( is_object( $post ) ) {
			$terms = wp_get_object_terms( $post->ID, ['resource_category'] );
			if ( $terms ) {
				return str_replace( '%cat%', $terms[0]->slug, $post_link );
			}
		}
	}
	return  $post_link ;
}
	
add_action( 'init', 'generated_rewrite_rules' );
	
function generated_rewrite_rules() {
	add_rewrite_rule(
		'^resources/(.*)/(.*)/?$',
		'index.php?post_type=resource&name=$matches[2]',
		'top'
	);
}

After then, go Setting — Permalinks — Save Changes. But if we go on /resources/ we'll see 404 page.

Step 3: Return to first step and replace 'has_archive' => true to 'has_archive' => 'resources. Ultimately, we have:

<?php
$args = [
	...
    'rewrite' => [ 'slug' => 'resources/%cat%' ]
    'has_archive'=> 'resources',
	...
]

Again go Setting — Permalinks — Save Changes.

Sources:

  1. https://wordpress.stackexchange.com/questions/341088/add-term-slug-in-url-of-custom-post-type-details-page
  2. https://wordpress.stackexchange.com/questions/307788/how-to-rewrite-slug-of-custom-post-type-archive-page

Leave Comment

Your email address will not be published. Required fields are marked *