11

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:

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.

2
  • This plugin does what you're after. If you don't want to use a plugin you might be able to find the answer to your question in the source code.
    – supajb
    May 13, 2011 at 1:41
  • I think it is not possible by touching the author base. You’ll have to set up a separate rewrite rule and filter the author permalink.
    – fuxia
    May 13, 2011 at 7:26

1 Answer 1

12

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;
}
6
  • But aren’t trainee/john/ and ninja/john/ now both valid URIs for the same author? There is no way to create a canonical permalink for one author just by changing the rewrite rules, right? A user_meta could help …
    – fuxia
    May 13, 2011 at 11:02
  • Yes, they are both valid, but if you use the standard functions only one of them will be linked to, via the author_link filter. You can also add an extra "canonical check" just like the core redirect_canonical() does, if you really care about this. I don't know how user_meta will help here? My author_link example is too simple, it needs site-specific logic to separate the ninjas from the trainees.
    – Jan Fabry
    May 13, 2011 at 11:37
  • This is still a really nice solution, thank you so much! what to you mean with site-specific logic? May 13, 2011 at 11:46
  • @dotwired: Well, because I don't know how your site defines which users are ninjas and which are trainees, you will have to complete that author_link filter yourself. (Actually you did tell it - Authors are ninjas and Subscribers are trainees - but my code should be enough to complete that part and be generic enough so others can learn from it too.)
    – Jan Fabry
    May 13, 2011 at 13:09
  • Does author_rewrite_rules run on every page load? Mar 15, 2014 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.