2

Dave Jesch on his site presents a way to create virtual pages in WordPress. Dave created a class "to do all the heavy lifting", as he says. I think, for my purposes this class not require changes, so I do not put it here. Also, Dave created a function (see bellow) that calls the above mentioned class to create a virtual page when is needed. I tested this method and it just works.

What I want, is to use the Dave's class and function to put on my site a list of department members with links to their virtual pages with some content from their profiles. Pages must be virtual, so I do not have to create for each new member a real page, it must be created automatically (virtually) from his profile.

This is how I create and save some extra user profile fields:

/* Add Extra Fields to the User Profile */
add_action( 'show_user_profile', 'extra_user_profile_fields' );
add_action( 'edit_user_profile', 'extra_user_profile_fields' );

function extra_user_profile_fields( $user ) { ?>
   <h3><?php _e("Academic", "blank"); ?></h3>
   <table class="form-table">
      <!-- Teaching position -->
      <tr>
      <th><label for="teaching_position"><?php _e("Teaching position"); ?></label></th>
      <td>
      <input type="text" name="teaching_position" id="teaching_position" value="<?php echo esc_attr( get_the_author_meta( 'teaching_position', $user->ID ) ); ?>" class="regular-text" /><br />
      <span class="description"><?php _e("Put here your teaching position"); ?></span>
      </td>
      </tr>
   </table>
}

/* Save Extra User Profile Fields */
add_action( 'personal_options_update', 'save_extra_user_profile_fields' );
add_action( 'edit_user_profile_update', 'save_extra_user_profile_fields' );

function save_extra_user_profile_fields( $user_id ) {
   if ( !current_user_can( 'edit_user', $user_id ) ) { return false; }
   update_user_meta( $user_id, 'teaching_position', $_POST['teaching_position'] );
}

This is the Daves's function that calls his class to create virtual pages:

function dj_create_virtual()
{
    $url = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
    if ($url == 'dave-virtual-page') {
       $args = array('slug' => 'dave-virtual-page',
          'title' => 'Dave\'s Virtual Page',
          'content' => "This can be generated content, or static content<br />
          Whatever you put here will appear on your virtual page.");
       $pg = new DJVirtualPage($args);
    }
}
add_action('init', 'dj_create_virtual');

And this is how I display currently the members list of specific department on my site (with a shortcode):

add_shortcode( 'list_of_members', 'members_listing' );
/* usage: [list_of_members department = 'psychology'] */

function members_listing( $department ) {

   $members = get_users( array( 'meta_key' => 'department', 'meta_value' => $department ) ); 

   usort($members, create_function('$a, $b', 'return strnatcasecmp($a->last_name, $b->last_name);'));

   echo '<div id="memberlist"><ul>';
   foreach ( $members as $member ) {
      echo '<li>';
      echo get_avatar($member->ID);
      /* Bellow I want to put their names in a link to their virtual pages with some information from their profiles */
      echo '<div class="authname">' . $member->first_name . ' ' . $member->last_name;
      echo '</div></li>';
   }
   echo '</ul></div>';
}

Now I want, with the Dave's class and function, to put in my (last) members_listing function the members names in links to their virtual pages with some information from their profiles. How to do this?

EDIT

Here are the functions in question as I have used them finally (many thanks to @g-m!):

function dj_create_virtual() {
   $url = trim( parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ), '/');
   if ( strpos( $url, 'users/' ) === 0 ) {
      $user_nicename = str_replace('users/', '', $url );
      $user = get_user_by( 'slug', $user_nicename );
      $user_info = array_map( function( $a ){ return $a[0]; }, get_user_meta( $user->ID ) );
      $args = array(
         'slug' => 'users/' . $user_nicename,
         'title' => $user_info['first_name'] . ' ' . $user_info['last_name'],
         'content' => get_avatar( $user->ID ));
      if( !empty( $user_info['teaching_position'] ) ) $args['content'] = $args['content'] . '<h5>Teaching position</h5>' . $user_info['teaching_position'];
      /* heare are some more user meta profile fields */
      $pg = new DJVirtualPage($args);
   }
}
add_action('init', 'dj_create_virtual');

and the members_listing function:

add_shortcode( 'list_of_members', 'members_listing' );
/* usage: [list_of_members department = 'psychology'] */

