WordPress Custom Taxonomy With Same Slug As Custom Post Type

If you want the Terms in your Custom Taxonomy to have their URL path containing their Custom Post Type slug instead of Custom Taxonomy slug without showing 404 page, that can be a little tricky, and as I found throughout the blogs and forums quite impossible.

But, fortunately, it is possible! And it is really quite simple (although it took me a whole day and a lot of nerves to figure it out).

Before going any further, note that this only works when Permalink Settings are set to Post name!

Custom Post Type and Custom Taxonomy

Lets imagine you have situation like this, you need Custom Post Type named Recipes, and you need dynamic categories (TermsChinese, Indian, Thai… So you don’t want to create Custom Taxonomy for each and every one of them, you want them to be categories inside Taxonomy, so you can create as many as you wish.

And you want to achieve URL structure like this:


The logical way to do it would be like this:

// register custom post type
function create_post_types() {
    register_post_type('recipes', array(
        'labels' => array(
            'name' => 'Recipes',
            'all_items' => 'All Posts'
        'public' => true
add_action('init', 'create_post_types');

// register taxonomy
function create_taxonomies() {
    register_taxonomy('recipes-categories', array('recipes'), array(
        'labels' => array(
            'name' => 'Recipes Categories'
        'show_ui' => true,
        'show_tagcloud' => false,
        'rewrite' => array('slug' => 'recipes')
add_action('init', 'create_taxonomies');

Note that when registering Custom Taxonomy we use rewrite slug same as the Custom Post Type slug.
This is important!

Then lets create some Terms in admin for that Custom Taxonomy, as we stated above (Chinese, Indian, Thai…).

Rewrite rules

That would give us the links we wanted. But now, WordPress wouldn’t exactly know what to do with them, cause Custom Types and Taxonomies may not have the same slug, and would give 404 page on those taxonomy terms you created. So, now our function comes into play:

 * Replace Taxonomy slug with Post Type slug in url
 * Version: 1.1
function taxonomy_slug_rewrite($wp_rewrite) {
    $rules = array();
    // get all custom taxonomies
    $taxonomies = get_taxonomies(array('_builtin' => false), 'objects');
    // get all custom post types
    $post_types = get_post_types(array('public' => true, '_builtin' => false), 'objects');
    foreach ($post_types as $post_type) {
        foreach ($taxonomies as $taxonomy) {
            // go through all post types which this taxonomy is assigned to
            foreach ($taxonomy->object_type as $object_type) {
                // check if taxonomy is registered for this custom type
                if ($object_type == $post_type->rewrite['slug']) {
                    // get category objects
                    $terms = get_categories(array('type' => $object_type, 'taxonomy' => $taxonomy->name, 'hide_empty' => 0));
                    // make rules
                    foreach ($terms as $term) {
                        $rules[$object_type . '/' . $term->slug . '/?$'] = 'index.php?' . $term->taxonomy . '=' . $term->slug;
    // merge with global rules
    $wp_rewrite->rules = $rules + $wp_rewrite->rules;
add_filter('generate_rewrite_rules', 'taxonomy_slug_rewrite');

WordPress has its own nice rewriting mechanism independent from .htaccess that is processed in php before output. Here we tell WordPress what to do with the URLs we created (only those Taxonomy Terms whose parent Taxonomy has the same slug as its Custom Post Type) and where to redirect them, by adding permalinks to his rewriting object.

PHP files

So, now, all you have to do is to create .php files in your theme directory, that will print the content. The filename for the Post Type page is arhchive-{post_type}.php, for the Taxonomy page is taxonomy-{registered_taxonomy}.php, and for the single pages its single-{post_type}.php

In our case from above it would be:

  • archive-recipes.php
  • taxonomy-recipes-categories.php
  • single-recipes.php


After doing all this, just go to settings/permalinks and save changes using structure /%postname%/, and thats it!

Download example files

Download working example to see how it works.


  1. Simply wis to sɑy yоur article iss as amazing.
    Thhe clearness іn yօur publish is јust excellent and i
    can assume уоu’re aan expert ߋn tһis subject.
    Ꮃell with ʏour permission ɑllow mme t᧐
    grasp yoyr feed to kеep սp to dɑtе with imminent post.
    Tһanks оne million ɑnd pleaѕe қeep up the gratifying

  2. Thanks for sharing your thoughts about odsylam tutaj.


  3. Dennis

    Ending up with a 404 error page when trying to create a WordPress Custom Taxonomy is enough to make me want to rip my hair out. When working on my webpages, I need movements to be seamless, and errors to be non-existent for my customers. Hopefully this code will make my pages load faster, so they can easily pass the dns speed test, and lead to less wait time for visitors to my site. The images you have provided for your walk-through are super detailed! I can’t wait to try this!

  4. Mohammed

    Thanks for your code, I just wonder dose it work with Multi languages for ex. if we use WPML ?


  5. Anton

    top article! saved me a lot of time, thanks

  6. Mateusz


    If anyone still has a problem with the link structure in WordPress, then I would like to present you a plugin that solves this problem:


    By using it you can achieve a friendly link structure (all this in a few clicks in the admin panel):

    Custom Post Type > Single Term > Post
    Custom Post Type > Post (if there is no selected category)
    Custom Post Type > Single Term

    I invite you to check my plugin and if you like it – to recommend to others. I will be very grateful!

    1. Valeka

      Thank you very much. This worked for me.

  7. ANil

    Works For Me Thank you!!!

  8. james

    Demo code doesn’t work with sub-cats or pagination…

  9. Great goods from you, man. I’ve understand your stuff previous to and you’re just too fantastic.
    I actually like what you have acquired here, really like what you’re stating
    and the way in which you say it. You make it entertaining and you still take care
    of to keep it sensible. I cant wait to read far more from you.

    This is actually a great web site.

  10. Hi there this is somewhat of off topic but I was
    wanting to know if blogs use WYSIWYG editors or if you have to manually code with HTML.
    I’m starting a blog soon but have no coding know-how so I wanted to get guidance
    from someone with experience. Any help would be greatly appreciated!

  11. The downloadable code is different from the the embedded example in the post.

    The working code compares the taxonomy object type against the post type, where the embedded example compares the taxonomy object type against the post type’s slug.

    Line 26(left) vs line 29(right). The condition doesn’t pass, so the re-write update never fires, causing the single 404 error.

    see: https://cdn.pbrd.co/images/GCKqjQO.png

    Most people won’t read down this far in a comment chain, so I’d consider updating the example code in the post.

  12. Hi, l am having a problem with the custom post types that are embedded in the wordpress theme functions code.
    l want to change theme so l want to make the custom post types a plugin in order to switch themes, using the genesis framework.

    Any ideas?

    1. Wow! Thank this helped instantly :) you can set a higher priorty than the post type in the hook when registering the taxonomy

  13. Simone

    Hi, for me it doesn’t works, i have a 404 on single post page.
    Any help?

  14. function wp_travel_engine_register_trip() {
    $labels = array(
    ‘name’ => _x( ‘Trips’, ‘post type general name’, ‘wp-travel-engine’ ),
    ‘singular_name’ => _x( ‘Trip’, ‘post type singular name’, ‘wp-travel-engine’ ),
    ‘menu_name’ => _x( ‘Trips’, ‘admin menu’, ‘wp-travel-engine’ ),
    ‘name_admin_bar’ => _x( ‘Trip’, ‘add new on admin bar’, ‘wp-travel-engine’ ),
    ‘add_new’ => _x( ‘Add New’, ‘Trip’, ‘wp-travel-engine’ ),
    ‘add_new_item’ => __( ‘Add New Trip’, ‘wp-travel-engine’ ),
    ‘new_item’ => __( ‘New Trip’, ‘wp-travel-engine’ ),
    ‘edit_item’ => __( ‘Edit Trip’, ‘wp-travel-engine’ ),
    ‘view_item’ => __( ‘View Trip’, ‘wp-travel-engine’ ),
    ‘all_items’ => __( ‘All Trips’, ‘wp-travel-engine’ ),
    ‘search_items’ => __( ‘Search Trips’, ‘wp-travel-engine’ ),
    ‘parent_item_colon’ => __( ‘Parent Trips:’, ‘wp-travel-engine’ ),
    ‘not_found’ => __( ‘No Trips found.’, ‘wp-travel-engine’ ),
    ‘not_found_in_trash’ => __( ‘No Trips found in Trash.’, ‘wp-travel-engine’ )

    $args = array(
    ‘labels’ => $labels,
    ‘description’ => __( ‘Description.’, ‘wp-travel-engine’ ),
    ‘public’ => true,
    ‘menu_icon’ => ‘dashicons-location-alt’,
    ‘publicly_queryable’ => true,
    ‘show_ui’ => true,
    ‘show_in_menu’ => true,
    ‘query_var’ => true,
    ‘rewrite’ => array( ‘slug’ => ‘trip’ ),
    ‘capability_type’ => ‘post’,
    ‘has_archive’ => true,
    ‘hierarchical’ => false,
    ‘menu_position’ => null,
    ‘supports’ => array( ‘title’, ‘editor’, ‘author’, ‘thumbnail’, ‘excerpt’, ‘comments’ )

    register_post_type( ‘trip’, $args );

    function wp_travel_engine_create_trip_taxonomies() {
    // Add new taxonomy, make it hierarchical (like trip_categories)
    $labels = array(
    ‘name’ => _x( ‘Categories’, ‘taxonomy general name’, ‘wp-travel-engine’ ),
    ‘singular_name’ => _x( ‘Categories’, ‘taxonomy singular name’, ‘wp-travel-engine’ ),
    ‘search_items’ => __( ‘Search Categories’, ‘wp-travel-engine’ ),
    ‘all_items’ => __( ‘All Categories’, ‘wp-travel-engine’ ),
    ‘parent_item’ => __( ‘Parent Categories’, ‘wp-travel-engine’ ),
    ‘parent_item_colon’ => __( ‘Parent Categories:’, ‘wp-travel-engine’ ),
    ‘edit_item’ => __( ‘Edit Categories’, ‘wp-travel-engine’ ),
    ‘update_item’ => __( ‘Update Categories’, ‘wp-travel-engine’ ),
    ‘add_new_item’ => __( ‘Add New Categories’, ‘wp-travel-engine’ ),
    ‘new_item_name’ => __( ‘New Categories Name’, ‘wp-travel-engine’ ),
    ‘menu_name’ => __( ‘Categories’, ‘wp-travel-engine’ ),

    $args = array(
    ‘hierarchical’ => true,
    ‘labels’ => $labels,
    ‘show_ui’ => true,
    ‘show_admin_column’ => true,
    ‘query_var’ => true,
    ‘rewrite’ => array( ‘slug’ => ‘trip’ ),

    register_taxonomy( ‘trip_categories’, array( ‘trip’ ), $args );

    function taxonomy_slug_rewrite($wp_rewrite) {
    $rules = array();
    // get all custom taxonomies
    $taxonomies = get_taxonomies(array(‘_builtin’ => false), ‘objects’);
    // get all custom post types
    $post_types = get_post_types(array(‘public’ => true, ‘_builtin’ => false), ‘objects’);

    foreach ($post_types as $post_type) {
    foreach ($taxonomies as $taxonomy) {

    // go through all post types which this taxonomy is assigned to
    foreach ($taxonomy->object_type as $object_type) {

    // check if taxonomy is registered for this custom type
    if ($object_type == $post_type->rewrite[‘slug’]) {

    // get category objects
    $terms = get_categories(array(‘type’ => $object_type, ‘taxonomy’ => $taxonomy->name, ‘hide_empty’ => 0));

    // make rules
    foreach ($terms as $term) {
    $rules[$object_type . ‘/’ . $term->slug . ‘/?$’] = ‘index.php?’ . $term->taxonomy . ‘=’ . $term->slug;
    // merge with global rules
    $wp_rewrite->rules = $rules + $wp_rewrite->rules;

    I’m using it for my plugin, so all the mentioned templates are there. Archive page works but single page returns 404 page.
    Any help??

  15. Faisal

    Works perfect. Thank you so much..

  16. Schalk

    This is magical, thank you!
    …but i need some help, please.

    It works perfectly for my parent taxonomies, but not for child taxonomies.

    My CPT: accommodation
    my Tax: accommodation-region

    This are the perfectly change from / to:

    BUT This doesn’t change from / to:

    Thank you

  17. Fabrice

    Hello, I was wondering if this would work with a shared taxonomy between several custom posts.
    For example, if I have a CPT called “project” and another called “portfolio” and I have a custom taxonomy called “color” with terms like “yellow”, “red”… will this work like this ?
    on domain.com/projects/color/red I will have only projects that have the red color and on domain.com/porfolio/color/yellow only the yellow portfolio or will i have the yellow projects and yellow portfolio mixed ?

  18. Aakash

    Works like a charm. Thankyou so much :)

  19. Torben

    thanks for sharing this. I tried it and it works, but however I was wondering if this is still the easiest and best solution in WP 4.3.1? Do you know that? Thanks!

  20. Ask a “main street” American how the economy is doing and they’ll say ‘we’re in a recession, if not a depression. If you have a great product that somehow never seems to get the attention that it deserves, it may be that by creating a landing page and a campaign to drive traffic to that page is all you require, rather than a full website build and optimisation of every page on the website. To make sure that you are getting the best techniques for your business, better make sure that you have chosen the best SEO Company for your business needs.

  21. Andrius

    Hi there is a small problem with line 26. The code works perfectly but if the amount of posts is higher it cant won’t allow you to navigate to next page. Additional line helps to fix this issue :
    $rules[“{$object_type}/{$term->slug}/page/?([0-9]{1,})/?$”] = “index.php?{$term->taxonomy}={$term->slug}&paged=” . ‘$matches[1]’;

  22. Ryan

    This worked a charm for me! Exactly what I wanted. :)

  23. nicmare

    you really need to flush the rewrite rules cache. but has someone an idea how to do this when a new taxonomy is created? so i do not need to do this each time by visiting permalinks page?!

    1. nicmare

      this should do the trick:
      add_action( ‘save_post’, ‘flush_permalinks’);
      function flush_permalinks( $post_id ) {
      if(get_post_type($post_id) == “YOUR_POSTTYPE_NAME”){

  24. nicmare

    very, very good tutorial! i do not need the taxonomy theme file. but added has_archive = true to my CPT. then it worked as expected for me. thank you!

  25. Samuel

    Thanks for tutorial.
    I get “Page not found” when open sub category.

    For example : I have “gallery” custom post type. The slug of custom taxonomy is “gallery” too.

    I create a post and attach it in a category, named “holiday”.

    I am able to display post list with the following link : ../gallery/holiday/

    Then I create a sub category “beach” underneath “holiday”

    I get “Page not found” when open this link :

    How to modify your script to solve the problem?

    Thanks in advance.

    1. Porter

      I’ve been trying to get this to work all night, and for whatever reason, site.com/dining/actual-post is giving me a 404. site.com/dining and site.com/dining/term work great, but all posts of the custom post type return a 404. I’ve made the template, I’ve flushed the rewrite rules, nothing seems to work – any ideas?

  26. How to prevent a post to steal a term slug?
    Example : I have a ‘books’ CPT with a ‘novels’ category:
    URL –> http://www.tld.com/books/novels
    What can I do if I don’t want any of my post can have the same URL to prevent conflicts ? Is it possible to deal with a filter to attribute a modified slug to a post that can try to use a reserved term slug ? Thank you

  27. I got this error, when i try to use your function,

    Parse error: syntax error, unexpected ‘$rules’ (T_VARIABLE)

    Basicaly error is because of the line “$rules = array();”

    please suggest me what to do..

    1. Be carefull when copying and pasting from the text box on the page as it sometimes will convert characters.
      I realized this when I removed the first $rules variable and noticed that I was getting PHP errors with &nbps; at the line where I had spaces in the code.

  28. Greg,

    Thanks! I’m just building my first theme, and this finally got my custom post types & taxonomies working. One question though: From an SEO perspective, to have URLs like this:


    is considered (by Google) as less preferrable to this:


    Is this possible to accomplish? Would this just be a matter of customizing the “rewrite slug” method?

  29. Gen

    You are a genius!! I spent all day trying to figure this out and I finally found your post. Thank you!

  30. Pudge Reyem

    When adding a new taxonomy I needed to manually update the Rewrite rules, but automated this using the save_post hook. Code here; http://pudge.se/D9Vs

  31. Jason

    You are the man. Thanks.

  32. The fix from @THEOEPHRAIM works for me, but… I’m having problem with subcategories!
    /products/subcategory … returning 404 error. It should be /products/category/subcategory

    Any ideas?

  33. wntd!

    awesome, that rewrite code fix all my problems, thanks!!

  34. Michel

    thanks Much. It works great. But I have a little issue on the page navigation. When I navigate to page/2 it works fine. But when I navigate to page 3 and so on, I got 404 page. Any thoughts? Thanks

  35. Hello,
    Your code is very usefull. But it does not work with sub categories. Do you know how to fix that?

    1. xchp

      I too would like to know how to make your code display sub-categories.

  36. Hi, I couldn’t quite work out the:

    if ($object_type == $post_type->rewrite[‘slug’])

    The object_type was coming out as my namespaced post type name and wasn’t matching the slug so I changed this to be:

    if ($taxonomy->rewrite[‘slug’] == $post_type->rewrite[‘slug’])

    Can you see any complications coming from that in the future?

  37. Thanks, work perfecly for me.

    But, how to show all taxonomies althought they are not have post?

  38. Thank you so much for sharing this snippet! Other techniques were a lot more cumbersome and didn’t work with pre-existing WP functions. I’m glad to see someone has figured it out.

  39. Thanks for the PHP file tips. Finaly got the custom templates to work.

  40. leonardo

    it’s amazing, man! i was searching exactly for this! thanks so much!

    1. leonardo

      but i have a issue!

      cpt = ‘house’

      tax = ‘house-types’

      url domain.com/house/ – works (list all houses)
      ul domain.com/house/sale/ – works (list all sale house)

      but my permalink appears – domain.com/house/texas-united-states

      404 error!


      1. Augusto Carmo

        did you find the answer for that?

  41. Works perfectly in the scenario stated and explains a lot of headaches in the past with CPTS.

    I didn’t realise it was because the slugs were shared. I usually create a page to fulfil the purpose of the /post_type/ url with the CPT archive and query_var settings off and then the taxonomy permalinks behave as expected. Will try this next time.

    The CMS allways seems to generate permalinks in the expected format; why doesn’t the front-end just rewrite the URLS in the same way? Can your filter be modified to work without setting permalink settings to post_name?

  42. Cameron

    I was having the same issue with my single pages returning 404 errors when the archive and taxonomy archive pages were working just fine. I was even able to copy the example “project” CPT and templates into my own project to verify they worked in the same context.

    The one difference I noticed was order of definition. I was registering my custom taxonomy before my CPT whereas the example in this post does the reverse. For whatever reason I have yet to figure out, this order of definition matters. Once I switched my project to register the CPT before the taxonomy, like magic it worked.

    If I manage to figure out why, I’ll post what I find. (or if anyone else figures it out, please share! My ocd brain is dying to know.)

  43. Could you add rules for paged archives ($rules[$object_type . ‘/’ . $term->slug . ‘/page/?([0-9]{1,})/?$’] = ‘index.php?’ . $term->taxonomy . ‘=’ . $term->slug . ‘&paged=$matches[1]’;) and for category feeds?


  44. EY

    Hi I have problem with the URL rewrite, I have template files:
    – archive-articles.php
    – taxonomy-articles-categories.php

    and this is my cpt and tax slug:
    – my cpt slug = articles
    – my taxonomy slug = articles

    and I want my URL to be like this:
    http://domain.com/articles (works)
    http://domain.com/articles/parent-tax (works)
    http://domain.com/articles/parent-tax/child-tax (404 error)
    http://domain.com/articles/parent-tax/child-tax/post-title (404 error)


    1. reeslo

      * Replace Taxonomy slug with Post Type slug in url
      * Version: 1.1 - http://someweblog.com/wordpress-custom-taxonomy-with-same-slug-as-custom-post-type/
      public function taxonomy_slug_rewrite($wp_rewrite) {

      $rules = array();
      // get all custom taxonomies
      $taxonomies = get_taxonomies(array('_builtin' => false), 'objects');
      // get all custom post types
      $post_types = get_post_types(array('public' => true, '_builtin' => false), 'objects');

      foreach ($post_types as $post_type) {
      foreach ($taxonomies as $taxonomy) {

      // go through all post types which this taxonomy is assigned to
      foreach ($taxonomy->object_type as $object_type) {

      // check if taxonomy is registered for this custom type
      if ($object_type == $post_type->rewrite['slug']) {

      // get category objects
      $terms = get_categories(array('type' => $object_type, 'taxonomy' => $taxonomy->name, 'hide_empty' => 0));

      // make rules
      foreach ($terms as $term) {

      $route = '';

      if(!empty($term->parent)) {

      $route .= $object_type . '/' . $this->get_term_parents_route($term->parent, $term->taxonomy) . '/'. $term->slug . '/?$';
      else {
      $route .= $object_type . '/' . $term->slug . '/?$';

      $rules[$route] = 'index.php?' . $term->taxonomy . '=' . $term->slug;
      // merge with global rules
      $wp_rewrite->rules = $rules + $wp_rewrite->rules;

      public function get_term_parents_route($id, $taxonomy, $route = array()) {

      $term = get_term_by('id', $id, $taxonomy);

      if(!empty($term)) {

      $route[] = $term->slug;

      if(!empty($term->parent)) {
      $route[] = $this->get_term_parents_route($term->parent, $term->taxonomy);

      $reverse = array_reverse($route);

      $route = implode('/', $reverse);

      return $route;

      1. Arun

        how to create parent child URL structure with same slug

  45. Theo Ephraim

    worked for me. Thanks. But your code does not take into account a rewrite slug on the custom post type (for example my post type is portfolioitem but the rewrite slug is just “portfolio”)
    Here is a slightly updated version which takesit into account.

    function ss_fix_portfolio_rewrite($wp_rewrite) {
        $rules = array();
        // get all custom taxonomies
        $taxonomies = get_taxonomies(array('_builtin' => false), 'objects');
        // get all custom post types
        $post_types = get_post_types(array(
            'public' => true,
            '_builtin' => false),
        foreach ($post_types as $post_type) {
        	$post_type_name = $post_type->name;
        	$post_type_slug = $post_type->name;
        	if ( $post_type->rewrite && $post_type->rewrite['slug'] ){
        		$post_type_slug = $post_type->rewrite['slug'];
            foreach ($taxonomies as $taxonomy) {
                // check if taxonomy is registered for this custom type
                if ($taxonomy->object_type[0] == $post_type_name) {
                    // get all categories (terms)
                    $categories = get_categories(array(
                        'type' => $post_type_name,
                        'taxonomy' => $taxonomy->name,
                        'hide_empty' => 0
                    // make rules
                    foreach ($categories as $category) {
                      $rules[$post_type_slug . '/' . $category->slug . '/?$'] = 
                        'index.php?' . $category->taxonomy . '=' . $category->slug;
        // merge with global rules
        $wp_rewrite->rules = $rules + $wp_rewrite->rules;
    add_filter('generate_rewrite_rules', 'ss_fix_portfolio_rewrite');
    1. Thanks man, I totally forgot about that. I’ve updated the code slightly different from yours, with one more modification (fix).

      Cheers ;)

    2. Cameron

      Thanks Theo,

      I hit this same issue and it took me a while to realize that neither the original post nor the attached sample zip handled CPT->rewrite[‘slug’]. I just needed to replace $rules[$post_type->name…] with $rules[$post_type->rewrite[‘slug’]…]


    3. Nico

      Awesome! Thank to you both!

    4. fernando

      This one works than the Author’s code

  46. Didn’t work for me though. Post type was “music” and register_taxonomy (‘genre’ ….

    I had xyz.com/music/genre/post-title
    url structure worked fine but just simply didn’t show the posts (archive-music.php) rather it gives me 404 notice.

    Interestingly, I could get the archive-music.php working with custom loop.. ( ‘music’, ‘posts_per_page’ => 10 );
    $loop = new WP_Query( $args );” . Regular loops doesn’t work! Any idea? I also want to display posts under “taxonomies” but “taxonomy-music-genre.php” fails to grab any post with regular loop. Please help. Thanks.

  47. Clive

    Thank you for this. It’s great however it throws a 404 when using pagination, example:


    Any ideas from you clever folk how to get it working with pagination?

    1. got the same problem, anyone got this right ?

  48. Lee

    Hi Željko,
    thanks for taking the time to share your experience and creating the example files. For the life of me I can’t get the URL’s to play nice. With your sample files I create a project category (let’s call it ‘urban’). I then create a new project (let’s call it ‘city’) and associate it to the new category. The URL in the new project stays as /project/city, not /project/urban/city as I would expect it to be. I have resaved the permalinks and still nothing. What am I missing?

    Thanks, any suggestions are appreciated :)


    1. Just let me get this clear, you registered custom post type as ‘project’ like this:
      register_post_type('project', ... );
      and taxonomy as ‘urban’ like this:
      register_taxonomy('urban', array('project'), ... );
      And ‘city’ is the term you created in administration?
      Have I understood you correctly?

      1. Lee

        Thanks for your reply. All I have done is restored your test files as a theme. In WordPress admin I have then configured a project category called ‘urban’, then added a new project ‘city’ and associated it to the category ‘urban’. I haven’t changed any code. Should I expect to get a URL for city like /project/urban/city?

  49. This does seem to work, but it also seems to ruin pagination. Any thoughts on how to fix?

    1. What plugin are you using for pagination? We’ve tested it with WP-PageNavi and it worked fine.

      1. Jung

        Hi I tried using WP-PageNavi but it still navigates to single-posttypename.php file (with a first item within the list)
        can you please help?

  50. Cool it is working great busy getting it implemented in a blog with a directory currently

  51. Hello! Thanks for the very helpful article. I have one question though: Using your example with recipes. Let’s say my website has both a BLOG and a RECIPE section. Here, you explain how to make each term a valid/non404 URL. But, what if I had “chinese” or “indian” as a tag on blog posts, as well? The tag (if I made that first) would already own the “chinese” or “indian” slug, correct? So, WordPress would automatically add a “-2” to my slugs, right? However, I would like nice, clean URLs to these recipe terms; how can I acheive this?

    For example, a year ago I wrote a blog post about eating Chinese food, tagging the article with “chinese,” among other things. Now, I did what you did in your article – I have made a custom post type “recipes,” and a custom tax for the recipe categories. But I want my URLs to look like: http://www.domain.com/recipes/chinese NOT domain.com/recipes/chinese-2/ you know?

    Any ideas as to what I should do? Thanks a bunch for the help and for the very informative article!

  52. I’m also struggling a bit. I have a custom post type called retail-product and a custom post type called retail-product-type. I want the both to share a base called retail-products. However, in the case of the custom post type, I want it to be /retail-products/%retail-product-type%/. I keep getting a 404 on the base /retail-products/. Can the function be modified in some way to cater for the /%retail-product-type%/ ?

    1. You got me confused. You have two CPTs and want both to share same base? Or I misunderstood something?

      1. Thanks for the reply. I’m actually trying something odd. I don’t have two CPT trying to share the same base as you asked. I have one CPT and one Custom Taxonomy trying to share the same base, except that I need the CPT slug to be “shared-base/%Custom-Taxonomy%”. I’m sure I’m confusing you even more. The end result would be an archive of the Custom Taxonomy items. Don’t worry if you can’t assist, as your function has already done half the work to eliminate some 404’s. I can always create a plain page so the base slug has something to match.

          1. Have a look at my code:
            You will see three functions. One for the CPT, one for the Taxonomy and one to rewrite the %retail-product-types% part of the permalink when I create a new post.

            So, without the slug, it should work something like:
            http://yourdomain.com/retail-product-types/strong-coffees/blah-coffee-brand. But I am specifying in the slug parameter that I want it to be …com/retail-products/strong… instead.

            So, I would like:
            /retail-products – Tax Archive
            /retail-products/strong-coffees – CPT archive

            Your function works all but for /retail-products where I get a 404. I have created a page called “Retail Products” which fills that gap. It’s ok, but I kinda wanted it done right.

            This comment is taking up space, so feel free to email me directly.

  53. Thanks for this.

    I too bumped into the issue of categories showing while the projects gave a 404. I noticed the rewrite rules were cached… and this could be the issue if you experience similar problems.

    Flush the rewrite rules (I did it by re-saving the permalink setting). This should fix the problem.. it did for me.

  54. Peter

    Didn’t work for me either. Tried with CPT: project and project-categories with slug: project.


    1. I’ve included working example at the end of the text, download it and try it ;)

  55. I’ve been looking for this and it almost works. The problem I’m having is that now single items of the post type shup up 404.

    In in my case I have a Custom post type of “Products”, with a custom taxonomy of “Product Type”.

    I want taxonomy archives to show up under /products/taxonomy-term/, and this bit you have achieves that. But now my single products with urls like /products/single-product-name/ are 404.

    Back to searching…

    1. Like I said to JKRUGER, try to name your files like I’ve mentioned in the text, it should be working then.

  56. Jkruger

    Didn’t work for me. Same setup. Still 404s

    1. I forgot to write how to name your files in theme directory. I’ve added it to the text above, so try that.

    2. Steve

      Try to regenerate permalinks (Settings->Permalinks->Save changes)…

      1. Thanks, that worked for me. Kept checking to make sure file names were ok and everything, when in fact a permalink re-save was the solution.

        1. testtest

          Rotel jobal lol

    3. Marek

      Check hierarchical for CPT, should be set to false.

Leave a Reply to florent Cancel reply

Your email address will not be published. Required fields are marked *