I have created a system whereby users can sign up and then be searched for on the frontend. The search uses WP_User_Query and works great.

I want each user to have their own profile page, which shows all sorts of info tied to their account. All of the data is there, but I'm unsure how or where I can build these profile pages.

The URLs of these pages will be /member/[slug]/[ID] EG: /member/mike/32

I'd like a theme file that is called when this route is hit. I've thought about having a rewrite rule within .htaccess and a flat .php file that calls wp-load.php, and then attempts to load the header and footer. That seems to be extremely nonsensical to me though.

Any help is appreciated.

1 Answer 1


You can add a new endpoint for your profile page. There's no need to manage anything with the htaccess. WordPress will do it for you.

codex: add_rewrite_endpoint

Another way (half solution) is to create a template file and load it via template_include hook. But it will not get the user name (as it is).

add_filter( 'template_include',  array($this, 'profile_page'), 99 );

function profile_page($templates){
    if ( is_page( 'profile-page' ) ) {
        $new_template = YOURPLUGIN_DIR .'templates/profile-page';
        if ( '' != $new_template ) {
            return $new_template ;

Create a page with permalink set to profile-page and create functions and profile page content...


Here a rewrite complete class for a profile user page, without the need to create a page.

class wpse242114{

public function __construct(){

    add_action( 'wp_loaded', array($this,'_flush_rules') );
    add_filter( 'rewrite_rules_array', array($this,'_insert_rewrite_rules') );
    add_filter( 'query_vars', array($this,'_insert_query_vars') );
    add_filter( 'template_include',  array($this, '_get_plugin_template'), 99 );

public function _flush_rules() {
    $rules = get_option( 'rewrite_rules' );

    if ( ! isset( $rules['(profile)/(\d*)$'] ) ) {
        global $wp_rewrite;

public function _insert_rewrite_rules( $rules ) {
$newrules = array();
$newrules['(profile)/(\d*)$'] = 'index.php?pagename=$matches[1]&id=$matches[2]';
return $newrules + $rules;

public function _insert_query_vars( $vars ) {
array_push( $vars, 'id' );
return $vars;

public function _get_plugin_template($template){
    global $wp_query;

    if ( $wp_query->query['name'] == 'profile') {

        $new_template = APIKEYABLE_DIR .'includes/templates/page-login.php';
        if ( '' != $new_template ) {
            return $new_template ;

    return $template;

The template file example:

<?php get_header(); ?>

<div class="container">
   <div id="main-grid" class="row">

      <div id="primary" class="content-area col-md-8">
        <main id="main" class="site-main" role="main">

        $userid = get_current_user_id();

        $user = new WP_User($userid);

        if ( $user->exists() ) {
            // do something


       </main><!-- #main -->
    </div><!-- #primary -->

  <?php get_sidebar(); ?>

</div><!-- .row -->

  • That link is empty. How does it know what template to load, and how can I define the route? Thanks
    – mikemike
    Oct 9, 2016 at 19:45
  • @mikemike the link has been fixed
    – Michal Mau
    Oct 9, 2016 at 20:32
  • Hmmm, I think it's close but I'm not sure how I can achieve what I need with that. I was sort of hoping for a function that allows a route to be defined that points to a file in the theme, like: add_rewrite_page('member/(:s)/(:n)', 'memberprofile.php');
    – mikemike
    Oct 9, 2016 at 20:36
  • @mikemike : I edit my answer
    – Benoti
    Oct 10, 2016 at 15:30
  • Thanks @Benoti but I can't get this working. I created a file called wpse242114.php, included it into my functions.php then called new wpse2421124();. If I add a die() into __construct(); that works so the file is being called and processed. If I visit /profile, /profile/123 or /profile/test/123 I just get a 404 as though the rewrite rule hasn't been defined. No errors. Any idea?
    – mikemike
    Oct 11, 2016 at 7:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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