Best way to change display for a field? I have a node display that shows about 20 different fields.
One of the fields is a list of years (multiple values). Instead of printing the list of years I would like to just show the first and last year, for example "1999-2005".

Views has a great formatter for those situations but I don't want to use views for the node display.
You might want to test the following simple formatter I put together for one of my projects - named mvspan (multivalue span). Soon after I wrote it, the specs of my client changed and I did not need it anymore, therefore it may need some more tests, therefore please accept it in its "as-is" shape.

It works for simple text or integer types, not date or datestamps, unfortunately. Feel free to shape it for your own needs.

It has two modes: displaying first/last values or min/max values. Plus, it allows you to set the delimiter to glue up the values.

mvspan.info:

name = Multi-value Span
description = "Formats multi-value fields to show first/last or min/max value spans."
core = 7.x
files[] = mvspan.module


mvspan.module:

&lt;?php
 /**
 * Implements hook_field_formatter_info().
 */
function mvspan_field_formatter_info() {
  return array(
    // the key must be unique, so it's best to prefix with your module's name.
    'mvspan_formatter' =&gt; array(
      'label' =&gt; t('Multi-value Span'),
      'field types' =&gt; array('text', 'number_integer'),
      'multiple values' =&gt; FIELD_BEHAVIOR_DEFAULT,
      'settings' =&gt; array(
        'delimiter' =&gt; '...',
        'mode' =&gt; 'minmax',
      )
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function mvspan_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'];

  $delimiter = check_plain($settings['delimiter']); // The delimiter string in the settings form

  switch($settings['mode']){
    case 'minmax':
      $minv = NULL;
      $maxv = NULL;

      foreach($items as $delta =&gt; $item) {
        if(is_null($minv) || $item['value'] &lt; $minv){
          $minv = $item['value'];
        }
        if(is_null($maxv) || $item['value'] &gt; $maxv){
          $maxv = $item['value'];
        }
      }

      if($minv === $maxv) {
        $element[0]['#markup'] = $minv;
      } else {
        $element[0]['#markup'] = implode($delimiter, array($minv, $maxv));
      }

      break;

    case 'firstlast':
      reset($items);
      $firstv = $items[key($items)]['value'];
      end($items);
      $lastv = $items[key($items)]['value'];

      $element[0]['#markup'] = implode($delimiter, array($firstv, $lastv));
      break;
  }
  return $element;
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function mvspan_field_formatter_settings_form($field, $instance, $view_mode, $form, &amp;$form_state){
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $element = array();

  // settings
  $element['delimiter'] = array(
    '#type' =&gt; 'textfield',
    '#title' =&gt; t('Delimiter'),
    '#description' =&gt; t('Delimiter string to be inserted between min and max values.'),
    '#default_value' =&gt; $settings['delimiter'],
  );
  $element['mode'] = array(
    '#type' =&gt; 'select',
    '#title' =&gt; t('Value handling'),
    '#description' =&gt; t('How multiple values will be managed: min/max or first/last'),
    '#default_value' =&gt; $settings['mode'],
    '#options' =&gt; array(
      'minmax' =&gt; t('Minimum/maximum'),
      'firstlast'  =&gt; t('First/last'),
    )
  );
  return $element;
}

/**
 * Implements hook_field_formatter_settings_summary().
 */
function mvspan_field_formatter_settings_summary($field, $instance, $view_mode) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $summary = array();

  switch($settings['mode']){
    case 'minmax':
      $summary[] = t('&lt;strong&gt;Min/max&lt;/strong&gt; values will be displayed');
      break;

    case 'firstlast':
      $summary[] = t('&lt;strong&gt;First/last&lt;/strong&gt; values will be displayed');
      break;
  }
  $summary[] = t('using delimiter: "&lt;strong&gt;@delim&lt;/strong&gt;"', array('@delim' =&gt; $settings['delimiter']));
  return implode('&lt;br /&gt;', $summary);
}