Change author base slug for different roles

Is it possible to change the author base slug according to his role? For example, authors get example.com/ninja/%username% and subscribers get example.com/trainee/%username%?

I am thinking of something like:

Read More
add_action('init', 'set_new_author_base');
function set_new_author_base() {
  global $wp_rewrite;

  if($user->role == 'subscriber')
    $author_slug = 'trainee';
    $wp_rewrite->author_base = $author_slug;
  } elseif($user->role == 'author') {
    $author_slug = 'ninja';
    $wp_rewrite->author_base = $author_slug;
  }
}

It should work for unregistered visitors if they browse the site and it should work for the logged in authors and subscribers themselves.

Related posts

Leave a Reply

1 comment

  1. In your example, the author rewrite pattern changes from /author/[authorname]/ to /[author_level]/[author_name]/. If we allow [author_level] to be anything, we will get into conflict with the rules for pages, because /[anything]/[anything]/ can be either an author archive or a regular subpage.

    For this reason, my solution assumes you have a limited number of author levels, so we can explicitly put them in the rewrite rules. So /ninja/[anything]/ will be an author archive, but /not-ninja/[anything]/ will be a regular page.

    Changing the URL structure always consists of two parts: changing the URLs that WordPress will accept and changing the URLs that WordPress will generate. First we will change the URLs that WordPress will accept by introducing a new rewrite tag and setting our author base to that tag.

    // I assume you define these somewhere, this is just to make the example work
    $wpse17106_author_levels = array( 'trainee', 'ninja' );
    
    add_action( 'init', 'wpse17106_init' );
    function wpse17106_init()
    {
        global $wp_rewrite;
        $author_levels = $GLOBALS['wpse17106_author_levels'];
    
        // Define the tag and use it in the rewrite rule
        add_rewrite_tag( '%author_level%', '(' . implode( '|', $author_levels ) . ')' );
        $wp_rewrite->author_base = '%author_level%';
    }
    

    If you check the resulting rewrite rules with my Rewrite Analyzer you will notice that it contains extra rules for the plain /[author-level]/ pages. This happens because WordPress generates rules for each directory part that contains a rewrite tag, like %author_level%. We don’t need these, so filter out all author rewrite rules that don’t contain an author_name:

    add_filter( 'author_rewrite_rules', 'wpse17106_author_rewrite_rules' );
    function wpse17106_author_rewrite_rules( $author_rewrite_rules )
    {
        foreach ( $author_rewrite_rules as $pattern => $substitution ) {
            if ( FALSE === strpos( $substitution, 'author_name' ) ) {
                unset( $author_rewrite_rules[$pattern] );
            }
        }
        return $author_rewrite_rules;
    }
    

    Now WordPress should accept URLs using this new pattern. The only thing left to do is change the URLs it generates when it creates a link to an author archive. For that you can hook into the author_link filter, like this very basic example:

    add_filter( 'author_link', 'wpse17106_author_link', 10, 2 );
    function wpse17106_author_link( $link, $author_id )
    {
        if ( 1 == $author_id ) {
            $author_level = 'ninja';
        } else {
            $author_level = 'trainee';
        }
        $link = str_replace( '%author_level%', $author_levels, $link );
        return $link;
    }