Modifier le slug de base de l'auteur pour différents rôles

9

Est-il possible de changer le slug de base de l'auteur en fonction de son rôle? Par exemple, les auteurs obtiennent example.com/ninja/%username% et les abonnés obtiennent example.com/trainee/%username%?

Je pense à quelque chose comme:

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

Cela devrait fonctionner pour les visiteurs non enregistrés s'ils naviguent sur le site et cela devrait fonctionner pour les auteurs connectés et les abonnés eux-mêmes.

Maxim Zubarev
la source
Ce plugin fait ce que vous recherchez. Si vous ne souhaitez pas utiliser de plugin, vous pourrez peut-être trouver la réponse à votre question dans le code source.
supajb
Je pense que ce n'est pas possible en touchant la base des auteurs. Vous devrez configurer une règle de réécriture distincte et filtrer le lien permanent de l'auteur.
fuxia

Réponses:

9

Dans votre exemple, le modèle de réécriture de l'auteur passe de /author/[authorname]/à /[author_level]/[author_name]/. Si nous permettons [author_level]d'être quoi que ce soit, nous entrerons en conflit avec les règles pour les pages, car il /[anything]/[anything]/peut s'agir d'une archive d'auteur ou d'une sous-page régulière.

Pour cette raison, ma solution suppose que vous avez un nombre limité de niveaux d'auteur, nous pouvons donc les mettre explicitement dans les règles de réécriture. Ce /ninja/[anything]/sera donc une archive d'auteur, mais ce /not-ninja/[anything]/sera une page régulière.

La modification de la structure des URL se compose toujours de deux parties: la modification des URL que WordPress acceptera et la modification des URL que WordPress générera. Nous allons d'abord modifier les URL que WordPress acceptera en introduisant une nouvelle balise de réécriture et en définissant notre base d'auteur sur cette balise.

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

Si vous vérifiez les règles de réécriture résultantes avec mon analyseur de réécriture, vous remarquerez qu'il contient des règles supplémentaires pour les /[author-level]/pages simples . Cela se produit car WordPress génère des règles pour chaque partie de répertoire qui contient une balise de réécriture, comme %author_level%. Nous n'en avons pas besoin, alors filtrez toutes les règles de réécriture d'auteur qui ne contiennent pas de 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;
}

Maintenant, WordPress devrait accepter les URL utilisant ce nouveau modèle. La seule chose qui reste à faire est de modifier les URL qu'il génère lorsqu'il crée un lien vers une archive d'auteur. Pour cela, vous pouvez vous connecter au author_linkfiltre, comme cet exemple très basique:

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;
}
Jan Fabry
la source
Mais ne sont-ils pas trainee/john/et ninja/john/maintenant les deux URI valides pour le même auteur? Il n'y a aucun moyen de créer un permalien canonique pour un auteur simplement en changeant les règles de réécriture, non? A user_metapourrait aider…
fuxia
Oui, ils sont tous les deux valides, mais si vous utilisez les fonctions standard, une seule d'entre elles sera liée, via le author_linkfiltre. Vous pouvez également ajouter une «vérification canonique» supplémentaire, tout comme le noyau redirect_canonical(), si vous vous souciez vraiment de cela. Je ne sais pas comment ça user_metava aider ici? Mon author_linkexemple est trop simple, il a besoin d'une logique spécifique au site pour séparer les ninjas des stagiaires.
Jan Fabry
C'est toujours une très bonne solution, merci beaucoup! que voulez-vous dire par logique spécifique au site?
Maxim Zubarev
@dotwired: Eh bien, parce que je ne sais pas comment votre site définit quels utilisateurs sont des ninjas et quels sont les stagiaires, vous devrez compléter ce author_linkfiltre vous-même. (En fait, vous l'avez dit - les auteurs sont des ninjas et les abonnés sont des stagiaires - mais mon code devrait être suffisant pour compléter cette partie et être suffisamment générique pour que les autres puissent en apprendre aussi.)
Jan Fabry
Fonctionne author_rewrite_rulesà chaque chargement de page?
henrywright