Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

A scenario I keep coming across is where an organisation might have several staff for whom I want to have some sort of listing and a single profile page with biographical information.

Typically I would create a custom post type for staff and maybe a custom taxonomy if needed.

But now I'm wondering if it might not be optimal to use the built-in "user" post type in Wordpress. I realise I can customise the user profile fields, display user listings, single profiles etc Custom taxonomies are possible too I believe.

Is there a best practice here?

I have a case now where all staff are also writing blog posts under their own name and so have a user account anyway and it crossed my mind that maybe I'm better off just fleshing out their user profiles and working with author.php instead of using the custom post type of 'staff'.

For now I've been going with the CPT and using Posts 2 Posts plugin to associate their "staff" post with their "user" account and thereby create listings of their blog posts on their single staff page.

Any thoughts on how best to implement this in wordpress is appreciated.

share|improve this question
add comment

1 Answer 1

If people you want to show pubblically on site are user, i.e. have an account an write posts, in my opinion is much better using the worpress user functionality: every information you should put on CPT you can put in user metadata, too, but create users is mandatory (they have to login) create CPT can be avoided and so, for me, is a duplicate.

However I know that using CPT can be simpler, for some reasons:

  1. Default profile page on wp admin has little informations
  2. In WP there is no public profile page at all: author.php is not a profile page
  3. In addition to profile page, you probably want to loop through staff people, and of course you can use WP_User_Query to do this, but isolate staff people from users that must be hidden can be a little hard: there is no user taxonomy and using user roles can generate problem if you want assign the public role to any user that must stay not publicly visible

Luckily these problems are not real problems and can be solved easily. The workflow I suggest you is:

  1. Create a new user role. You can clone capabilities from a standard role, but creating a role, isolate staff from other users will be super-easy
  2. Add custom fields for user profile where put all information you want
  3. Create a page template that will handle the users loop and the user profile. How? Look at point 4.
  4. Create a rewrite endpoint, in this way an url like yoursite.com/staff will call a page (the one you assign the template created on 3.) and an url like yoursite.com/staff/user/nickname will call the same page but passing the query var user with value nickname that you can use in the page to show the user profile

1., 2. and 4. can be easily done in a plugin. I will give you the bones of this plugin, that should be improved:

<?php
/**
 * Plugin Name: Staff Plugin
 * Description: Test
 * Author: G.M.
*/

/**
* Add a new role cloning capabilities from editor and flush rewrite rules
*/
function install_staff_plugin() {
    $editor = get_role( 'editor' );
    add_role('staff', 'Staff', $editor->capabilities );
    staff_plugin_endpoint();
    flush_rewrite_rules();
}

/**
* Remove the role and flush rewrite rules
*/
function unistall_staff_plugin() {
    remove_role( 'staff' );
    flush_rewrite_rules();
}

/**
* Add the endpoint
*/
function staff_plugin_endpoint() {
    add_rewrite_endpoint( 'user', EP_PAGES );
}

/**
* Add custom field to profile page
*/
function staff_plugin_profile_fields( $user ) {
    $fields = array(
        'facebook' => __('Facebook'),
        'twitter' => __('Twitter'),
        'photo_id' => __('Photo ID (use attachment id)')
    );
    echo '<h3>' . __('Staff Information') . '</h3>';
    echo '<table class="form-table">';
    foreach ( $fields as $field => $label ) {
        $now = get_user_meta( $user->ID, $field, true ) ? : "";
        printf( '<tr><th><label for="%s">%s</label></th>', esc_attr($field), esc_html($label) );
        printf( '<td><input type="text" name="%s" id="%s" value="%s" class="regular-text" /><br /></td></tr>', esc_attr($field), esc_attr($field), esc_attr($now) );
    }
    echo '</table>';
}

/**
* Save the custom fields
*/
function staff_plugin_profile_fields_save( $user_id ) {
    if ( ! current_user_can( 'edit_user', $user_id ) ) return;
    $fields = array('facebook','twitter','photo_id');
    foreach ( $fields as $field ) {
        if ( isset($_POST[$field]) ) update_user_meta( $user_id, $field, $_POST[$field] );
    }
}

add_action( 'init', 'staff_plugin_endpoint' );
add_action( 'show_user_profile', 'staff_plugin_profile_fields' );
add_action( 'edit_user_profile', 'staff_plugin_profile_fields' );
add_action( 'personal_options_update', 'staff_plugin_profile_fields_save' );
add_action( 'edit_user_profile_update', 'staff_plugin_profile_fields_save' );
register_activation_hook( __FILE__, 'install_staff_plugin' );
register_deactivation_hook( __FILE__, 'unistall_staff_plugin' );

