Изменить автора базы слаг для разных ролей

9

Можно ли изменить автора базы слизняк в зависимости от его роли? Например, авторы получают example.com/ninja/%username%, а подписчики получают example.com/trainee/%username%?

Я думаю о чем-то вроде:

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

Это должно работать для незарегистрированных посетителей, если они просматривают сайт, и это должно работать для зарегистрированных авторов и самих подписчиков.

Максим Зубарев
источник
Этот плагин делает то, что вы после. Если вы не хотите использовать плагин, вы можете найти ответ на свой вопрос в исходном коде.
supajb
Я думаю, что это невозможно, касаясь базы автора. Вам нужно будет установить отдельное правило перезаписи и отфильтровать постоянную ссылку автора.
Fuxia

Ответы:

10

В вашем примере автор переписывает изменения шаблона с /author/[authorname]/на /[author_level]/[author_name]/. Если мы позволим [author_level]быть чем-либо, мы вступим в конфликт с правилами для страниц, потому что это /[anything]/[anything]/может быть либо архив автора, либо обычная подстраница.

По этой причине мое решение предполагает, что у вас есть ограниченное количество уровней автора, поэтому мы можем явно включить их в правила перезаписи. Так /ninja/[anything]/будет авторский архив, но /not-ninja/[anything]/будет обычная страница.

Изменение структуры URL всегда состоит из двух частей: изменение URL-адресов, которые будет принимать WordPress, и изменение URL-адресов, которые будет генерировать WordPress. Сначала мы изменим URL-адреса, которые WordPress будет принимать, введя новый тег перезаписи и установив базу наших авторов для этого тега.

// 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%';
}

Если вы проверите полученные правила перезаписи с помощью моего Rewrite Analyzer, вы заметите, что он содержит дополнительные правила для простых /[author-level]/страниц. Это происходит потому, что WordPress генерирует правила для каждой части каталога, которая содержит тег перезаписи, например %author_level%. Нам это не нужно, поэтому отфильтруйте все правила переписывания авторов, которые не содержат 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;
}

Теперь WordPress должен принимать URL-адреса, используя этот новый шаблон. Осталось только изменить URL-адреса, которые он генерирует при создании ссылки на архив автора. Для этого вы можете подключиться к author_linkфильтру, как этот очень простой пример:

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;
}
Ян Фабри
источник
Но не являются ли trainee/john/и ninja/john/теперь оба действительными URI одного и того же автора? Невозможно создать каноническую постоянную ссылку для одного автора, просто изменив правила перезаписи, верно? А user_metaможет помочь…
fuxia
Да, они оба действительны, но если вы используете стандартные функции, только одна из них будет связана через author_linkфильтр. Вы также можете добавить дополнительную «каноническую проверку», как это redirect_canonical()делает ядро , если вы действительно заботитесь об этом. Я не знаю, как user_metaздесь поможет? Мой author_linkпример слишком прост, ему нужна специфическая для сайта логика, чтобы отделить ниндзя от учеников.
Ян Фабри
Это все еще действительно хорошее решение, спасибо большое! что вы имеете ввиду с сайт-специфической логикой?
Максим Зубарев
@dotwired: Ну, потому что я не знаю, как ваш сайт определяет, какие пользователи являются ниндзя, а какие - стажерами, вам придется выполнить этот author_linkфильтр самостоятельно. (На самом деле вы это сказали - авторы - ниндзя, а подписчики - стажеры, - но моего кода должно быть достаточно, чтобы завершить эту часть и быть достаточно универсальным, чтобы другие тоже могли учиться на нем.)
Ян Фабри
Запускается ли author_rewrite_rulesна каждой странице загрузка?
Генрирайт