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 end 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://thebizpixie.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%/ structure $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!
Note: This solution does not correctly update the feed URL for this category, as it wasn’t that important for this particular project, so it’s a problem I haven’t solved yet. You’ll need to decide how important a functional feed is for your site, and whether you want to try and solve this issue yourself.
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!
27 comments
Alexander Behling
Update: not $taxonomy. Instead you have to use $term->slug.
Wasn’t able to correct it.
Nikki H Stokes
Hi Alexander,
I’m glad you found my solution, and that it was helpful to you.
As with many of my WordPress discoveries, I make them when I’m solving for a specific issue, and once I find something that works well enough, I usually move on.
I don’t recall specifically now why I chose to use the category ID instead of the slug, but you’re right that either should work, and using the slug would be more readable for future maintenance purposes, along with the possibility that the ID might change at some point (probably only during migration or a serious database overhaul I would have thought).
I just don’t have a working code example for that version, so I can’t say for sure without testing it myself.
But if you do implement it this way, I’d love to hear back from you how it goes and anything you learned from the process that you’re willing to share.
Alexander Behling
Great, just what I was looking for.
However I wonder why you don’t use the taxonomy parameter in the nhs_custom_case_studies_permalink_archive function. Therefore you don’t need to rely on an id since this could change based on the system you are working with. The slug stays even if the category has different id. So I would do something like “if( $taxonomy = ‘case-studies’){…”.
Only a suggestion.
Matthew Giannels
Hi there.
Thank you for this post. This is a solution I have been looking for to apply this to just single categories. The only problem this. I am no dev, not a wordpress gun like most people here seem to be. So I can't make heads or tails of the intructions
Any chance I can get some help?
There is some plugin that can apparently do this. However, its greatly expensive
Thank you
Nikki H Stokes
Hi Matthew,
I’m glad you found it helpful.
I do some freelance work on the side, but you might find that I’m more expensive than the plugin you’re looking at. Please feel free to contact me if you want more information.
When I was starting out, I used a site called WP Questions to get answers to specific WordPress questions for a small fee and found it extremely helpful, or you could look at hiring someone on UpWork to help you get it working.
Stephen Copley
Great code, thanks!
Nikki H Stokes
You’re most welcome.
ravi
Hello Nikki,
This is a valuable post.. thank you for sharing
Can u help me with the below case
xyz.com is a course website using an lms like learndash
xyz.com/course/abc-masterclass —- this is a course link ( has videos + quizzes)
xyz.com/course/ten-quizzes —- this is also a course link that has only quizzes
Now is it possible to assign a category to courses that has only quizzes and change the permalink for just those courses like
xyz.com/practice/ten-quizzes
If Yes… can u please help me with it…
Thank you,
Ravi
Nikki H Stokes
Hi Ravi,
Sorry, I only just saw your question. I really can’t offer any specific advice, but I’m sure you could adapt the code through trial and error to find a solution.
Linda Sturling
Awesome! Thank you so much for sharing!!!
Nikki H Stokes
Hi Linda,
You’re most welcome!
P.T.
Hi Nikki,
This is awesome and I'm using your codes. But I was looking to extend this a little further. Here is the scenario:
1. Website has multiple categories
2. A post can belong to two or three categories
3. How do I get the post's URL to change based on whichever category it's clicked on.
> Essentially something like: leave post's URL as is (website.com/post-name)
>>>UNLESS it's from this specific-category then URL would be website (website.com/specific-category/post-name)
Appreciate any tips you have.
P.T. Phan
I have thought of using tags. How would I use your codes here and apply to tags? Or would adding tags to the permalinks causes the same SEO issue?
Nikki H Stokes
No, sorry, I wasn’t saying that you could use tags to modify your URLs. I would never advocate changing your URLs dynamically for the reasons mentioned previously (mostly SEO but also the programmatic/WordPress challenges), but what you do with your URLs is up to you in the end.
What I meant was that if you wanted to put your content into more than one category, you could use tags for this instead.
My approach is to use categories like chapters of a book or a table of contents – a piece of content is only ever in one section.
And tags are like the index of a book – a piece of content can have as many as you want, which allows you to pull out a specific post in many ways.
If you took this approach, you could use the category for the URL, and then the URL would be unique and unchanging, and then use tags to display or retrieve the content in different ways, depending on the context.
But as I don’t fully understand your use case, then this may not meet your needs.
P.T.
Hi Nikki,
Thank you for your quickly reply. The posts on my is currently defined https://yourdomain.com/%postname%/. I am looking for the post's URL to change dynamically. Although, I did not think about the SEO angle – appreciate that. I'll have to rethink my next step.
Again, thank you so much.
Nikki H Stokes
OK, so I now understand what you’re aiming for, and although I strongly recommend against using dynamic URLs, you would need to create a rewrite rule to handle this, if you decide to go ahead.
But I think a different approach might cause you fewer problems. You might consider putting each post into one category only (with one unique URL) and using multiple tags to achieve some of the same things?
Nikki H Stokes
HI P.T.
I’m glad you’re finding it helpful.
I’m not 100% clear on what you’re trying to achieve, so I’ll address the two possibilities I’m hearing from you.
Firstly, I would never want a post’s URL to change dynamically, so if you’re suggesting that, then it’s not a great idea, and I honestly don’t know how WordPress would even be able to handle that, let alone all the SEO issues that would arise.
But if what you want to do instead is have the category show up in a post’s URL, but only for posts in a specific category, with everything else at the root of the site, then you would just define a custom structure for your post permalinks of something like https://yourdomain.com/%postname%/, and then use a modification of my code to rewrite the URLs to include the category (as per my code) for only those posts in a specific category.
But that only makes sense if a post is in one category, not if it is in multiple categories, as this could potentially give one post multiple URLs which could cause you all kinds of headaches, as mentioned.
Let me know if that helps.
Praneet
This works but it doesnt show the rss feed unfortunately , i have a category news, when i try to go to the rss feed link “/news/feed/” it does not work
Nikki Stokes
Hi Praneet,
That’s really great feedback, thanks. I hadn’t tested the RSS feed because it wasn’t important to my project, but it’s definitely something that matters, and might just be an extension of the same process of trial and error.
I probably won’t get the chance to look at this for a while sol let me know if you figure out how to get it working.
Lucas Lopvet
Hi there,
This is what I was looking for, however how can I display all posts with that category? in your example, if you go to yourdomain.com/case-study/ it returns a 404 instead of displaying everything. At least this is what happens to me with your code. Could you help?
Nikki Stokes
Hi Lucas,
I’m glad you found it helpful. Like I said in my post I just had to keep testing over and over until I got it to work. I can’t provide specific support because your setup is unique, but I can say that my code did allow me to display the posts as you are trying to do. I would have a look at your permalink settings and make sure that they’re right, and then read through the code line by line to make sure you’ve modified everything to match your set up exactly.
Marissa Wright
I’ve been trying to adapt this solution to a different Category by changing the term Case Studies with ID 28 to Careers with ID 171. Staging server of course, so no big deal when it blows up, but it doesn’t seem to work for me. Other than the Category name and the ID, is there anything else I’ve missed in the code? The consequence is that it seems to blow away all of the permalinks for the Post content – no Permalink or slug shows in the Post attributes, and no content can be viewed from the site’s front end from a user browser. Thoughts?
Nikki Stokes
Hi Marissa,
I suggest reading through the code line by line, making sure you understand what each line is doing, and that you’ve made appropriate changes in all parts of the code.
I had to do a lot of trial and error when getting this to work, so you may have to do the same.
Nishad
Hey, Seems interesting. Do you think it will work with woocommerce for a specific category?
Nikki Stokes
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.
Jagjot Singh
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
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.