The plugin do exactly what I said. Regarding add custom fields for user profile, as example, I added just 3 fields. One of them is intended to be used for user image and accept the id of an attachment. Of course in real world is better call the media uploader an let the user choose or upload an image, but this is not the scope of this answer...

After plugin is saved and activated we have to create the page template, create a page and assign that template. Again I will post here a proof of concept for the template:

<?php
/**
* Template Name: Staff Page
*
*/

get_header(); ?>

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

<?php
/* The page content */
while ( have_posts() ) : the_post();
  $page_link = get_permalink();
  the_content();
endwhile;
?>

<?php

$required_user = get_query_var('user');

$wanted_meta = array(
  'first_name', // this is a standard meta
  'facebook', // this is an example of custom meta
  'twitter' // this is another example of custom meta
);

if ( empty($required_user) ) {

/* The Users Loop */

// customize the args as you need
$args = array (
  'role' => 'Staff',
  'orderby' => 'post_count',
  'order' => 'DESC',
  'fields' => 'all'
);
$user_query = new WP_User_Query( $args );
if ( ! empty( $user_query->results ) ) { foreach ( $user_query->results as $user ) {
  $profile_url = trailingslashit($page_link) . 'user/' . $user->user_nicename;
  $meta_fields = get_user_meta($user->ID); // this get ALL the meta fields as a 2 dimensional array (array of arrays)
?>
  <div id="user-<?php echo $user->ID ?>">
  <?php
  // an example of custom meta where to save the id of an attachment
  if ( isset($meta_fields['photo_id'][0]) && ! empty($meta_fields['photo_id'][0]) ) {
    echo '<a href="' . esc_url($profile_url) . '/">';
    echo wp_get_attachment_image( $meta_fields['photo_id'][0], 'medium' );
    echo '</a>';
  }
  ?>
  <h2><?php echo '<p><a href="' .esc_url($profile_url) . '/">' . $user->display_name . '</a></p>';?></h2>
  <p><?php echo $meta_fields['description'][0]; ?></p>
  <ul>
  <?php
  foreach ( $wanted_meta as $key ) { if ( isset($meta_fields[$key][0]) && ! empty($meta_fields[$key][0]) ) {
  ?>
  <li><?php echo $meta_fields[$key][0]; ?></li>
  <?php } } ?>
  </ul>
  </div>
  <?php
  }
}

} else {

/* One User Requested */

  $user = get_user_by( 'slug', $required_user );
  if ( $user ) {
  ?>
  <div id="user-<?php echo $user->ID ?>">
  <?php
  $meta_fields = get_user_meta($user->ID);
  if ( isset($meta_fields['photo_id'][0]) && ! empty($meta_fields['photo_id'][0]) ) {
  echo wp_get_attachment_image( $meta_fields['photo_id'][0], 'full' );
  }
  ?>
  <h1><?php echo '<p>' . $user->display_name . '</p>';?></h1>
  <p><?php echo $meta_fields['description'][0]; ?></p>
  <p>
  <a href="<?php echo get_author_posts_url($user->ID); ?>"><?php printf(__('See all posts by %s'), $user->display_name); ?></a> | 
  <a href="<?php echo $page_link; ?>"><?php _e('Back to Staff'); ?></a>
  </p>
  <ul>
  <?php
  foreach ( $wanted_meta as $key ) {
    if ( isset($meta_fields[$key][0]) && ! empty($meta_fields[$key][0]) ) {
    ?>
    <li><?php echo $meta_fields[$key][0]; ?></li>
    <?php } } ?>
  </ul>
  </div>
  <?php
  }
}
?>

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

<?php get_footer(); ?>

Now create a page and assign this template. Then assign the user role 'staff' to your staff people and fill profiles.

As final touch, in your author.php you can add, probably in the header, something like this:

<div class="author-info">
<?php
$curauth = (get_query_var('author_name')) ? get_user_by('slug', get_query_var('author_name')) : get_userdata(get_query_var('author'));
$photo = get_user_meta($curauth->ID, 'photo_id', true);
if ( $photo ) echo wp_get_attachment_image( $photo, 'medium' );
?>
<h2><?php echo $curauth->display_name; ?></h2>
<h3><em><?php echo $curauth->user_description; ?></em></h3>
</div>

That's all. Test it, improve it and have funny with it.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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