I was recently working on a Drupal 8 website and needed to rewrite the output of a date field for better displaying and theming purpose.
In Drupal 7, I would have done this with the Display Suite module. But in Drupal 8, I will be using the Drupal console to generate the scaffolding for me and a Twig template to control output bit of custom code to connect the dots.
Output will look like:
<div class="article-date">
<span>{{ source.day }}</span>
<span>{{ source.month }}</span>
</div>
I make a module (or implement this in a custom module) that allows me to easily enable and disable my functionality.
$ drupal generate:module
Drupal console will prompt for some details. After entering them, I have my custom module.
Creating the custom field formatter.
$ drupal generate:plugin:fieldformatter
Drupal console will prompt for some details. After entering them, I have my custom field formatter inside my custom module.
Creating a the Twig template file (/templates/article-date.html.twig) in the custom module to control the output.
<div class="article-date">
<span>{{ source.day }}</span>
<span>{{ source.month }}</span>
</div>
Implement hook_theme() in the .module file
/**
* Implements hook_theme().
*/
function mymodule_theme() {
$theme = [];
$theme['article-date'] = [
'variables' => array(
'source' => NULL
),
];
return $theme;
}
To connect the dots I add code to the viewElements() method of the formatter class.
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
$source = array();
foreach ($items as $delta => $item) {
// Get the date value
$date = $item->getValue();
// Split the date in pieces for theming.
$date_pieces = explode('-', $date['value']);
// Transform the numeric representation of a month into the three letters
//representation of a month.
switch ($date_pieces[1]) {
case '01':
$date_pieces[1] = 'jan';
break;
case '02':
$date_pieces[1] = 'feb';
break;
case '03':
$date_pieces[1] = 'mar';
break;
case '04':
$date_pieces[1] = 'apr';
break;
case '05':
$date_pieces[1] = 'may';
break;
case '06':
$date_pieces[1] = 'jun';
break;
case '07':
$date_pieces[1] = 'jul';
break;
case '08':
$date_pieces[1] = 'aug';
break;
case '09':
$date_pieces[1] = 'sep';
break;
case '10':
$date_pieces[1] = 'oct';
break;
case '11':
$date_pieces[1] = 'nov';
break;
case '12':
$date_pieces[1] = 'dec';
break;
}
// Prepare the variables.
$source = array(
'day' => $date_pieces[2],
'month' => $date_pieces[1],
'year' => $date_pieces[0]
);
}
// Put everything in an array for theming.
$elements[] = array(
'#theme' => 'article-date',
'#source' => $source,
);
return $elements;
}
Clear the caches.