function members_listing( $department ) {
   $members = get_users( array( 'meta_key' => 'department', 'meta_value' => $department ) ); 
   usort( $members, create_function( '$a, $b', 'return strnatcasecmp($a->last_name, $b->last_name);' ) );
   echo '<div id="memberlist"><ul>';
   foreach ( $members as $member ) {
      echo '<li>';
      printf( '<div class="authname"><a href="%s">%s</a>', home_url( '/users/' . $member->user_nicename ), get_avatar( $member->ID ) );
      printf( '<div class="authname"><a href="%s">%s</a>', home_url( '/users/' . $member->user_nicename ), $member->display_name );
      if( !empty( $member->teaching_position ) ) { echo '<br />' . mb_convert_case( $member->teaching_position, MB_CASE_LOWER, 'UTF-8' ); };
      echo '</div></li>';
   }
   echo '</ul></div>';
}
1

Before answer, a side note: what you want can be done a in a lot simpler and more performant way just creating a real post type: register a cpt, maybe not public (so no ui is showed on dashboard), and on user profile saving/updating just create/update a cpt entry.

Doing so you do not need any external class and you can just use the core wp functions, to show all member pages, show single member page, link them and any other things you need.

As bonus you can also make use of the template hierarchy and have a lot more flexibility.

One my personal rule of thumb is: "never write code for custom features when core can do same thing". In your case core features don't do the same, do it better and simpler.

However, this is a Q&A site, you asked a question and this is the answer:

the dj_create_virtual function must be changed in something like this:

function dj_create_virtual() {
  $url = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
  if ( strpos($url, 'member-') === 0 ) {
    $user_nicename = str_replace('member-', '', $url);
    $user = get_user_by( 'slug', $user_nicename );
    $user_info = array_map( function( $a ){ return $a[0]; }, get_user_meta( $user->ID ) );
    $args = array(
      'slug' => 'member-' . $user_nicename,
      'title' => $user_info['first_name'] . ' ' . $user_info['last_name'],
      // following is just an example
      'content' => 'This is the page for:' . $user_info['first_name'] . ' ' . $user_info['last_name']
    );
    $pg = new DJVirtualPage($args);
  }
}
add_action('init', 'dj_create_virtual');

and your members_listing function need just a little edit:

function members_listing( $department ) {
   $members = get_users( array( 'meta_key' => 'department', 'meta_value' => $department ) ); 
   usort($members, create_function('$a, $b', 'return strnatcasecmp($a->last_name, $b->last_name);'));
   echo '<div id="memberlist"><ul>';
   foreach ( $members as $member ) {
      echo '<li>';
      echo get_avatar($member->ID);
      $user_info = array_map( function( $a ){ return $a[0]; }, get_user_meta( $member->ID ) );
      $fullname = $user_info['first_name'] && $user_info['first_name'] ? $user_info['first_name'] . ' ' . $user_info['last_name'] : $member->display_name;
      printf( '<div class="authname"><a href="%s">%s</a></div></li>', home_url('/member-' . $member->user_nicename), $fullname);
   }
   echo '</ul></div>';
}
  • @g-m Thank you! 1) I suppose, I must ask another question about creating/updating on user profile of a CPT entry. 2) Something is wrong with the printf() row, this does not display anything. – Iurie Malai Sep 5 '13 at 17:31
  • @Iurie You are welcome. 1) In your save_extra_user_profile_fields function you can use wp_insert_post to save a cpt or wp_update_post to update it if already exists. If you have problem ask new question. 2) yes, there was an error there. I've also updated little parts of all my code. Check it again, please. – gmazzap Sep 5 '13 at 18:20
  • @g-m 1) Now links goes to a 404 page. 2) I do not understand how the members_listing function calls the dj_create_virtual function or they works somehow different? – Iurie Malai Sep 6 '13 at 18:24
  • @Iurie 1) I changed a little my code, I've tested it, now it works for me. 2) members_listing is called from shortcode. dj_create_virtual is called on init hook, it's not called by members_listing. – gmazzap Sep 7 '13 at 5:40
  • @g-m Now is OK, but under the user page appear some comments from the Hello world! page (do not exists other comments on the site). How to disable this? You can see an example. P.S. How to mention here, in these comments, your displayed user name: G.M? – Iurie Malai Sep 7 '13 at 6:25

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.