WordPress has great flexibility when it comes to specifying your permalink structure. I had a request come in recently, however, to use only the topmost category in the permalinks for a site. The settings did not seem to allow this, so I had to find a way to remove subcategories from WordPress permalinks.
No Code
You can get the permalink structure to use just the top-level category, but it requires active participation of the authors, and would require you to edit all existing posts. If you’re starting a brand new site, you can use /%category%/ for the permalink structure. However, with every post, you’ll need to select the subcategory for the post and it’s top-most parent category. WordPress will then be able to find the post by either permalink, with or without the subcategory in the URL.
This is a perfectly acceptable solution, if you have complete control over every post and don’t mind ensuring every parent category is selected on those posts. And if you don’t mind the answering the inevitable question when an author forgets to tick that top-most level category.
Remove Subcategories from WordPress Permalinks, Every Time
To ensure the subcategories are removed without user intervention, we’re going to have to get our hands dirty. With PHP. Get it? I already did a bit of Googling, and found this StackOverflow post, which gave me a handle on the overall approach. So my hands are dirty here, too.
Let’s take a look at the code.
add_filter( 'post_link', 'my_filter_post_link' ); function my_get_all_child_categories( $category_id ) { $subcategories = array(); $category = get_category( $category_id ); if ( $category->parent ) { $subcategories[] = $category->slug . '/'; $results = my_get_all_child_categories( $category->parent ); $subcategories = array_merge( $subcategories, $results ); } return $subcategories; } function my_filter_post_link( $permalink, $post, $leavename ) { if ( 'post' != get_post_type( $post ) ) return $permalink; switch ( $post->post_type ) { case 'post': $categories = get_the_category( $post->ID ); $subcategories = array(); foreach ( $categories as $category ) { $results = my_get_all_child_categories( $category->term_id ); $subcategories = array_merge( $subcategories, $results ); } $permalink = str_replace( $subcategories, '', $permalink ); break; } return $permalink; } |
We’re going to need to hook into the post_link
filter and do a little bit of recursion. Evaluating the filter hook function, we can see we’re limiting our logic to basic post types. We then use our custom my_get_all_child_categories
function to get an array of child category slugs with their trailing slashes.
Once we have all the subcategories in an array, we can simply use str_replace
to clean up the post permalink.
Violà! We now completely remove subcategories from WordPress permalinks!
Thanks for this article – works nicely.
However, how do you then change the permalink in the actual Post Edit page to reflect the new URL structure?
Oh, you may need to go to Settings > Permalinks and save the settings. (You won’t have to change anything. Clicking save just forces a refresh). Let me know if that fixes it.
I tried in my website https://downiz.com but the subcategories not removed
Oh, you may need to go to Settings > Permalinks and save the settings. (You won’t have to change anything. Clicking save just forces a refresh). Let me know if that fixes it.
Hey … Thanks for great tutorial … I removed the subcategory using first method….
But I want to use 2nd method and I don’t know where we should paste the code?
Please let me know how to do it. Thanks!
Probably in your functions.php of your theme. You could also create a plugin, but that may be overkill.