I am having trouble working with WordPress rewrite rules, and could use some help.

I have a custom post type called _shows_.

All shows have a single custom taxonomy category _show-category_. A _show_ will never have more than one _show-category_.

I would like my urls to route in this manner:

www.mysite.com/shows/  =>  archive-shows.php

www.mysite.com/shows/%category%/ => taxonomy-show-category.php

www.mysite.com/shows/%category%/%postname%/ => single-shows.php

So as a real world example, lets say we have a _show-category_ "Foo" and a _show_ post titled "Bar" that has "Foo" as it's _show-category_. I would expect my WordPress app to look like this:

www.mysite.com/shows/foo/ => shows all posts under the foo category
www.mysite.com/shows/foo/bar => shows the indivual post

I try to avoid plugins when possible, but am open to any solution.

up vote 53 down vote accepted

First, register your taxonomy and set the slug argument of rewrite to shows:

register_taxonomy(
    'show_category',
    'show',
    array(
        'rewrite' => array( 'slug' => 'shows', 'with_front' => false ),
        // your other args...
    )
);

Next, register your post type and set the slug to shows/%show_category%, and set has_archive argument to shows:

register_post_type(
    'show',
    array(
        'rewrite' => array( 'slug' => 'shows/%show_category%', 'with_front' => false ),
        'has_archive' => 'shows',
        // your other args...
    )
);

Last, add a filter to post_type_link to substitute the show category in individual show permalinks:

function wpa_show_permalinks( $post_link, $post ){
    if ( is_object( $post ) && $post->post_type == 'show' ){
        $terms = wp_get_object_terms( $post->ID, 'show_category' );
        if( $terms ){
            return str_replace( '%show_category%' , $terms[0]->slug , $post_link );
        }
    }
    return $post_link;
}
add_filter( 'post_type_link', 'wpa_show_permalinks', 1, 2 );

EDIT

Forgot the has_archive argument of register_post_type above, that should be set to shows.

  • 1
    Milo, thank you! The post_type_link filter was the missing piece for me. Anyone reading this thread with the same problem, the only thing of note is there is a small mistake on the wpa_show_permalinks function, where $post->post_type == 'show' should actually be 'shows'. Thanks again Milo! – Paul T Aug 2 '13 at 5:38
  • 1
    @milo, coming over from wordpress.stackexchange.com/questions/199456/…, I keep landing on a 404 with this approach. My permalink structure is %category%/%postname% – Atticus Aug 23 '15 at 17:47
  • 4
    If you're making a change to an existing WordPress instance, make sure you go to Settings > Permalinks and click save. The changes you've made in functions.php won't take effect until you do. – Jay Neely Jan 5 '16 at 0:14
  • 2
    This almost worked for me in that the taxonomy displays on the post type page, the /post_type/taxonomy/ is a legitimate page (previously 404) but my /post_type/taxonomy/post is 404'ing. I noticed when registering the taxonomy above both "show_category", "show" were being registered, even though only the show_category is the taxonomy. I'm only registering the taxonomy. – justinavery Sep 28 '16 at 7:16
  • 3
    @Milo any way to get this to work with sub sub tax like shows/tax/subtax/post ? – Benn Jan 26 '17 at 14:22

To get custom taxonomy on post page or archive why not used this code?

global $wpdb, $post;
    $terms = get_the_terms($post->ID, 'CUSTOM_TEXONOMY_NAME_HERE');
    if (! empty($terms)) {
      foreach ($terms as $term) {
        $url = get_term_link($term->slug, 'CUSTOM_TEXONOMY_NAME_HERE');
        print "<a class='auther_nama' href='{$url}'>{$term->name}</a>";
      }
    }

protected by Community Sep 15 '16 at 10:55

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.