How to exclude uncategorized from permalink structure /tegory%/%postname%/

I’m using a custom permalink structure:

/%category%/%postname%/

So that my posts are listed like:

Read More
mysite.com/widgets/blue-widget

This works fine as long as “blue-widget” exists in one and only one category. However, when it appears in more than one category, like perhaps a child of uncategorized, the resulting URL becomes:

mysite.com/uncategorized/child-of-uncategorized/blue-widget

Even though the post is still in “widgets”, it appears that there is something that makes uncategorized trump it. I believe its because it has the lower id.

I need to know if its possible to exclude uncategorized and any children of uncategorized from appearing in the permalink structure.

UPDATED EXAMPLE:

So, if a post is in 3 categories for example:

Widgets (parent_id=0),
Uncategorized (parent_id=0),
Child of Uncategorized (parent_id=1)

I want the filter to use “Widgets” as the permalink slug and
exclude “uncategorized” and all of its children.

If the post is in 2 or more categories that are not uncategorized or
a child of uncategorized, then just use the newest category as the
permalink slug.

If the post is assigned solely to uncategorized or one of its children, then do not display a category slug permalink

Related posts

1 comment

  1. I hope this will work for you 😀

    function mf_post_link( $permalink, $post, $leavename ) {
      if( $post->post_type != 'post' ) return $permalink;
    
      // if no category, the filter is deactivated
      $cats = get_the_category($post->ID);
      if( ! count($cats) ) return $permalink;
    
      usort($cats, '_usort_terms_by_ID'); // order by ID
      $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
    
      $category_object = get_term( $category_object, 'category' );
      $parent = $category_object->parent;
    
      // if no father, the filter is deactivated
      if ( !$parent ) return;
      $category_parent = get_term( $parent, 'category' );
    
      // if the parent is not uncategorized, the filter is deactivated
      if( $category_parent->slug != 'uncategorized' ) return $permalink;
    
      return str_replace('uncategorized/', '', $permalink);
    
    }
    add_filter( 'post_link', 'mf_post_link', 9, 3 );
    

    EDIT:

    if the post is category “uncategorized” or child of “uncategorized” as the main category, change the permalink rule of “/%category%/%postname%” to “/%postname%”

    function my_pre_post_link( $permalink, $post, $leavename ) {
      if( $post->post_type != 'post' ) return $permalink;
      $cats = get_the_category($post->ID);
      if( ! count($cats) ) return $permalink;
    
      usort($cats, '_usort_terms_by_ID');
      $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
    
      $category_object = get_term( $category_object, 'category' );
    
      return _clear_uncategorized($category_object, $permalink);
    }
    
    function _clear_uncategorized($cat, $permalink) {
      if( $cat->slug == 'uncategorized' ) {
        return str_replace('%category%/', '', $permalink);
      }
      $parent = $cat->parent;
      if ( !$parent )
        return $permalink;
      return _clear_uncategorized($parent, $permalink);
    }
    
    add_filter( 'pre_post_link', 'my_pre_post_link', 9, 3 );
    

Comments are closed.