Step 1: Flush Rewrite Rules
Manually: Visit Settings > Permalinks
and click “Save Changes”.
Programmatically (temporarily):
function my_custom_flush_rewrite_rules() {
flush_rewrite_rules();
}
add_action( 'init', 'my_custom_flush_rewrite_rules' );
Step 2: Add Custom Rewrite Rules
function custom_rewrite_rules() {
add_rewrite_rule(
'^products/([^/]+)/([^/]+)/?$',
'index.php?post_type=product&product_category=$matches[1]&name=$matches[2]',
'top'
);
}
add_action( 'init', 'custom_rewrite_rules' );
Step 3: Modify post_type_link
Filter
function add_custom_rewrite_rule( $post_link, $post, $leavename ) {
if ( $post->post_type === 'product' ) {
$terms = wp_get_object_terms( $post->ID, 'product_category' );
if ( !is_wp_error( $terms ) && !empty( $terms ) && is_object( $terms[0] ) ) {
return str_replace( '%product_category%', $terms[0]->slug, $post_link );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'add_custom_rewrite_rule', 10, 3 );
Step 4: Register CPT and Taxonomy
Custom Post Type:
function register_custom_product_post_type() {
register_post_type( 'product', array(
'labels' => array(
'name' => __( 'Products' ),
'singular_name' => __( 'Product' )
),
'public' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'products/%product_category%', 'with_front' => false ),
'supports' => array( 'title', 'editor', 'thumbnail' )
));
}
add_action( 'init', 'register_custom_product_post_type' );
Taxonomy:
function register_product_category_taxonomy() {
register_taxonomy( 'product_category', 'product', array(
'labels' => array(
'name' => __( 'Product Categories' ),
'singular_name' => __( 'Product Category' )
),
'hierarchical' => true,
'rewrite' => array( 'slug' => 'products' ),
));
}
add_action( 'init', 'register_product_category_taxonomy' );