admin管理员组

文章数量:1023018

Is it possible to change the author base slug according to his role? For example, authors get example/ninja/%username% and subscribers get example/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.

Is it possible to change the author base slug according to his role? For example, authors get example/ninja/%username% and subscribers get example/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.

Share Improve this question edited Apr 24, 2019 at 19:12 Maxim Zubarev asked May 12, 2011 at 21:48 Maxim ZubarevMaxim Zubarev 3074 silver badges16 bronze badges 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 Commented 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 Commented May 13, 2011 at 7:26
Add a comment  | 

1 Answer 1

Reset to default 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;
}

Is it possible to change the author base slug according to his role? For example, authors get example/ninja/%username% and subscribers get example/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.

Is it possible to change the author base slug according to his role? For example, authors get example/ninja/%username% and subscribers get example/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.

Share Improve this question edited Apr 24, 2019 at 19:12 Maxim Zubarev asked May 12, 2011 at 21:48 Maxim ZubarevMaxim Zubarev 3074 silver badges16 bronze badges 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 Commented 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 Commented May 13, 2011 at 7:26
Add a comment  | 

1 Answer 1

Reset to default 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;
}

本文标签: url rewritingChange author base slug for different roles