Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.978
diff -u -F^f -r1.978 common.inc
--- includes/common.inc	31 Aug 2009 05:51:07 -0000	1.978
+++ includes/common.inc	31 Aug 2009 06:42:01 -0000
@@ -5137,7 +5137,6 @@ function entity_get_info($entity_type = 
  *   An array of conditions in the form 'field' => $value.
  * @param $reset
  *   Whether to reset the internal cache for the requested entity type.
- *
  * @return
  *   An array of entity objects indexed by their ids.
  */
@@ -5162,6 +5161,41 @@ function entity_get_controller($entity_t
 }
 
 /**
+ * Create the path to view an entity.
+ *
+ * This is used to create links to arbitrary entities.
+ *
+ * @see hook_entity_info()
+ *
+ * @param $entity_type
+ *   The type of an entity that is defined in hook_entity_info().
+ * @param $entity
+ *   The entity for which the path shall be created.
+ * @return
+ *   The router path that links to the entity, or FALSE if there is no way to
+ *   link to the entity.
+ */
+function entity_create_path($entity_type, $entity) {
+  $info = entity_get_info($entity_type);
+
+  if (!empty($info['view path'])) {
+    $path = $info['view path'];
+    $pieces = explode($path);
+    // Replace wildcards in the view path.
+    foreach ($pieces as $piece) {
+      // Match the wildcard
+      if (preg_match('!(%[^/]+)(/|$)!', $piece, $matches)) {
+        // Get the property of the entity that has the name of the wildcard.
+        $property = $entity->{$matches[1]};
+        // Replace the wildcard with the property
+        $path = str_replace($matches[1], $property, $info['view path']);
+      }
+    }
+    return $path;
+  }
+  // If 'view path' is not set, there is no way to link to this entity.
+  return FALSE;
+}
+
+/**
  * Performs one or more XML-RPC request(s).
  *
  * @param $url
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.765
diff -u -F^f -r1.765 comment.module
--- modules/comment/comment.module	29 Aug 2009 10:46:40 -0000	1.765
+++ modules/comment/comment.module	31 Aug 2009 06:42:02 -0000
@@ -109,6 +109,7 @@ function comment_entity_info() {
         'id' => 'cid',
         'bundle' => 'node_type',
       ),
+      'view path' => 'comment/%cid',
       'bundle keys' => array(
         'bundle' => 'type',
       ),
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1116
diff -u -F^f -r1.1116 node.module
--- modules/node/node.module	29 Aug 2009 21:05:16 -0000	1.1116
+++ modules/node/node.module	31 Aug 2009 06:42:04 -0000
@@ -162,6 +162,7 @@ function node_entity_info() {
       // Node.module handles its own caching.
       // 'cacheable' => FALSE,
       'bundles' => array(),
+      'view path' => 'node/%nid',
     ),
   );
   // Bundles must provide a human readable name so we can create help and error
Index: modules/system/system.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v
retrieving revision 1.68
diff -u -F^f -r1.68 system.api.php
--- modules/system/system.api.php	31 Aug 2009 05:47:34 -0000	1.68
+++ modules/system/system.api.php	31 Aug 2009 06:42:06 -0000
@@ -61,6 +61,10 @@
  *   - cacheable: A boolean indicating whether Field API should cache
  *     loaded fields for each object, reducing the cost of
  *     field_attach_load().
+ *   - view path: A pattern for the menu router path to view entities. The
+ *     pattern can contain a wildcard that will be replaced by the entity's
+ *     property of the same name (if the view path pattern is 'node/%nid',
+ *     %nid will be replaced by the entity's nid property).
  *   - bundles: An array describing all bundles for this object type.
  *     Keys are bundles machine names, as found in the objects' 'bundle'
  *     property (defined in the 'object keys' entry above).
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.507
diff -u -F^f -r1.507 taxonomy.module
--- modules/taxonomy/taxonomy.module	27 Aug 2009 20:48:31 -0000	1.507
+++ modules/taxonomy/taxonomy.module	31 Aug 2009 06:42:07 -0000
@@ -28,6 +28,7 @@ function taxonomy_entity_info() {
       'controller class' => 'TaxonomyTermController',
       'base table' => 'taxonomy_term_data',
       'fieldable' => TRUE,
+      'view path' => 'taxonomy/term/%tid',
       'object keys' => array(
         'id' => 'tid',
         'bundle' => 'vocabulary_machine_name',
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1036
diff -u -F^f -r1.1036 user.module
--- modules/user/user.module	29 Aug 2009 21:05:16 -0000	1.1036
+++ modules/user/user.module	31 Aug 2009 06:42:09 -0000
@@ -96,6 +96,7 @@ function user_entity_info() {
       'object keys' => array(
         'id' => 'uid',
       ),
+      'view path' => 'user/%uid',
       'bundles' => array(
         'user' => array(
           'label' => t('User'),
