? .cache
? .settings
Index: modules/field/field.attach.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.attach.inc,v
retrieving revision 1.68
diff -u -p -r1.68 field.attach.inc
--- modules/field/field.attach.inc	28 Dec 2009 20:24:08 -0000	1.68
+++ modules/field/field.attach.inc	31 Dec 2009 02:12:34 -0000
@@ -1111,15 +1111,41 @@ function field_attach_query_revisions($f
 }
 
 /**
- * Allow formatters to act on fieldable objects prior to rendering.
+ * Prepare field data prior to display.
+ *
+ * This function must be called before field_attach_view(). It lets field
+ * types and formatters load additional data needed for display, and
+ * therefore accepts an array of objects to allow query optimisation when
+ * displaying lists of objects.
+ *
+ * @param $obj_type
+ *   The type of $objects; e.g. 'node' or 'user'.
+ * @param $objects
+ *   An array of objects, keyed by object id.
+ * @param $view_mode
+ *   View mode, e.g. 'full', 'teaser'...
  */
 function field_attach_prepare_view($obj_type, $objects, $view_mode = 'full') {
+  // To ensure hooks are only run once per entity, only process items without
+  // the _field_view_prepared flag.
+  // @todo: resolve this more generally for both entity and field level hooks.
+  $prepare = array();
+  foreach ($objects as $id => $object) {
+    if (empty($object->_field_view_prepared)) {
+      // Add this entity to the items to be prepared.
+      $prepare[$id] = $object;
+
+      // Mark this item as prepared.
+      $object->_field_view_prepared = TRUE;
+    }
+  }
+
   // First let the field types do their preparation.
-  _field_invoke_multiple('prepare_view', $obj_type, $objects);
+  _field_invoke_multiple('prepare_view', $obj_type, $prepare);
   // Then let the formatters do their own specific massaging.
   // field_default_prepare_view() takes care of dispatching to the correct
   // formatters according to the display settings for the view mode.
-  _field_invoke_multiple_default('prepare_view', $obj_type, $objects, $view_mode);
+  _field_invoke_multiple_default('prepare_view', $obj_type, $prepare, $view_mode);
 }
 
 /**
@@ -1128,6 +1154,9 @@ function field_attach_prepare_view($obj_
  * Each field is displayed according to the display options specified in the
  * $instance definition for the given $view_mode.
  *
+ * The object must have run through field_attach_prepare_view() beforehands.
+ * @see field_attach_prepare_view()
+ *
  * Sample structure:
  * @code
  * array(
@@ -1185,6 +1214,11 @@ function field_attach_view($obj_type, $o
   );
   drupal_alter('field_attach_view', $output, $context);
 
+  // Reset the _field_view_prepared flag set in field_attach_prepare_view(),
+  // in case the same object is displayed with different settings later in
+  // the request.
+  unset($object->_field_view_prepared);
+
   return $output;
 }
 
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1192
diff -u -p -r1.1192 node.module
--- modules/node/node.module	29 Dec 2009 20:23:10 -0000	1.1192
+++ modules/node/node.module	31 Dec 2009 02:00:37 -0000
@@ -1236,9 +1236,10 @@ function node_build_content($node, $view
   }
 
   // Build fields content.
-  // @todo field_attach_prepare_view() is only invoked by node_view_multiple(),
-  //   all other entities invoke it _here_.
-  //field_attach_prepare_view('node', array($node->nid => $node), $view_mode);
+  // In case of a multiple view, node_view_multiple() already ran the
+  // 'prepare_view' step. An internal flag prevents the operation from running
+  // twice.
+  field_attach_prepare_view('node', array($node->nid => $node), $view_mode);
   $node->content += field_attach_view('node', $node, $view_mode);
 
   // Always display a read more link on teasers because we have no way
Index: modules/rdf/rdf.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/rdf/rdf.module,v
retrieving revision 1.15
diff -u -p -r1.15 rdf.module
--- modules/rdf/rdf.module	26 Dec 2009 12:48:14 -0000	1.15
+++ modules/rdf/rdf.module	31 Dec 2009 01:51:16 -0000
@@ -582,12 +582,6 @@ function rdf_field_attach_view_alter(&$o
     $element = &$output[$field_name];
     if ($element['#field_type'] == 'taxonomy_term' && $element['#formatter'] == 'taxonomy_term_link') {
       foreach ($element['#items'] as $delta => $item) {
-        // @todo Remove this when "node_view() does not call
-        // field_attach_prepare_view()" bug is fixed.
-        // See http://drupal.org/node/493314.
-        if (!isset($item['taxonomy_term'])) {
-          $item['taxonomy_term'] = taxonomy_term_load($item['tid']);
-        }
         $term = $item['taxonomy_term'];
         if (!empty($term->rdf_mapping['rdftype'])) {
           $element[$delta]['#options']['attributes']['typeof'] = $term->rdf_mapping['rdftype'];
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.553
diff -u -p -r1.553 taxonomy.module
--- modules/taxonomy/taxonomy.module	26 Dec 2009 16:50:09 -0000	1.553
+++ modules/taxonomy/taxonomy.module	31 Dec 2009 01:51:07 -0000
@@ -1079,12 +1079,6 @@ function taxonomy_field_formatter_view($
   switch ($display['type']) {
     case 'taxonomy_term_link':
       foreach ($items as $delta => $item) {
-        // @todo Remove this when "node_view() does not call
-        // field_attach_prepare_view()" bug is fixed.
-        // See http://drupal.org/node/493314.
-        if (!isset($item['taxonomy_term'])) {
-          $item['taxonomy_term'] = taxonomy_term_load($item['tid']);
-        }
         $term = $item['taxonomy_term'];
         $element[$delta] = array(
           '#type' => 'link',
