Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.550
diff -u -p -r1.550 theme.inc
--- includes/theme.inc	8 Nov 2009 12:43:41 -0000	1.550
+++ includes/theme.inc	10 Nov 2009 02:18:00 -0000
@@ -2003,7 +2003,10 @@ function template_preprocess_username(&$
     $variables['link_path'] = 'user/' . $variables['uid'];
   }
   elseif (!empty($account->homepage)) {
-    $variables['link_attributes'] = array('rel' => 'nofollow');
+    // Like the 'class' attribute, the 'rel' attribute can hold a
+    // space-separated set of values, so initialize it as an array to make it
+    // easier for other preprocess functions to append to it.
+    $variables['link_attributes'] = array('rel' => array('nofollow'));
     $variables['link_path'] = $account->homepage;
     $variables['homepage'] = $account->homepage;
   }
@@ -2023,7 +2026,14 @@ function template_process_username(&$var
   // This is done in the process phase so that attributes may be added by
   // modules or the theme during the preprocess phase.
   if (isset($variables['link_path'])) {
-    $variables['link_options']['attributes'] = $variables['link_attributes'] + $variables['attributes_array'];
+    // $variables['attributes_array'] contains attributes that should be applied
+    // whether a link is being rendered or not. $variables['link_attributes']
+    // contains attributes that should only be applied if a link is being
+    // rendered. Preprocess functions are encouraged to use the former unless
+    // they are adding attributes that would be senseless to place on a
+    // non-link. If a link will be rendered, these need to be merged. Some
+    // attributes are themselves arrays, so the merging needs to be recursive.
+    $variables['link_options']['attributes'] = array_merge_recursive($variables['link_attributes'], $variables['attributes_array']);
   }
 }
 
Index: modules/rdf/rdf.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/rdf/rdf.module,v
retrieving revision 1.7
diff -u -p -r1.7 rdf.module
--- modules/rdf/rdf.module	3 Nov 2009 06:47:22 -0000	1.7
+++ modules/rdf/rdf.module	10 Nov 2009 02:18:03 -0000
@@ -402,6 +402,10 @@ function rdf_preprocess_node(&$variables
     $date_attributes_array = rdf_rdfa_attributes($variables['rdf_mapping']['created'], $variables['created']);
     $variables['rdf_template_variable_attributes_array']['date'] = $date_attributes_array;
   }
