Make post slug have priority over category slug

There isn’t a clean way to do what you’re asking. What you want is for WordPress to check to see if, for a given URL, there is a post with that slug, and if not, try to find a category with that slug. With the exception of pages, WordPress doesn’t check to see if an opject (post, term) exists before “committing” to a matching rewrite rule. Therefore, when you have conflicting rewrite rules, the second one will never be read.

The best answer is to find a different rewrite structure for your posts or categories. Prefixes are ideal, like /blog/%postname%/, /articles/%postname%/ for posts, or /category/%category%/, /topic/%category%/ for categories.

That said, it’s not impossible to do what you’re asking, it’s just not optimal. What you need to do is intercept the request and check to see if the post exists. If not, alter the query vars. Note that this adds to every post’s page load, so weigh the costs against the benefits. Also remember that if a post and category share the same name, there’s no accessing the category. Without further ado,

function wpse_75604_check_rewrite_conflicts( $qv ) {
    if ( isset( $qv['name'] ) ) {
        if ( ! get_page_by_path( $qv['name'], OBJECT, 'post' ) ) {
            $qv['category_name'] = $qv['name'];
            unset( $qv['name'] );
        }
    }
    return $qv;
}
add_filter( 'request', 'wpse_75604_check_rewrite_conflicts' );

Leave a Comment