Hide uncategorized when no category set

ok I found a solution. Let me know if I can incur into troubles doing this.

basically we add the category to the url link programmatically.

on page request we check if the url begin with a category/subcategory name.
if so we prepend just for this request the %category% section to the permalink structure.

Nice thing is that site.com/%category%/my-article-name and site.com/my-article-name will point to the same content.
the category will be in first place but with a few tweaks you can put it where you want.

  1. set permalinks structure without category (e.g. /%year%/%monthnum%/%postname%)
  2. add the following to the functions.php

    function add_categories( $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 '/%category%' . $permalink;
      }
      $parent = $cat->parent;
      if ( !$parent )
        return $permalink;
      return _clear_uncategorized($parent, $permalink);
    }
    add_filter( 'pre_post_link', 'add_categories', 9, 3 );
    
    function custom_rewrite_basic() {
      global $wp_rewrite;
      $categories = get_the_categories();
      foreach ($categories as $cat) {
        if(strrpos($_SERVER["REQUEST_URI"], $cat) === 0 )
        {
            $wp_rewrite->permalink_structure = "/%category%" . $wp_rewrite->permalink_structure;
        }
      }
      $wp_rewrite->flush_rules();
    }
    add_action('init', 'custom_rewrite_basic');
    
    function get_the_categories( $parent = 0, $pSlug = "" ) 
    {
        $slug = array();
        $categories = get_categories( "hide_empty=0&parent=$parent" );
        if (!$categories) return $slug;
        foreach ( $categories as $cat )
        {
            $slug[] = (($pSlug)?"https://wordpress.stackexchange.com/".$pSlug : "")."https://wordpress.stackexchange.com/".$cat->slug;
            $slug = array_merge($slug, get_the_categories( $cat->term_id, $cat->slug ));
        }
        return $slug;
    }