24

I want to create a public front-end profile page with a friendly url like this format.

mysite.com/user/someusername

Any idea on how can i achieve this? I know it has something to do with rewrite rule but i have no idea on how can i do that. If you got any link or tutorial for me that will be great.

Thanks!

4 Answers 4

15

There are two ways I've discovered doing this:

  1. Author Page with a custom rewrite rule
  2. A custom template files paired with a rewrite rule

The first is more simple to implement, but may not work in all circumstances (one of which I'll describe soon).

Custom Rewrite Rule

I found this solution a few days ago here: URL Rewriting

And here's the code, with comments:

// Define the author levels you want to use
$custom_author_levels = array( 'user', 'leader' );

// On init, add a new author_level rewrite tag and add it to the author_base property of wp_rewrite
add_action( 'init', 'wpleet_init' );
function wpleet_init()
{
    global $wp_rewrite;
    $author_levels = $GLOBALS['custom_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%';

}

// The previous function creates extra author_name rewrite rules that are unnecessary.  
//This function tests for and removes them

add_filter( 'author_rewrite_rules', 'wpleet_author_rewrite_rules' );
function wpleet_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;
}

You can then use the built in author.php template, modifying to your hearts content.

Sincerely, check the link listed above, as Jan Fabry does an excellent job explaining everything.

Query Vars and Page Templates

For the theme I was working on while discovering these solutions, I needed to serve a custom page based on a user meta value (a separate ID). My client did not want the username or user ID visible publicly, so we created a separate layer.

The only problem? At the moment, there isn't a clear way how to use the Rewrite API to query by meta keys/values. Luckily, there was a solution.

In your functions.php file...

// Create the query var so that WP catches your custom /user/username url
add_filter( 'query_vars', 'wpleet_rewrite_add_var' );
function wpleet_rewrite_add_var( $vars )
{
    $vars[] = 'user';
    return $vars;
}

And then, you need to create a new rewrite tag and rule so that it knows when and how to handle the new query var.

add_rewrite_tag( '%user%', '([^&]+)' );
add_rewrite_rule(
    '^user/([^/]*)/?',
    'index.php?user=$matches[1]',
    'top'
);

Once you've done this, you merely need to "catch" when the query var is being served, and then redirect to the template of your choice:

add_action( 'template_redirect', 'wpleet_rewrite_catch' );
function wpleet_rewrite_catch()
{
    global $wp_query;

    if ( array_key_exists( 'user', $wp_query->query_vars ) ) {
        include (TEMPLATEPATH . '/user-profile.php');
        exit;
    }
}

Just make sure you have created user-profile.php.

In my own example, I created a third function that matched the "public User ID" to the actual user_id via the $wpdb->usermeta table, and passed the information to the template.

If you need to create a template different from the rest of your theme, remember that with get_header, you can specify a name:

get_header( 'user' );

Which will call the header-user.php file.

Conclusion

Both of these are valid, working solutions. The second offers a separate layer of "security" as it does not reveal user IDs or usernames, if other people will be able to browse the profiles.

Hope that helps, let me know if you have any questions.

3
  • I actually solved it using the Query_var method. Thanks!
    – tiltdown
    Commented Jul 18, 2012 at 0:36
  • 1
    @bybloggers I know this post is a bit old, but was curious if you could share your third function for passing the username in the URL to the template?
    – Pat
    Commented Mar 17, 2013 at 3:22
  • @Pat Not sure where the actual function is in all of my code at this time (as you said, it was awhile ago), but the format would follow the wpleet_rewrite_catch() function very closely. Instead of array_key_exists( 'user' ), I was testing for the public user ID, and then doing a search on the wp_usermeta table to see which user had that public ID associated with it. Hope the algorithm helps, even if the code isn't available.
    – bybloggers
    Commented Apr 3, 2013 at 23:34
2

I found this earlier today and made some modificatios to @bybloggers code with the diference that instead of using template_redirect I change the request to show a static page, that means that you can now add anything you like to a page template and use it on that page.

class ProfilePage {
function __construct() {
    add_filter( 'init',array($this,'rw_init'));
    add_filter( 'query_vars', array($this,'wpleet_rewrite_add_var') );
    add_filter( 'request', array($this,'change_requests'));
}
function wpleet_rewrite_add_var( $vars ) {
    $vars[] = 'usuario';
    return $vars;
}
function rw_init(){
    add_rewrite_tag( '%usuario%', '([^&]+)' );
    add_rewrite_rule(
        '^usuario/([^/]*)/?',
        'index.php?usuario=$matches[1]',
        'top'
    );
}
function change_requests($query_vars) {
    //go to a specific page when the usuario key is set
    $query_vars['page_id'] = isset($query_vars['usuario']) ? 7581 : $query_vars['page_id'];
    return $query_vars;
}
}
new ProfilePage();

Spanish -> usuario = user <- English

1
  • Very nice! Thanks for sharing that. I'd like to make more dynamic and you can switch the id with get_page_by_path('page-slug')->ID. Also don't forget of use flush_rewrite_rules, so I'd add like: add_action( 'after_switch_theme', 'flush_rewrite_rules' ); Commented Aug 28, 2016 at 7:12
1

This is my working code based on @bybloggers answer (thanks by the way) I just learn that we shouldn't be using template_redirect hook and then exiting php, because some things may stop working because the abrupt interruption of php executing code.

The explanation is here: https://markjaquith.wordpress.com/2014/02/19/template_redirect-is-not-for-loading-templates/

So, we should be using the template_include hook. With this hook, there is no need to use the redirect and exit method.

And the other difference is that I just needed www.server.com/myaccount without the /userid.

This is the code:

add_filter( 'query_vars', 'wp58683_userprofile_var' );
function wp58683_userprofile_var( $vars )
{
    $vars[] = 'myprofile';
    return $vars;
}

add_rewrite_tag( '%myprofile%', '([^&]+)' );

add_rewrite_rule(
    '^myprofile/?',
    'index.php?myprofile',
    'top'
);

add_action( 'template_include', 'wp58683_userprofile_page' );
function wp58683_userprofile_page($original_template)
{
    global $wp_query;

    if ( array_key_exists( 'myprofile', $wp_query->query_vars ) ) {
        if (is_user_logged_in() ){ 
            return TEMPLATEPATH . '/user-profile.php';
        }
    }
    else {
        return $original_template;
    }

}
0

Another way is to use Buddypress which have this built-in even if the plugin have even more functionality which may not be of interest.

http://wordpress.org/extend/plugins/buddypress/

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