Custom Formatter Examples

Last updated on
30 April 2025

You are browsing documentation for an older version of Drupal, which is not supported any longer, and the information may not be correct. See current documentation for Contributed modules

A collection of Custom Formatters for various field types.

Field Type:


Date Formatters

D8: Date Range

The default presentation for a start/end date is:

Friday, June 9, 2018 - 10:00 - Sunday, June 11, 2018 - 11:30

The Date Range Formatter provides an abbreviated format that consolidates days, months and years if they are identical:

June 9, 2018
June 9 - June 10, 2018
June 9, 2018 - January 10, 2019


// Breaks days, months and years out if different
// June 9, 2018
// June 9 - June 10, 2018 
// June 9, 2018 - January 10, 2019 

  $element = array();
  $date_string_start = $items
    ->first()
    ->getValue()['value'];
  $date_string_end = $items
    ->first()
    ->getValue()['end_value'];
  if (!empty($date_string_start) && !empty($date_string_end)) {
    // Create new datetime objects from the start and end dates.
    $datetime_start = new DateTime($date_string_start, new DateTimeZone('UTC'));
    $datetime_end = new DateTime($date_string_end, new DateTimeZone('UTC'));
    $drupal_time_zone = date_default_timezone_get();
    // Time is stored in UTC - convert to local site timezone.
    $datetime_start->setTimezone(new DateTimeZone($drupal_time_zone));
    $datetime_end->setTimezone(new DateTimeZone($drupal_time_zone));
    // Format date elements to properly render the date.
    $event_date_start = $datetime_start->format('Y-m-d');
    $event_date_end = $datetime_end->format('Y-m-d');
    $event_start_day = $datetime_start->format('d');
    $event_end_day = $datetime_end->format('d');
    $event_start_month = $datetime_start->format('F');
    $event_end_month = $datetime_end->format('F');
    $event_start_year = $datetime_start->format('Y');
    $event_end_year = $datetime_end->format('Y');
    // Check if this is a one day event and print out one day with time.
    if ($event_date_start == $event_date_end) {
      $element = "$event_start_month $event_start_day, $event_end_year";
    }
    // Check if it is at least in the same year.
    elseif ($event_start_year == $event_end_year) {
      // And check if it is in the same month
      if ($event_start_month == $event_end_month) {
        $element = "$event_start_month $event_start_day" . '–' . "$event_end_day, $event_end_year";
        // If this is not in the same month but is in the same year, print
        // both months.
      }
      else {
        $element = "$event_start_month $event_start_day" . '–' . "$event_end_month $event_end_day, $event_end_year";
      }
    }
    // Well this is annoying, it's an event that runs between two different
    // years, two different months and different days so print all that madness.
    else {
      $element = "$event_start_month $event_start_day, $event_start_year" . '–' . "$event_end_month $event_end_day,  $event_end_year";
      }
      return $element;
  }

D7: Natural Date Format

The default presentation for a start/end date is:

Sunday, December 1, 2013 - 10:00 - Sunday, December 1, 2013 - 11:30

The Natural Data Formatter gives you more natural formats, such as (depending on field values):

Tuesday, June 9, 2015
Tuesday, June 9, 2015 at 12:00 p.m.
Tuesday, June 9, 2015 at 12:00 p.m. - 1:00 p.m.
Tuesday, June 9, 2015 - Wednesday, June 10, 2015
Tuesday, June 9, 2015 - Wednesday, June 10, 12:00 p.m. - 1:00 p.m.
(Multiple date fields will be broken into multiple lines with <br /> tags)

// Natural Date Formatter
// Displays as (depending on field values): 
//   Tuesday, June 9, 2015 
//   Tuesday, June 9, 2015 at 12:00 p.m.
//   Tuesday, June 9, 2015 at 12:00 p.m. - 1:00 p.m.
//   Tuesday, June 9, 2015 - Wednesday, June 10
//   Tuesday, June 9, 2015 - Wednesday, June 10, 2015, 12:00 p.m. - 1:00 p.m.
//   (Multiple date fields will be broken into multiple lines with <br /> tags

// Get all dates
$dates = $variables['#items'];

// Cycle through all dates (if more than one)
foreach ($dates as $index => $date) {
  $timezone = $date['timezone'];
  $timezone_db = $date['timezone_db'];
  $date1 = strtotime($date['value'] . ' ' . $timezone_db);
  $date2 = strtotime($date['value2'] . ' ' . $timezone_db);
  $rrule = $date['rrule'];

  // Get the start and end date for the current date
  $display = array('settings' => array('format_type' => 'medium'));
  $d1 = format_date($date1, 'custom', 'l, F j, Y', $timezone);
  $d2 = format_date($date2, 'custom', 'l, F j, Y', $timezone);
  $t1 = format_date($date1, 'custom', 'g:i a', $timezone);
  $t2 = format_date($date2, 'custom', 'g:i a', $timezone);

  // Change am to a.m. (add periods) and pm to p.m.
  $t1 = str_replace( array('am', 'pm'), array('a.m.', 'p.m.'), $t1 );
  $t2 = str_replace( array('am', 'pm'), array('a.m.', 'p.m.'), $t2 );

  // Print single date or a range (dash-separated)
  if (empty($d2) or $d1 == $d2) {
    $str = "$d1";
  } else {
    $str = "$d1 - $d2";
  }

  // If time is specified, print it (if time is blank or the same, print it once, otherwise print the range)
  if (empty($t1) && empty($t2)) {
    $str .= '';
  } elseif (empty($t2) || $t1 == $t2) {
    $str .= " at $t1";
  } else {
    $str .= ", $t1 - $t2";
  }
  $output[] = $str;
}

return( implode( '<br />', $output) );


D7: Display Age in Years

$element = array();
foreach ($variables['#items'] as $delta => $item) {
  // Calculation based on http://ibndawood.com/2011/10/calculating-the-age-of-a-person-given-their-birthdate/
  $element[$delta] = array(
    '#markup' => floor((time() - strtotime($item['value'])) / (365.2425 * 60 * 60 * 24)),
  );
}
return $element;


Image Formatters


Displays a thumbnail image linked to a large image.

// Formatter settings.
$settings = $variables['#display']['settings'];
foreach (element_children($variables['#items']) as $delta) {
  $item = $variables['#items'][$delta];
  $source = theme('image_style', array('style_name' => $settings['image_style_source'], 'path' => $item['uri']));
  $destination = image_style_path($settings['image_style_destination'], $item['uri']);
  return l($source, file_create_url($destination), array('html' => TRUE));
}


Taxonomy Term Formatters


D7: Display Top (root) Parent Term Name

Apply to taxonomy_term_reference fields and this will show the top-most parent term, or itself if it is a top-level term.

NOTE: If used in a sortable Views table, it will not sort the results by this name, it will sort by the original term's name.

$tid = $variables['#items'][0]['tid'];
$terms = taxonomy_get_parents_all($tid);
$terms = array_reverse($terms);  // Make the top-most term first in array
$top_term = $terms[0];
return $top_term->name;


Text Field Formatters

D8: Uppercase Text Field

This formatter will convert the text field to uppercase. (Based on Custom Formatters 8.x-3.0-alpha1)

namespace Drupal\Core\TypedData;
use Drupal\Component\Utility\Unicode;

$output=array();
foreach ($items as $delta => $item) {
  $output[$delta] = ['#markup' => Unicode::strtoupper($item->getString())];
}
return($output);

Help improve this page

Page status: Not set

You can: