I’m working on a WordPress site where I want to pull out just one category of blog post into its own URL structure, so that I can see how it’s performing in Analytics, and also send a signal to Google about the more important nature of the content.
This site has a number of blog post categories, including:
- Case Studies
- Product Updates
- Company Updates
- Job Postings
- Industry Insights
Most of these categories are not that critical to the site for SEO purposes and may change in the future as our content plan expands.
So the permalink structure I’ve chosen for most blog posts is:
https://mydomain.com/news/my-blog-post-name
This is done via a Custom Structure setting with this value:
/news/%postname%/
regardless of which category they fall into.
This will allow me to move posts between categories, have posts in multiple categories, and gives me the flexibility to modify categories in the future with minimal impact on the URL structure of the site.
The individual category archive pages have a URL structure like this:
https://mydomain.com/category/company-updates/
which I did using “category” as my Category base value in the permalink settings, and leaving the category base on in Yoast SEO.
I chose to do this so that these category archive pages fall into their own group of pages, and I can report on them as a whole, minus the category below.
My Custom Permalink Category = Case Studies
However, the one type of content this is critical to this website is “Case Studies”.
This content outperforms all the other blog post content combined and is the foundation of our content strategy moving forward.
So I wanted to pull it into its own URL structure to emphasize its importance to visitors, but also to Google.
Before I made any changes, the URL for all of my case studies posts was something like:
https://mydomain.com/news/some-company/
when what I wanted it to be was:
https://mydomain.com/case-studies/some-company/
to highlight the fact that this is not just another news item or blog post, but a bona fide, highly relevant and interesting case study.
And my Case Studies archive page URL was:
https://mydomain.com/category/case-studies/
when I wanted it to be instead:
https://mydomain.com/case-studies/
The Custom Category Permalink Solution
Initially, I used a plugin, Custom Permalinks, to make this change, but there were a few issues with this option:
- A whole plugin for a handful of URLs seemed like a lot of overhead
- The plugin hasn’t been actively maintained and has caused lots of issues for people
- It adds a field to every page and post that allows you to completely change the URL, which was just way too much of a disaster waiting to happen for my liking
So I decided to create a solution in PHP.
I solved the first part of this issue (the individual case study URLs) using a solution I found on Stack Exchange.
It took a little bit of stuffing around to get it working the way I wanted it to, but I got it working eventually.
The second part of the issue (the category archive page) was much harder to solve because I couldn’t find anyone doing this anywhere.
All the solutions I found were for the actual post URLs, and not for the archive page itself.
I eventually found a partial solution from Misha Rudrastyh, but this was more complex and didn’t create the exact behaviour I was looking for.
So I combined his solution with the Stack Exchange one, and then just kept testing over and over until I got it to work.
Important Note: Make sure to reload or save your permalinks settings page every time you make a change to your permalinks so WordPress flushes the permalink cache, otherwise you’ll be chasing your tail, trust me!
The Custom Category Permalink Code
Add this code to your site’s functions.php file and make suitable updates.
You’ll need to change the category ID to match the category you’re trying to change. Just hover over the edit link next to the category in your back to see the ID in the URL.
And of course, you’ll want to update the category name, and the category URL you’re changing it to for both the individual post and the archive function.
I highly recommend working on a test copy of your site in a development environment. This can seriously mess with your URLs on a live site or even take your site down!
Important Note: If you’re changing the URLs of existing, live, indexed content, make sure you add appropriate redirection rules to your .htaccess file or via a redirection plugin.
/*********************************** Modifying case study permalinks ************************************/ /** * Modify Permalinks for the Case Studies Category * * @author Nikki Stokes * @link https://measurewhatworks.com/ * * @param string $permalink * @param array $post * @param array $leavename */ // Modify the individual case study post permalinks function nhs_custom_case_studies_permalink_post( $permalink, $post, $leavename ) { // Get the categories for the post $category = get_the_category($post->ID); if ( !empty($category) && $category[0]->cat_name == "Case Studies" ) { $permalink = trailingslashit( home_url('/case-studies/'. $post->post_name . '/' ) ); } return $permalink; } add_filter( 'post_link', 'nhs_custom_case_studies_permalink_post', 10, 3 ); // Modify the "case studies" category archive permalink function nhs_custom_case_studies_permalink_archive( $permalink, $term, $taxonomy ){ // Get the category ID $category_id = $term->term_id; // Check for desired category if( !empty( $category_id ) && $category_id == 28 ) { $permalink = trailingslashit( home_url('/case-studies/' ) ); } return $permalink; } add_filter( 'term_link', 'nhs_custom_case_studies_permalink_archive', 10, 3 ); // Add rewrite rules so that WordPress delivers the correct content function nhs_custom_rewrite_rules( $wp_rewrite ) { // This rule will will match the post name in /case-study/%postname%/ struture $new_rules['^case-studies/([^/]+)/?$'] = 'index.php?name=$matches[1]'; $new_rules['^case-studies/?$'] = 'index.php?cat=28'; $wp_rewrite->rules = $new_rules + $wp_rewrite->rules; return $wp_rewrite; } add_action('generate_rewrite_rules', 'nhs_custom_rewrite_rules');
Remember to reload or save your permalinks settings page every time you make a change to your permalinks so WordPress flushes the permalink cache!
I’m absolutely tickled pink about this solution because it gives me complete control over the URL structure of these posts.
It took me a while to get it working correctly because you’re working with regular expressions and permalink caches and deep dark WordPress magic, but it was totally worth it in the end!
The other really important thing to remember is that this code should NEVER be removed from your site, not even temporarily, otherwise your URLs will change and your SEO will get seriously messed up.
To avoid this, you might want to consider pulling the code out of your theme’s functions file, and putting it into its own dedicated plugin file.
This provides protection in the event that your theme is deactivated or replaced at some point, but ultimately plugins can also be deactivated, so it’s not a foolproof solution either way.
No matter which approach you use, just make sure your code always, ALWAYS stays active.
Have fun modifying your WordPress category URLs!
Jagjot Singh says
Thank you for this amazing post. It really helped me setting up a custom URL structure for only 1 category.
You should also mention the “Important Note” regarding reloading the permalinks once again after the code haha. I was chasing my tail for 15 minutes before I figured out how to reload it.
Nikki Stokes says
Hi Jagjot,
You’re most welcome!
I’ve added that reminder after the code as you suggested, to save other people forgetting that key step.
Have a great day.
Nishad says
Hey, Seems interesting. Do you think it will work with woocommerce for a specific category?
Nikki Stokes says
Hi Nishad,
I’ve never tried this trick with WooCommerce, but seeing as it’s fundamentally changing the permalinks using the WordPress system, it would be worth a go.
I imagine you’d have to do a lot of testing and stuffing around to make sure it works as expected, like I had to when I was trying to get this working.
It is possible that WooCommerce wouldn’t cope with URLs that didn’t match what it was expecting, but let me know how you go if you try it out.