Index: modules/user/user-picture.tpl.php
===================================================================
RCS file: modules/user/user-picture.tpl.php
diff -N modules/user/user-picture.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/user/user-picture.tpl.php	31 Jul 2007 14:36:33 -0000
@@ -0,0 +1,19 @@
+<?php
+// $Id
+/**
+ * @file user-picture.tpl.php
+ * Default theme implementation to present an picture configured for the
+ * user's account.
+ *
+ * Available variables:
+ * - $picture: Image set by the user or the site's default. Will be linked
+ *   depending on the viewer's permission to view the users profile page.
+ * - $account: Array of account information. Potentially unsafe. Be sure to
+ *   check_plain() before use.
+ *
+ * @see template_preprocess_user_picture()
+ */
+?>
+<div class="picture">
+  <?php print $picture; ?>
+</div>
Index: modules/user/user-profile-category.tpl.php
===================================================================
RCS file: modules/user/user-profile-category.tpl.php
diff -N modules/user/user-profile-category.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/user/user-profile-category.tpl.php	31 Jul 2007 14:36:33 -0000
@@ -0,0 +1,33 @@
+<?php
+// $Id
+/**
+ * @file user-profile-category.tpl.php
+ * Default theme implementation to present profile categories.
+ *
+ * Categories (field groups) can be defined when creating profile fields for
+ * the site. All profile fields for a given category will be output through
+ * the $fields variable.
+ *
+ * @see user-profile-field.tpl.php where each profile field is rendered. It is
+ *      implemented as a definition list.
+ * @see user-profile.tpl.php where the categories (field groupings) and fields
+ *      are invoked with drupal_render().
+ *
+ * Available variables:
+ * - $title: Title assigned for the profile category.
+ * - $fields: All the fields as it is rendered through
+ *   user-profile-item.tpl.php.
+ * - $attributes: HTML attributes. Usually renders classes.
+ * - $element: Array of raw values for the category. It is unsafe so be sure
+ *   clean the data with check_plain() before use.
+ *
+ * @see template_preprocess_user_profile_category()
+ */
+?>
+<?php if ($title) : ?>
+  <h3><?php print $title; ?></h3>
+<?php endif; ?>
+
+<dl<?php print $attributes; ?>>
+  <?php print $fields; ?>
+</dl>
Index: modules/user/user-profile-field.tpl.php
===================================================================
RCS file: modules/user/user-profile-field.tpl.php
diff -N modules/user/user-profile-field.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/user/user-profile-field.tpl.php	31 Jul 2007 14:36:33 -0000
@@ -0,0 +1,26 @@
+<?php
+// $Id
+/**
+ * @file user-profile-field.tpl.php
+ * Default theme implementation to present profile fields.
+ *
+ * This template iterates through and renders each profile field configured
+ * for the site. It is grouped by categories.
+ *
+ * @see user-profile-category.tpl.php for the parent markup. Implemented here
+ *      as a definition list.
+ * @see user-profile.tpl.php where the fields and categories (field groupings)
+ *      are invoked with drupal_render().
+ *
+ * Available variables:
+ * - $title: Title assigned for the profile field.
+ * - $value: Value for the profile field.
+ * - $attributes: HTML attributes. Usually renders classes.
+ * - $element: Array of raw values for the category. It is unsafe so be sure
+ *   clean the data with check_plain() before use.
+ *
+ * @see template_preprocess_user_profile_field()
+ */
+?>
+<dt<?php print $attributes; ?>><?php print $title; ?></dt>
+<dd<?php print $attributes; ?>><?php print $value; ?></dd>
Index: modules/user/user-profile.tpl.php
===================================================================
RCS file: modules/user/user-profile.tpl.php
diff -N modules/user/user-profile.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/user/user-profile.tpl.php	31 Jul 2007 14:36:33 -0000
@@ -0,0 +1,55 @@
+<?php
+// $Id
+/**
+ * @file user-profile.tpl.php
+ * Default theme implementation to present user profile fields and categories
+ * (field groups).
+ *
+ * This template is used when viewing a registered member's profile page,
+ * e.g., example.com/user/123. 123 being the users ID.
+ *
+ * In order to customize, replace the HTML below with your own wrapper and use
+ * drupal_render($profile['foo']) or drupal_render($profile['foo']['bar']) to
+ * print them out where you want each piece of the data to appear. Replace the
+ * 'foo' and 'bar' in the example above with the desired element, e.g.,
+ * drupal_render($profile['contact']['profile_phone']). Each key will
+ * correspond to profile categories and fields configured for the site.
+ *
+ * In the above example, the first key of 'contact' is the category. This
+ * value would be configured by a site administrator.
+ * @see user-profile-category.tpl.php where the html is handled for the group.
+ *
+ * The 'profile_phone' key is the child of the 'contact' group. In this
+ * example, it would contain the value of a textfield the user has entered for
+ * their phone number.
+ * @see user-profile-field.tpl.php where the html is handled for the field.
+ *
+ * drupal_render() will keep track of what has been rendered. After printing
+ * out all the specific groups or fields, make sure to call
+ * drupal_render($profile) one last time so it can output all the other groups
+ * and fields that were not specifically called.
+ *
+ * Also keep in mind when targeting specific fields with drupal_render(), the
+ * template for rendering categories will not be used.
+ * user-profile-category.tpl.php and user-profile-field.tpl.php contain html
+ * markup which are dependent to one another. <dl> inside categories and <dt>
+ * & <dd> for the fields. Make sure a matching parent tag is used as a wrapper
+ * in this template when directly rendering fields.
+ * 
+ * To check for all available field groups and fields, use the code below.
+ * Anything preceded with a "#" can be ignored. They are used for internal
+ * processing.
+ *
+ *   <?php print '<pre>'. check_plain(print_r($profile, 1)) .'</pre>'; ?>
+ *
+ * Available variables:
+ * - $profile: Array of profile categories and items. Data is unsafe.
+ *   drupal_render() does the cleaning.
+ * - $account: Array of account information. Potentially unsafe. Be sure to
+ *   check_plain() before use.
+ */
+?>
+<div class="profile">
+
+  <?php print drupal_render($profile); ?>
+</div>
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.824
diff -u -p -r1.824 user.module
--- modules/user/user.module	27 Jul 2007 13:08:17 -0000	1.824
+++ modules/user/user.module	31 Jul 2007 14:36:34 -0000
@@ -31,18 +31,19 @@ function user_theme() {
   return array(
     'user_picture' => array(
       'arguments' => array('account' => NULL),
+      'file' => 'user-picture',
     ),
     'user_profile' => array(
-      'arguments' => array('account' => NULL),
-      'file' => 'user_profile',
+      'arguments' => array('account' => NULL, 'profile' => NULL),
+      'file' => 'user-profile',
     ),
     'user_profile_category' => array(
       'arguments' => array('element' => NULL),
-      'file' => 'user_profile_category',
+      'file' => 'user-profile-category',
     ),
-    'user_profile_item' => array(
+    'user_profile_field' => array(
       'arguments' => array('element' => NULL),
-      'file' => 'user_profile_item',
+      'file' => 'user-profile-field',
     ),
     'user_list' => array(
       'arguments' => array('users' => NULL, 'title' => NULL),
@@ -555,7 +556,7 @@ function user_user($type, &$edit, &$acco
       '#title' => t('History'),
     );
     $account->content['summary']['member_for'] =  array(
-      '#type' => 'user_profile_item',
+      '#type' => 'user_profile_field',
       '#title' => t('Member for'),
       '#value' => format_interval(time() - $account->created),
     );
@@ -719,8 +720,18 @@ function user_block($op = 'list', $delta
   }
 }
 
-function theme_user_picture($account) {
+/**
+ * Process variables for user-picture.tpl.php.
+ *
+ * The $variables array contains the following arguments:
+ * - $account
+ *
+ * @see user-picture.tpl.php
+ */
+function template_preprocess_user_picture(&$variables) {
+  $variables['picture'] = '';
   if (variable_get('user_pictures', 0)) {
+    $account = $variables['account'];
     if (!empty($account->picture) && file_exists($account->picture)) {
       $picture = file_create_url($account->picture);
     }
@@ -730,19 +741,22 @@ function theme_user_picture($account) {
 
     if (isset($picture)) {
       $alt = t("@user's picture", array('@user' => $account->name ? $account->name : variable_get('anonymous', t('Anonymous'))));
-      $picture = theme('image', $picture, $alt, $alt, '', FALSE);
+      $variables['picture'] = theme('image', $picture, $alt, $alt, '', FALSE);
       if (!empty($account->uid) && user_access('access user profiles')) {
-        $picture = l($picture, "user/$account->uid", array('attributes' => array('title' => t('View user profile.')), 'html' => TRUE));
+        $attributes = array('attributes' => array('title' => t('View user profile.')), 'html' => TRUE);
+        $variables['picture'] = l($variables['picture'], "user/$account->uid", $attributes);
       }
-
-      return "<div class=\"picture\">$picture</div>";
     }
   }
 }
 
 /**
  * Make a list of users.
- * @param $items an array with user objects. Should contain at least the name and uid
+ *
+ * @param $users
+ *   An array with user objects. Should contain at least the name and uid.
+ * @param $title
+ *  (optional) Title to pass on to theme_item_list().
  *
  * @ingroup themeable
  */
@@ -755,6 +769,42 @@ function theme_user_list($users, $title 
   return theme('item_list', $items, $title);
 }
 
+/**
+ * Process variables for user-profile-field.tpl.php.
+ *
+ * The $variables array contains the following arguments:
+ * - $element
+ *
+ * @see user-profile-field.tpl.php
+ * @see theme_user_profile_field()
+ */
+function template_preprocess_user_profile_field(&$variables) {
+  $variables['title'] = $variables['element']['#title'];
+  $variables['value'] = $variables['element']['#value'];
+  $variables['attributes'] = '';
+  if (isset($variables['element']['#attributes'])) {
+    $variables['attributes'] = drupal_attributes($variables['element']['#attributes']);
+  }
+}
+
+/**
+ * Process variables for user-profile-category.tpl.php.
+ *
+ * The $variables array contains the following arguments:
+ * - $element
+ *
+ * @see user-profile-category.tpl.php
+ * @see theme_user_profile_category()
+ */
+function template_preprocess_user_profile_category(&$variables) {
+  $variables['title'] = $variables['element']['#title'];
+  $variables['fields'] = $variables['element']['#children'];
+  $variables['attributes'] = '';
+  if (isset($variables['element']['#attributes'])) {
+    $variables['attributes'] = drupal_attributes($variables['element']['#attributes']);
+  }
+} 
+
 function user_is_anonymous() {
   return !$GLOBALS['user']->uid;
 }
@@ -1708,16 +1758,14 @@ function user_edit_submit($form, &$form_
 }
 
 function user_view($account) {
-  global $user;
-
-  // Retrieve all profile fields and store data in content element.
-  $account->content = user_build_content($account);
   drupal_set_title(check_plain($account->name));
+  // Retrieve all profile fields to pass to theme_user_profile.
+  $profile = user_build_content($account);
   /**
    * To theme user profiles, copy modules/user/user_profile.tpl.php
    * to your theme directory, and edit it as instructed in that file's comments.
    */
-  return theme('user_profile', $account);
+  return theme('user_profile', $account, $profile);
 }
 
 /**
