.ics file download links from Events listing

I need to generate links that download an .ics file for an event. I have an events page where these download links need to appear, which is a listing page for child event pages. The child pages are not used on the front end of the site, they are just for organisation.

I have set up a route to try and achieve what I need, this is what it looks like at the moment:

site/config/config.php

'pattern' => 'events/(:all).ics',
  'action' => function($all) {
    $event = page('events/' . $all);
    if ($event != '') {
      Header::download(['mime'=>'text/calendar', 'name' => 'test.ics']);
      return snippet('ical');
    }
  }

And then on my events listing page (simplified for ease):

site/templates/events.php

<?php
foreach($page->children() as $event):
?>
  <div id="<?= $event->slug() ?>">
  <h2><?= $event->title() ?></h2>
  <a href="<?= $event->url() ?>.ics">Download ICS file</a>
  </div>
<?php
endforeach;
?>

I also have a snippet file for the ics - this is just a placeholder for now for testing. It looks like this:

site/snippets/ical.php

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//ZContent.net//Zap Calendar 1.0//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
SUMMARY:Abraham Lincoln
UID:c7614cff-3549-4a00-9152-d25cc1fe077d
SEQUENCE:0
STATUS:CONFIRMED
TRANSP:TRANSPARENT
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=2;BYMONTHDAY=12
DTSTART:20080212
DTEND:20080213
DTSTAMP:20150421T141403
CATEGORIES:U.S. Presidents,Civil War People
LOCATION:Hodgenville\, Kentucky
GEO:37.5739497;-85.7399606
DESCRIPTION:Born February 12\, 1809\nSixteenth President (1861-1865)\n\n\n
 \nhttp://AmericanHistoryCalendar.com
URL:http://americanhistorycalendar.com/peoplecalendar/1,328-abraham-lincol
 n
END:VEVENT
END:VCALENDAR

I also have a little template for an individual event page, to stop people visiting them:

site/templates/event.php

<?php
  go('/events#' . $page->slug())
?>

Currently when I click on the link the browser opens a new, empty tab. Nothing is downloaded / visible. I think my approach is right, but I think perhaps something in my route setup is wrong. If anyone could offer any thoughts that would be great.

try if ($event) { instead.

also could do <a download href=“…. to avoid the new tab

Thanks for the reply - I have made those changes but still no luck unfortunately.

Time to call it a night but will be back on it tomorrow!

instead of using the route you could try a content representation aka site/templates/event.ics.php file

Thanks for the pointer, that looks promising. I will give that approach a try.

I recently used content representations in for ics links in this project. It looks like this:

// site/templates/event.ics.php

<?php

  $kirby->response()->type('text/calendar');

  function iCalDateFormat($uStamp = 0, $tzone = 0.0) {
    $date = new DateTime();
    $date->setTimestamp($uStamp);
    $date->setTimezone(new DateTimeZone('Europe/Berlin'));
    $stamp = $date->format('Ymd\THis');
    return $stamp;
  }

  function iCalTextFormat($string) {
    return str_replace("\n", '\n', $string);
  }

  $startDate = $page->date_start()->toDate();
  $endDate = $page->date_start()->toDate();
  
?>
BEGIN:VCALENDAR<?= PHP_EOL ?>
VERSION:2.0<?= PHP_EOL ?>
PRODID:<?= $site->title() ?><?= PHP_EOL ?>
METHOD:PUBLISH<?= PHP_EOL ?>
BEGIN:VEVENT<?= PHP_EOL ?>
DTSTART:<?= iCalDateFormat($startDateTime) ?><?= PHP_EOL ?>
DTEND:<?= iCalDateFormat($endDateTime) ?><?= PHP_EOL ?>
SUMMARY:<?= $page->title() ?><?= PHP_EOL ?>
DESCRIPTION:<?= iCalTextFormat($page->summary()->escape()) ?><?= PHP_EOL ?>
LOCATION:<?= iCalTextFormat($page->location()->escape()) ?><?= PHP_EOL ?>
END:VEVENT<?= PHP_EOL ?>
END:VCALENDAR

Huge thanks @bnomei for the pointer and @thguenther for the hugely helpful reference file.

Got it working perfectly now!