0

I am trying to change author slug for a custom role. A role called trip_vendor is added by my plugin but I want to change the author slug only for this role. I have a function but this changes author slug for every roles so that the new url would be example.com/operator/user.

add_filter( 'init', array( $this, 'wpte_vendor_profile_url' ) );        
function wpte_vendor_profile_url()
{
        global $wp_rewrite;
        $author_slug = 'operator';
        $wp_rewrite->author_structure = '/' . $author_slug . '/%author%';
}

I tried as suggested here but with no help.

Any help would be more than appreciable.

0

You can use add_permastruct() (with ep_mask set to EP_AUTHORS) to add the proper rewrite rules, and the author_link filter to set the proper author URL:

add_action( 'init', function(){
    add_permastruct( '%author_trip_vendor%', 'operator/%author%', [
        'ep_mask' => EP_AUTHORS,
    ] );
} );

add_filter( 'author_link', function( $link, $author_id, $author_nicename ){
    if ( user_can( $author_id, 'trip_vendor' ) ) {
        $link = '/operator/' . $author_nicename;
        $link = home_url( user_trailingslashit( $link ) );
    }
    return $link;
}, 10, 3 );

Don't forget to flush the rewrite rules — just visit the permalink settings page.

UPDATE

non-vendors profile are loaded on URL example.com/operator/admin and also on example.com/author/admin

You can fix it via one of these options:

  1. Send a "404" header ("Page not found" error)

    add_action( 'parse_request', function( $wp ){
        if ( preg_match( '#^(author|operator)/([^/]+)#', $wp->request, $matches ) ) {
            $user = get_user_by( 'login', $matches[2] );
            if (
                ( 'author' === $matches[1] && $user && user_can( $user, 'trip_vendor' ) ) ||
                ( 'operator' === $matches[1] && $user && ! user_can( $user, 'trip_vendor' ) )
            ) {
                $wp->query_vars = ['error' => 404];
            }
        }
    } );
    
  2. Redirect the user to the proper "operator" URL

    add_action( 'parse_request', function( $wp ){
        if ( preg_match( '#^(author|operator)/([^/]+)#', $wp->request, $matches ) ) {
            $user = get_user_by( 'login', $matches[2] );
            if (
                ( 'author' === $matches[1] && $user && user_can( $user, 'trip_vendor' ) ) ||
                ( 'operator' === $matches[1] && $user && ! user_can( $user, 'trip_vendor' ) )
            ) {
                $base = ( 'author' === $matches[1] ) ? 'operator' : 'author';
                wp_redirect( home_url( '/' . $base . '/' . $matches[2] ) );
                exit;
            }
        }
    } );
    
  • Thank you @Sally. I am marking it as resolved even though non-vendors profile are loaded on url example.com/operator/admin and also on example.com/author/admin. For trip_vendors, it is doing correct. – saurav.rox Mar 6 at 9:27
  • Ok I've updated the answer. It should fix the issue of having the multiple URLs. – Sally CJ Mar 13 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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