I’m writing a module that has a custom Field (cruises) and Field Formatter (Cruise Calendar). I have the backend squared away and have assigned “Unlimited” related cruises to my node. My goal is to display all the details of the related cruises as well as a single Cruise Calendar on each page with a single formatter. I’ve got a twig template working for each individual item displaying the details of each cruise, but I’m stuck as to how to best create the wrapper/calendar element in a twig template. The wrapper needs to be passed a simple list of which dates should be highlighted on the calendar.
At first I thought I could do this by creating a nested Render Array in my viewElements funtion, but the more I dig I don’t think that’s true. Overwriting viewElements in FormatterBase really only effects the individual elements right? How best can I create a custom template wrapper for my field formatter?
Here’s my sample code, when I thought I could return a nested Render Array. But of course if I return $wrapper my child elements don’t appear.
class FareHarborCalendar extends FormatterBase {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
$all_cruise_dates = [];
foreach ($items as $delta => $fh_cruise) {
$local_cruise = FareharborCruises::load($fh_cruise->target_id);
$availabilities = FareharborAvailabilities::getByTypeDate($fh_cruise->target_id);
foreach($availabilities as $departure){
$date_parts = explode("T", $departure->start);
$all_cruise_dates[] = $date_parts[0];
}
$elements[$delta] = [
'#theme' => 'fareharbor_cruise_details',
'#cruise_id' => $fh_cruise->target_id,
'#name' => $local_cruise->name->value,
'#booking_notes' => $local_cruise->booking_notes->value,
'#headline' => $local_cruise->headline->value,
'#details' => $local_cruise,
'#availabilities' => $availabilities,
];
};
$elements['#attached']['library'][] = 'fareharbor/fareharbor';
$wrapper = [
'#theme' => 'fareharbor_calendar',
'#name' => "some fixed name",
'#all_dates' => $all_cruise_dates,
'child_details' => $elements,
];
return $elements;
}
}
My hook_theme in .module file
/**
* Implements hook_theme().
*/
function fareharbor_theme() {
$vars['cruise_id'] = NULL;
$vars['name'] = NULL;
$vars['booking_notes'] = NULL;
$vars['headline'] = NULL;
$vars['details'] = NULL;
$vars['availabilities'] = NULL;
$theme['fareharbor_cruise_details'] = [
'template' => 'fareharbor_cruise_details',
'variables' => $vars,
];
$cal_vars['name'] = NULL;
$cal_vars['child_details'] = $theme['fareharbor_cruise_details'];
$theme['fareharbor_calendar'] = [
'template' => 'fareharbor_calendar',
'variables' => $cal_vars,
];
return $theme;
}
and a Dump of available values in fareharbor_calendar.html.twig
^ array:14 [▼
"name" => "some fixed name"
"child_details" => array:2 [▼
"template" => "fareharbor_cruise_details"
"variables" => array:6 [▼
"cruise_id" => null
"name" => null
"booking_notes" => null
"headline" => null
"details" => null
"availabilities" => null
]
]
"theme_hook_original" => "fareharbor_calendar"
"attributes" => Drupal\Core\Template\Attribute {#4854 ▶}
"title_attributes" => Drupal\Core\Template\Attribute {#4847 ▶}
"content_attributes" => Drupal\Core\Template\Attribute {#4851 ▶}
"title_prefix" => []
"title_suffix" => []
"db_is_active" => true
"is_admin" => true
"logged_in" => true
"user" => Drupal\Core\Session\AccountProxy {#2996 ▶}
"directory" => "themes/custom/flagship"
"theme_hook_suggestions" => []
]
Any hints as to how to best go about this and have a better understanding of how it's supposed to work would be greatly appreciated.
thanks,
summer