The Permalink structure setting on the Permalink Settings admin page is only applied to the default post type, i.e. post
. For custom post types (CPTs), you can set the permalink structure (for posts in your CPT) when registering your CPT, via the rewrite
argument for register_post_type()
.
But, if you want to use %category%/%postname%
with your CPT, then you should use a unique base like lingeries
as in https://example.com/lingeries/category-slug/post-slug/
, to avoid conflict with the default post type’s permalinks.
- So for example, if the category slug is
foo-category
and the post slug isfoo-lingerie
, then the permalink would behttps://example.com/lingeries/foo-category/foo-lingerie/
.
And here’s how can you achieve that:
-
Set your CPT’s rewrite slug to
lingeries/%category%
, i.e.'rewrite' => array( 'slug' => 'lingeries/%category%' )
. -
Use the
post_type_link
hook to replace the%category%
tag in the above structure with the correct post category slug. -
Flush your rewrite rules (i.e. re-save your permalinks) by simply visiting the permalink settings page without having to click on the “Save Changes” button.
And remember that you need to re-save the permalinks every time you changed the rewrite slug, including after you registered/added a new post type with rewriting enabled, e.g. when simply using
'rewrite' => true
.
Sample code for replacing the %category%
tag (in step 2 above):
add_filter( 'post_type_link', 'my_lingerie_post_type_link', 10, 2 );
function my_lingerie_post_type_link( $post_link, $post ) {
// Do the replacement only if the post type is lingerie.
if ( $post && 'lingerie' === $post->post_type ) {
// Get the categories assigned to the post.
$categories = get_the_category( $post->ID );
// The category slug which will be used in the permalink, i.e. it replaces
// the %category% tag.
$category = '';
// If there is a category assigned to the post, we use the first one.
if ( ! empty( $categories[0] ) ) {
$category_object = $categories[0];
$category = $category_object->slug;
// If the category has one or more parents, let's add them to the
// permalink. So for example, the permalink would look like
// https://example.com/lingeries/parent-category/child-category/post-slug/
// instead of https://example.com/lingeries/the-first-category/post-slug/.
// (the-first-category refers to $categories[0])
if ( $category_object->parent ) {
$category = get_category_parents( $category_object->parent, false, "https://wordpress.stackexchange.com/", true ) . $category;
}
}
// If there were no categories assigned to the post, then let's use a default
// one. But it doesn't have to be "uncategorized", just use whatever you like..
$category = $category ? $category : 'uncategorized';
$post_link = str_replace( '%category%', $category, $post_link );
}
return $post_link;
}