Spin-off from #652834-47: Field formatters as render arrays:

we might also gain a couple cycles by calling the formatter hooks on the whole values array and have them return a render array keyed by value delta, instead of currently doing
foreach ($items as $delta => $item) {
$element[$delta] = $formatter_function($obj_type, $object, $field, $instance, $langcode, $display, $items, $delta);
$element[$delta]['#weight'] = $delta;
}

CommentFileSizeAuthor
#1 field_formatter_optimize-657828-2.patch28.27 KByched

Comments

yched’s picture

Status: Active » Needs review
StatusFileSize
new28.27 KB

Patch attached:

- hook_field_formatter() needs to do the foreach ($items as $delta => $value) internally. Saves repeated function calls, and makes the hook consistent with field-type hooks like h_f_validate(), h_f_update(), ..., which all take $items and loop on it.

- The distinction between 'single value' formatters and 'multiple values' formatters is gone. The formatter is free to return a render array with as many children it needs - one per value for typical formatters, one for all values for 'values in a table', or 'values as points in a graph'. We just require numeric keys.
From the patch:

function hook_field_formatter($obj_type, $object, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'];

  switch ($display['type']) {
    case 'sample_field_formatter_simple':
      // Common case: each value is displayed individually in a sub-element
      // keyed by delta. The field.tpl.php template specifies the markup
      // wrapping each value.
      foreach ($items as $delta => $item) {
        $element[$delta] = array('#markup' => $settings['some_setting'] . $item['value']);
      }
      break;

    case 'sample_field_formatter_combined':
      // Some formatters might need to display all values within a single piece
      // of markup.
      $rows = array();
      foreach ($items as $delta => $item) {
        $rows[] = array($delta, $item['value']);
      }
      $element[0] = array(
        '#theme' => 'table',
        '#header' => array(t('Delta'), t('Value')),
        '#rows' => $rows,
      );
      break;
  }

  return $element;
}

- As a result, 'multiple values' => FIELD_BEHAVIOR_CUSTOM in hook_field_formatter_info() is gone, and so is the field_behaviors_formatter() function.

- $delta param is removed from hook_field_formatter(). Also, the order of arguments is adjusted to match the common pattern for hook_field_[op]() hooks.

- Side optimization: do not run field.tpl.php if the formatter didn't return anything to display (for instance because the field is empty...)

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

I read through the patch and it looks like a nice simplication without the multiple values distinction.

sun’s picture

Awesome, yched! One WTF less in Drupal! :)

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks!

effulgentsia’s picture

Status: Fixed » Reviewed & tested by the community

Awesome indeed. Subscribing to know when it lands, which I hope is soon.

effulgentsia’s picture

Status: Reviewed & tested by the community » Fixed

Well that was fast. Sorry for the x-post.

Status: Fixed » Closed (fixed)
Issue tags: -Performance

Automatically closed -- issue fixed for 2 weeks with no activity.