I've been struggling with this for hours.

I'm trying to get this URL structure:
By custom tax name I don't mean the name of the taxonomy ("Location"), I mean the value that is chosen for that particular post, which will be a city name. So,

So far I've made a custom taxonomy:

$singular = 'Merchant Location';
$plural = 'Merchant Locations';
$taxonomy_args = array(
    'rewrite' => array(
        'slug' => 'business-location',
        'with_front' => FALSE,
        'hierarchical' => FALSE
// Register taxonomy ...

and have changed the links in the post_type_link filter

function filter_business_permalinks($post_link, $post, $leavename, $sample) {

if ($post->post_type == 'my_custom_post_type') {
    $terms = get_the_terms($post->ID, 'my_custom_taxonomy');
     foreach ($terms as $term) {
         $post_link = str_replace('business/', 'business/'. $term->slug .'/', $post_link);

return $post_link;
add_filter('post_type_link', 'filter_business_permalinks', 10, 4);

And the resulting URL is fine after that, just what I wanted, so the filter function is working perfectly. However when I click the URL, it goes to this:
which yields a 404.

What could be causing this and how could I fix it?

All help is greatly appreciated.

What I don't want is a URL structure like this:
having the taxonomy name in the URL.

1 Answer 1


Here's the method I use to get what you're trying to achieve.

First, register your location taxonomy:

    array( 'business' ),
        'rewrite' => array( 'slug' => 'business-location' )

Next, register the business post type. The important bit to note here is the inclusion of the %location% rewrite tag in the slug. We'll use that to replace with the location term in the post_type_link function:

        'label' => 'Business',
        'public' => true,
        'rewrite' => array( 'slug' => 'business/%location%' ),
        'hierarchical' => false

Now the function to swap in the location term:

function wpa_business_permalinks( $post_link, $id = 0 ){
    $post = get_post($id);
    if ( is_object( $post ) && $post->post_type == 'business' ){
        $terms = wp_get_object_terms( $post->ID, 'location' );
        if( $terms ){
            return str_replace( '%location%' , $terms[0]->slug , $post_link );
    return $post_link;
add_filter( 'post_type_link', 'wpa_business_permalinks', 1, 2 );
  • Thanks for the reply. I've flushed the permalinks and now this works: example.com/business but this doesn't: example.com/business/long-island-city/business-name/
    – Jordan
    Commented Jul 9, 2013 at 3:10
  • Do I have to add any rewrite rules using add_rewrite_rules() or the rewrite_rules_array filter? I've tried that before and it might have been the cause of an unusual redirection on the site
    – Jordan
    Commented Jul 9, 2013 at 3:15
  • no extra rewrites necessary, that's what the rewrite slug of register_post_type takes care of. do you have a front prefix on your post permalinks? you may need to add 'with_front' => false if that's the case. the above code is tested and working in twentytwelve theme.
    – Milo
    Commented Jul 9, 2013 at 3:17
  • The Permalinks option in Settings > Permalinks is set to 'Post Name' and all with_front options are set to false. After flushing the rules, neither example.com/business/ nor example.com/business/long-island-city/business-name work :/
    – Jordan
    Commented Jul 9, 2013 at 3:27
  • example.com/business/business-name/ won't work, there's no rewrite rule to handle that. if you mean example.com/business/ should show a post type archive, then you have to set 'has_archive' => 'business'. I have no explanation as to why your post type links aren't working though, without seeing your present code. I assume you're correctly registering types on init and have set the arguments as I have them above.
    – Milo
    Commented Jul 9, 2013 at 3:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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