=== added file 'themes/engines/phptemplate/user_profile.tpl.php'
--- /dev/null	
+++ themes/engines/phptemplate/user_profile.tpl.php	
@@ -0,0 +1,3 @@
+<div class="profile">
+  <?php print $account->content; ?>
+</div>
=== modified file 'modules/blog/blog.module'
--- modules/blog/blog.module	
+++ modules/blog/blog.module	
@@ -48,9 +48,11 @@ function blog_access($op, $node) {
  */
 function blog_user($type, &$edit, &$user) {
   if ($type == 'view' && user_access('edit own blog', $user)) {
-    $items[] = array('title' => t('Blog'),
-      'value' => l(t('view recent blog entries'), "blog/$user->uid", array('title' => t("Read @username's latest blog entries.", array('@username' => $user->name)))),
-      'class' => 'blog',
+    $user->content['summary']['blog'] =  array(
+      '#type' => 'profile_item',
+      '#title' => t('Blog'),
+      '#value' => l(t('view recent blog entries'), "blog/$user->uid", array('title' => t("Read @username's latest blog entries.", array('@username' => $user->name)))),
+      '#attributes' => array('class' => 'blog'),
     );
     return array(t('History') => $items);
   }
=== modified file 'modules/profile/profile.css'
--- modules/profile/profile.css	
+++ modules/profile/profile.css	
@@ -4,14 +4,24 @@
   clear: both;
   margin: 1em 0;
 }
+
 .profile .picture {
   float: right;
   margin: 0 1em 1em 0;
 }
+
+.profile h3 {
+  border-bottom: 1px solid #ccc;
+}
+
+.profile dl {
+  margin: 0 0 1.5em 0;
+}
+
 .profile dt {
-  margin: 1em 0 0.2em 0;
+  margin: 0 0 0.2em 0;
   font-weight: bold;
 }
 .profile dd {
-  margin:0;
+  margin:0 0 1em 0;
 }
=== modified file 'modules/profile/profile.module'
--- modules/profile/profile.module	
+++ modules/profile/profile.module	
@@ -590,7 +590,7 @@ function profile_view_field($user, $fiel
   }
 }
 
-function profile_view_profile($user) {
+function profile_view_profile(&$user) {
 
   profile_load_profile($user);
 
@@ -606,14 +606,24 @@ function profile_view_profile($user) {
     if ($value = profile_view_field($user, $field)) {
       $description = ($field->visibility == PROFILE_PRIVATE) ? t('The content of this field is private and only visible to yourself.') : '';
       $title = ($field->type != 'checkbox') ? check_plain($field->title) : NULL;
-      $item = array('title' => $title,
-        'value' => $value,
-        'class' => $field->name,
+
+      // create a single fieldset for each category
+      if (!isset($user->content[$field->category])) {
+        $user->content[$field->category] = array(
+          '#type' => 'profile_category',
+          '#title' => $field->category,
+        );
+      }
+
+      $user->content[$field->category][$field->name] = array(
+        '#type' => 'profile_item',
+        '#title' => $title,
+        '#value' => $value,
+        '#weight' => $field->weight,
+        '#attributes' => array('class' => 'profile-'. $field->name),
       );
-      $fields[$field->category][] = $item;
     }
   }
-  return $fields;
 }
 
 function _profile_form_explanation($field) {
=== modified file 'modules/user/user.module'
--- modules/user/user.module	
+++ modules/user/user.module	
@@ -443,14 +443,23 @@ function user_search($op = 'search', $ke
 /**
  * Implementation of hook_user().
  */
-function user_user($type, &$edit, &$user, $category = NULL) {
+function user_user($type, &$edit, &$account, $category = NULL) {
   if ($type == 'view') {
-    $items['history'] = array('title' => t('Member for'),
-      'value' => format_interval(time() - $user->created),
-      'class' => 'member',
+    $account->content['user_picture'] = array(
+      '#value' => theme('user_picture', $account),
+      '#weight' => -10,
+    );
+    $account->content['summary'] = array(
+      '#type' => 'profile_category',
+      '#attributes' => array('class' => 'user-member'),
+      '#weight' => -5,
+      '#title' => t('History'),
+    );
+    $account->content['summary']['member_for'] =  array(
+      '#type' => 'profile_item',
+      '#title' => t('Member for'),
+      '#value' => format_interval(time() - $account->created)
     );
-
-    return array(t('History') => $items);
   }
   if ($type == 'form' && $category == 'account') {
     return user_edit_form(arg(1), $edit);
@@ -619,32 +628,13 @@ function theme_user_picture($account) {
 /**
  * Theme a user page
  * @param $account the user object
- * @param $fields a multidimensional array for the fields, in the form of array (
- *   'category1' => array(item_array1, item_array2), 'category2' => array(item_array3,
- *    .. etc.). Item arrays are formatted as array(array('title' => 'item title',
- * 'value' => 'item value', 'class' => 'class-name'), ... etc.). Module names are incorporated
- * into the CSS class.
  *
  * @ingroup themeable
  */
-function theme_user_profile($account, $fields) {
+function theme_user_profile($account) {
   $output = '<div class="profile">';
-  $output .= theme('user_picture', $account);
-  foreach ($fields as $category => $items) {
-    if (strlen($category) > 0) {
-      $output .= '<h2 class="title">'. $category .'</h2>';
-    }
-    $output .= '<dl>';
-    foreach ($items as $item) {
-      if (isset($item['title'])) {
-        $output .= '<dt class="'. $item['class'] .'">'. $item['title'] .'</dt>';
-      }
-      $output .= '<dd class="'. $item['class'] .'">'. $item['value'] .'</dd>';
-    }
-    $output .= '</dl>';
-  }
+  $output .= $account->content;
   $output .= '</div>';
-
   return $output;
 }
 
@@ -1473,29 +1463,31 @@ function user_view($uid = 0) {
   if ($account === FALSE || ($account->access == 0 && !user_access('administer users'))) {
     return drupal_not_found();
   }
-  // Retrieve and merge all profile fields:
-  $fields = array();
-  foreach (module_list() as $module) {
-    if ($data = module_invoke($module, 'user', 'view', '', $account)) {
-      foreach ($data as $category => $items) {
-        foreach ($items as $key => $item) {
-          $item['class'] = "$module-". $item['class'];
-          $fields[$category][$key] = $item;
-        }
-      }
-    }
-  }
-
-  // Let modules change the returned fields - useful for personal privacy
-  // controls. Since modules communicate changes by reference, we cannot use
-  // module_invoke_all().
-  foreach (module_implements('profile_alter') as $module) {
-    $function = $module .'_profile_alter';
-    $function($account, $fields);
-  }
+  // Retrieve and render all profile fields:
+  $account->content = user_build_content($account);
+  $account->content = drupal_render($account->content);
 
   drupal_set_title($account->name);
-  return theme('user_profile', $account, $fields);
+  return theme('user_profile', $account);
+}
+
+/**
+ * Builds a structured array representing the profile content.
+ *
+ * @param $account
+ *   A user object.
+ *
+ * @return
+ *   An structured array containing the individual elements
+ *   of the profile.
+ */
+function user_build_content($account) {
+  $edit = NULL;
+  user_module_invoke('view', $edit, $account);
+  // Allow modules to modify the fully-built profile.
+  user_module_invoke('alter', $edit, $account);
+
+  return $account->content;
 }
 
 /*** Administrative features ***********************************************/
@@ -2532,6 +2524,35 @@ function theme_user_filters($form) {
 }
 
 /**
+ * Format a profile category as a definition array.
+ *
+ * @param $element
+ *   An associative array containing the properties of the element.
+ *   Properties used: attributes, title, value
+ * @return
+ *   A themed HTML string representing the profile category as a definition
+ *   list.
+ */
+function theme_profile_category($element) {
+  $output = '';
+  if ($element['#title'] != '') {
+    $output .= '<h3>'. check_plain($element['#title']) .'</h3>';
+  }
+  $output .= '<dl'. drupal_attributes($element['#attributes']) .'>';
+  $output .= $element['#children'];
+  $output .= '</dl>';
+  return $output;
+}
+
+function theme_profile_item($element) {
+  if ($element['#title'] != '') {
+    $output = '<dt'. drupal_attributes($element['#attributes']) .'>'. $element['#title'] .'</dt>';
+    $output .= '<dd'. drupal_attributes($element['#attributes']) .'>' . $element['#value'] .'</dd>';
+    return $output;
+  }
+}
+
+/**
  * Process result from user administration filter form.
  */
 function user_filter_form_submit($form_id, $form_values) {
=== modified file 'themes/engines/phptemplate/phptemplate.engine'
--- themes/engines/phptemplate/phptemplate.engine	
+++ themes/engines/phptemplate/phptemplate.engine	
@@ -343,6 +343,12 @@ function phptemplate_box($title, $conten
   ));
 }
 
+function phptemplate_user_profile($account) {
+  $variables = array('account' => $account);
+  return _phptemplate_callback('user_profile', $variables);
+}
+
+
 /**
  * Default callback for PHPTemplate.
  *
@@ -375,7 +381,7 @@ function _phptemplate_default($hook, $va
       $file = path_to_theme() ."/$hook$extension";
     }
     else {
-      if (in_array($hook, array('node', 'block', 'box', 'comment'))) {
+      if (in_array($hook, array('node', 'block', 'box', 'comment', 'user_profile'))) {
         $file = "themes/engines/$theme_engine/$hook$extension";
       }
       else {
