WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Using /%category%/%postname%/ for the permalink I get a URL string of all the categories that the specific post is included in. I would like the categories in the url to be filtered down to only one branch of the categories structure, and starting not from the root parent category.

I have a travel blog and I have this category structure:
places › countryName › regionName › cityName
ex: www.mytravelblog.com/places/indonesia/java/jakarta/myPostName/

I would like to skip the root category in the URL or even just use the smallest child
ex: www.mytravelblog.com/jakarta/myPostName

Is it possible? (WP 3.0.1)

share|improve this question
up vote 4 down vote accepted

This should be possible. First, you're lucky that www.mytravelblog.com/jakarta/myPostName/ already works, it shows you the post and doesn't redirect you to the longer version (at least it seems to work on my side). That means you only have to work on the generated link, and not mess with the way incoming URLs are handled or "canonicalized".

The result of get_permalink(), which you want to modify, is filtered through post_link. So you can probably do something like this:

add_filter( 'post_link', 'remove_parent_cats_from_link', 10, 3 );
function remove_parent_cats_from_link( $permalink, $post, $leavename )
    $cats = get_the_category( $post->ID );
    if ( $cats ) {
        // Make sure we use the same start cat as the permalink generator
        usort( $cats, '_usort_terms_by_ID' ); // order by ID
        $category = $cats[0]->slug;
        if ( $parent = $cats[0]->parent ) {
            // If there are parent categories, collect them and replace them in the link
            $parentcats = get_category_parents( $parent, false, '/', true );
            // str_replace() is not the best solution if you can have duplicates:
            // myexamplesite.com/luxemburg/luxemburg/ will be stripped down to myexamplesite.com/
            // But if you don't expect that, it should work
            $permalink = str_replace( $parentcats, '', $permalink );
    return $permalink;
share|improve this answer
works for me, thanks - it would be even awesomer to be able to specify the parent category (by name or ID) the permalink should primarily listen to. Your script works as needed for posts that are only in the 'places' category branch - but if the post is in other root categories, it sometimes uses those instead – pax Nov 15 '10 at 20:55
@pax: Indeed, the category used for the link is defined by the lowest category ID (the _usort_terms_by_ID). Maybe you should put all non-geographic "categories" in a separate taxonomy? That way the can never be used to construct the link. – Jan Fabry Nov 15 '10 at 21:08

I had thought I would just comment on it but then it would be too small a place to specify the details.

The answer posted by Jan Fabry works nicely! However the drawback of this is, which he even pointed out in the comments is that if you have a URL like http://example.com/sports/world-sports/permalink, it will be stripped down to http://example.com/world-permalink, which will actually lead to a 404.

To avoid this you can add

$parentcats = '/' . $parentcats;

So it should be like this

$parentcats = '/'. $parentcats;
$permalink = str_replace( $parentcats, '/', $permalink );

This will strip only /sports/ and not /world-sports/

Hope it helps someone !

share|improve this answer

What do you do if you have same area/town names in different regions/countries?

Another way is to keep the link but work on the content of the page, depending on the categories. U could use this:

foreach((get_the_category()) as $childcat)
  if (cat_is_ancestor_of($my_cat_id, $childcat))
    echo $child = $childcat->cat_name;
    //echo $parent = $childcat->category_parent;
share|improve this answer
Categories always have unique slugs, even if they have different ancestors. The second category created with the same name will have a slug with -2 added to it, so there will be no conflicts. – Jan Fabry Nov 15 '10 at 19:21

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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