This shows how to generate “Add to Calendar” links for Google, Outlook, iCalendar (.ics), etc. using fields from a Drupal entity.
Back to topInstall the Calendar Links Library
We are going to use the Spatie Calendar Links library (https://github.com/spatie/calendar-links) to generate "Add to Calendar" links from entity fields.
From your project root run :
composer require spatie/calendar-linksThe main class you’ll use is: Spatie\CalendarLinks\Link;
Load the Entity and Resolve the Event Dates
Assume you’re passing $entity_type_id, $entity_id, and a datetime field name (e.g. field_event_date):
$entity_id = 123;
$entity_type = 'node';
// Load the entity.
$storage = $this->entityTypeManager->getStorage($entity_type);
$entity = $storage->load($entity_id);Now extract the start/end from a date field on a fieldable entity:
use Drupal\Core\Entity\FieldableEntityInterface;
$field_name = 'field_event_date';
if ($entity instanceof FieldableEntityInterface && $entity->hasField($field_name) {
$start = ($entity->get($field_name)->value ?? NULL));
$end = ($entity->get($field_name)->end_value ?? $entity->get($field_name)->value ?? NULL));
$label = preg_replace('/[\n\r]+/', ' ', $entity->label());
$uid = $entity->uuid();
// Normalize to UTC for the calendar providers.
$tz = new \DateTimeZone('UTC');
$startDate = new \DateTime($start, $tz);
$endDate = new \DateTime($end, $tz);
}
else {
throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
}Create the Calendar Link Object
Use Spatie’s Link::create() to build the calendar link:
use Spatie\CalendarLinks\Link;
$link = Link::create($label, $startDate, $endDate)
->description('Event generated from Drupal.') // Optional
->address('Your event address here'); // OptionalYou now have a Link object that can output URLs or ICS content for multiple calendar systems.
Generate an ICS File or Calendar Provider URL
For ICS, you may want to force a file download from a controller:
use Symfony\Component\HttpFoundation\Response;
$ics = $link->ics(['UID' => $uid], ['format' => 'file']);
return new Response($ics, 200, [
'Content-Type' => 'text/calendar; charset=utf-8',
'Content-Disposition' => "attachment; filename=\"{$label}.ics\"",
]);For other providers (google, outlook, yahoo), you can generate an "add to calendar" link:
// Google Calendar
$url = $link->google();
// Outlook
$url = $link->webOutlook();
// Office365
$url = $link->webOffice();
// Yahoo
$url = $link->yahoo();