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)

3 s
3

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, "https://wordpress.stackexchange.com/", 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;
}

Leave a Reply

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