+  // Adds RDFa markup for the relation between the node and its author.
+  if (!empty($variables['rdf_mapping']['uid'])) {
+    $variables['rdf_template_variable_attributes_array']['name']['rel'] = $variables['rdf_mapping']['uid']['predicates'];
+  }
 }
 
 /**
@@ -440,48 +444,38 @@ function rdf_preprocess_user_profile(&$v
  * Implements MODULE_preprocess_HOOK().
  */
 function rdf_preprocess_username(&$variables) {
-  $account = $variables['account'];
-  if (!empty($account->rdf_mapping['name'])) {
-    if ($account->uid != 0) {
-      // The following RDFa construct allows to fit all the needed information
-      // into the a tag and avoids having to wrap it with an extra span.
-
-      // An RDF resource for the user is created with the 'about' attribute and
-      // the profile URI is used to identify this resource. Even if the user
-      // profile is not accessible, we generate its URI regardless in order to
-      // be able to identify the user in RDF.
+  // $variables['account'] is a pseudo account object, and as such, does not
+  // contain the rdf mappings for the user; in the case of nodes and comments,
+  // it contains the mappings for the node or comment object instead. Therefore,
+  // the real account object for the user is needed. The real account object is
+  // needed for this function only; it should not replace $variables['account'].
+  if ($account = user_load($variables['uid'])) {
+    // An RDF resource for the user is created with the 'about' attribute and
+    // the profile URI is used to identify this resource. Even if the user
+    // profile is not accessible, we generate its URI regardless in order to
+    // be able to identify the user in RDF. We do not use this attribute for
+    // the anonymous user because we do not have a user profile URI for it (only
+    // a homepage which cannot be used as user profile in RDF).
+    if ($account->uid > 0) {
       $variables['attributes_array']['about'] = url('user/' . $account->uid);
-      // The 'typeof' attribute specifies the RDF type(s) of this resource. They
-      // are defined in the 'rdftype' property of the user object RDF mapping.
-      // Since the full user object is not available in $variables, it needs to
-      // be loaded. This is due to the collision between the node and user
-      // when they are merged into $account and some properties are overridden.
-      $variables['attributes_array']['typeof'] = user_load($account->uid)->rdf_mapping['rdftype'];
-
-      // The first thing we are describing is the relation between the user and
-      // the parent resource (e.g. a node). Because the set of predicate link
-      // the parent to the user, we must use the 'rev' RDFa attribute to specify
-      // that the relationship is reverse.
-      if (!empty($account->rdf_mapping['uid']['predicates'])) {
-        $variables['attributes_array']['rev'] = $account->rdf_mapping['uid']['predicates'];
-        // We indicate the parent identifier in the 'resource' attribute,
-        // typically this is the entity URI. This is the object in RDF.
-        $parent_uri = '';
-        if (!empty($account->path['source'])) {
-          $parent_uri = url($account->path['source']);
-        }
-        elseif (!empty($account->cid)) {
-          $parent_uri = url('comment/' . $account->cid, array('fragment' => 'comment-' . $account->cid));
-        }
-        $variables['attributes_array']['resource'] = $parent_uri;
-      }
+    }
+
+    // The 'typeof' attribute specifies the RDF type(s) of this resource. They
+    // are defined in the 'rdftype' property of the user object RDF mapping.
+    if (!empty($account->rdf_mapping['rdftype'])) {
+      $variables['attributes_array']['typeof'] = $account->rdf_mapping['rdftype'];
+    }
 
-      // The second information we annotate is the name of the user with the
-      // 'property' attribute. We do not need to specify the RDF object here
-      // because it's the value inside the a tag which will be used
-      // automatically according to the RDFa parsing rules.
+    // Annotate the user name in RDFa. The attribute 'property' is used here
+    // because the user name is a literal.
+    if (!empty($account->rdf_mapping['name'])) {
       $variables['attributes_array']['property'] = $account->rdf_mapping['name']['predicates'];
     }
+
+    // Add the homepage RDFa markup if present.
+    if (!empty($variables['homepage']) && !empty($account->rdf_mapping['homepage'])) {
+      $variables['attributes_array']['rel'] = $account->rdf_mapping['homepage']['predicates'];
+    }
   }
 }
 
@@ -503,6 +497,10 @@ function rdf_preprocess_comment(&$variab
     $date_attributes_array = rdf_rdfa_attributes($comment->rdf_mapping['created'], $comment->created);
     $variables['rdf_template_variable_attributes_array']['created'] = $date_attributes_array;
   }
+  // Adds RDFa markup for the relation between the comment and its author.
+  if (!empty($comment->rdf_mapping['uid'])) {
+    $variables['rdf_template_variable_attributes_array']['author']['rel'] = $comment->rdf_mapping['uid']['predicates'];
+  }
   if (!empty($comment->rdf_mapping['title'])) {
     // Adds RDFa markup to the subject of the comment. Because the RDFa markup is
     // added to an h3 tag which might contain HTML code, we specify an empty
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1077
diff -u -p -r1.1077 user.module
--- modules/user/user.module	7 Nov 2009 14:27:20 -0000	1.1077
+++ modules/user/user.module	10 Nov 2009 02:18:05 -0000
@@ -3275,6 +3275,10 @@ function user_rdf_mapping() {
         'name' => array(
           'predicates' => array('foaf:name'),
         ),
+        'homepage' => array(
+          'predicates' => array('foaf:page'),
+          'type' => 'rel',
+        ),
       ),
     ),
   );
