Eventview / Calender: Is there any system out there to render calenderevents


I need a way to display events on a homepage. In the end it should look like this:


This schoolhomepage is the perfect example of the ideal endresult.


I would like to ask you, if there is any system at all to render events. I am at a point where I will take anything. The current workflow (Outlook --> ICS --> Joomla --> Calenderplugin) doesn’t seem to work (as in: Outlook --> ICS --> Kirby --> FullCalender.io-Plugin)

I asked about that here: Parsing ICS to populate a calender (here: FullCalender.io) and googled a lot.

Thanks :slight_smile:

Is export from Outlook needed? What other formats can you export to instead of ICS?

There are PHP libraries for parsing ICS you could use, but for FullCalender.io JSON export would probably be better suited.

I guess managing the calendar in Kirby is not an option?

Right now the events are mananged using Outlook. But in fact, the calender is hosted on a Ionos (1&1)-Server within Nextcloud.

Right now we export the .ics-file from Outlook. In theory, Nextcloud can export JSON. But the JSON is not compatible with the needed JSON (my internal ‘Bugreport’ is here: https://gitlab.com/cniehaus/kgskirby/-/issues/7) .

I might work around this by using regex to convert Nextclouds JSON to the needed JSON.

We could move from managing in Outlook to Thunderbird oder the Nextcloud-WebInterface, but no to the homepage run by Kirby. That page is strictly readonly.

Hm, this is completely beyond Kirby support. and a matter of converting your JSON to a format FullCalendar.io can read.

Ive worked with events in Kirby a fair bit, including using Fullcalender to display events created as pages within kirby and those coming in from a Google Calender. Fullcalendar only works with public calenders. If the outlook calendar needs authentication like a login or something, then you are out of luck.

I think your best idea is to use a PHP library (like this one https://libraries.io/github/OzzyCzech/icalparser) to turn the events into virtual pages. You can then feed those into Fullcalender.

You might find two of my plugins useful…

Gets recurring dates from between a range (so for example if an event always happens on every second tuesday of the month, Recurr will give you the dates of all of those tuesdays for as a many months and years as you need.) It can also turn a date into a Recurr rule that Fullcalendar understands.

Yasumi will get you all the dates of public and religious holidays for any country in the world and for any year. You can plot these on the calendar.

I hope that helps.

p.s i made this for kirby 2, but it is a working example using kirby pages as events, mixing them with Google calendar events, and displying both on Fullcalendar. Maybe theres something useful in that you use for your project. (note that there is now a decent GCal plugin for Kirby 3 so you can use that instead of all the manual API stuff in the repo below.)

Why would you want to to that instead directly feeding the JSON into Fullcalendar.io?

Multiple options are always useful :slight_smile: sounds like the JSON wrangling to get it into the correct format might be problematic. Good to have a plan B.

I agree that multiple options are often useful, but in this case, you might as well either parse the ical data and get useful json from that (for example using ical.js as described in the issue), or do something with the JSON export, without going the virtual pages route, because then you have an additional, imho unnessary step. Unless I’m missing something…

1 Like

We can find the ical format e.g. at https://en.wikipedia.org/wiki/ICalendar, at the end we find at “External links” the links to the RFCs, so you can import or parse the files from the Outlook export.

I setteled for using Google Calender as an itermediate step. So it is now:

Outlook -> Nextcloud -> Google Calender -> FullCalender.io

FullCalender.io is about to release a major version, who knows…
Using Google sucks but at least it works.

Thanks you for all you replies!

I couldn't stand using Google... So we coded a parser. It is not a beauty but it parses an ics file and spits out valid JSON that fullcalender.io can parse.

So in the spirit of giving back to the community, feel free to use my code. Not the best but it works :slight_smile:


    function echo2 ($inhalt){

        global $exportjson;

        $inhalt = str_replace('<br>',chr(13).chr(10),$inhalt);

        fwrite ($exportjson, $inhalt);


    //Kategorien 1-9 werden farblich unterschiedlich dargestellt

    $farbpalette =array("gray","skyblue","lightgrey","lightblue","greenyellow","mediumvioletred","papayawhip","pink","turquoise","orange");

    $such_beginn_datensatz = 'BEGIN:VEVENT';

    $such_ende_datensatz = 'END:VEVENT';

    $such_categorie = 'CATEGORIES:';

    $such_start = 'DTSTART';

    $such_end = 'DTEND';

    $such_description = 'DESCRIPTION:';

    $such_summary = 'SUMMARY';

    $such_zeilenumbruch_outlook = 'TRANSP';


    // Kalender einlesen

    $file = fopen ('quelle.ics', "r");

    $exportjson = fopen ("ziel.json", "w");

    $datensatz_nr = 0;

    $datensatz = false;

    echo2 ('['.'<br>'); //Zeile 1 der json-Datei für den fullcalendar

    while(!feof($file)) {

      $zeile = trim(fgets($file, 4096));

      if (substr($zeile,0,strlen($such_beginn_datensatz)) ==$such_beginn_datensatz) { //Beginn des Termindatensatzes - Initialisierung

        $datensatz_nr = $datensatz_nr + 1;

        $datensatz = true;//Termin beginnt

        $categorie ='';

        $start = '';

        $description = '';

        $summary = '';

        $end = '';


      if (substr($zeile,0,strlen($such_ende_datensatz)) ==$such_ende_datensatz){ //Ende des Datensatzes

              $datensatz = false; //Termin Ende

        $color = "white";

        $color = $farbpalette[substr($categorie,0,1)];

        if ($datensatz_nr != 1) {echo2 (','.'<br>');};

        echo2 ('{'.'<br>');

        echo2 ('"title": '.'"'.$summary.'",'.'<br>');

        echo2 ('"start": '.'"'.substr($start,0,4).'-'.substr($start,4,2).'-'.substr($start,6,2));

        if (strlen($start)>8) {echo2 (substr($start,8,3).':'.substr($start,11,2));};

        echo2 ('",<br>');

        echo2 ('"end": '.'"'.substr($end,0,4).'-'.substr($end,4,2).'-'.substr($end,6,2));

        if (strlen($end)>8) {echo2 (substr($end,8,3).':'.substr($end,11,2));};

        echo2 ('",<br>');

        echo2 ('"color": '.'"'.$color.'",'.'<br>');

        echo2 ('"textColor": '.'"'.'#707070'.'"<br>');

        echo2 ('}');


      //Termindetails auslesen

      if ($datensatz == true) {

          if (substr($zeile,0,strlen($such_categorie)) ==$such_categorie) {

            $categorie = trim(substr($zeile,strlen($such_categorie),100));


          if (substr($zeile,0,strlen($such_start)) ==$such_start) {

            $start = trim(substr($zeile,strpos($zeile,':')+1,100));


          if (substr($zeile,0,strlen($such_description)) ==$such_description) {

            $description = trim(substr($zeile,strlen($such_description),100));


          if (substr($zeile,0,strlen($such_summary)) ==$such_summary) {

            $summary = trim(substr($zeile,strpos($zeile,':')+1,200));

            $zeile = trim(fgets($file, 4096));

            if (substr($zeile,0,strlen($such_zeilenumbruch_outlook)) !=$such_zeilenumbruch_outlook) {

            $summary .= $zeile;


            //Hochkommas im string austauschen

            $summary = str_replace('"','\'',$summary);

            $summary = str_replace('\\','',$summary);


          if (substr($zeile,0,strlen($such_end)) ==$such_end) {

            $end = trim(substr($zeile,strpos($zeile,':')+1,100));




        echo2 ('<br>'.']'); //Ende der JSON-Datei

    fclose ($file);

    fclose ($exportjson);
1 Like