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;
}