[Expert] Creating Individual Calendar Event iCal files – In 3 Easy Steps …


(Tavernerj) #1

OK, so I lied about the “easy” steps :stuck_out_tongue:


Please note that this is for creating calendar items for individual events, to get a feed of all events follow this thread: http://forums.matrix.squiz.net/index.php?showtopic=3164 & credit due to Rayn & Nick for the work that I’ve managed to leverage to get this going.



Before you start, export a calendar event out of your default calendaring application so that you can check its preference for the fields that it uses. The implementation of .ics files is often sketchy across the various calendaring applications, so some “experimenting” is necessary :wink: . The version below works with: Novell GroupWise, Apple iCal, Gmail



A word of warning; you’ll have to set up conditional keywords for the End Date & Description (maybe not if you enforce this one), as usually the calendaring applications pack a sad if there’s no value for a field. Also note that an event that runs all day won’t have an End Date.


  1. Firstly you’ll need to have a design template that will output the correct "content type"
    
    


2. Next you’ll need a Paint Layout to output the iCal details (Make sure you create a Custom Asset Type of Single Calendar Event to attach the Conditional Keywords to). Please note that each field must be on a separate line (you’ll need to check the output of your .ics files to ensure that this is the case).

As we have Novell’s GroupWise as our email & calendaring application, not all of the following is necessary, specifically the fields beginning with X-GW & everything inside the BEGIN:VTIMEZONE & END:VTIMEZONE fields (although it might be a nice touch ;) )

PRODID is a customiable field that you can insert your own orginisation's name & version number.

In order to capture the (optional) Location , Orgainiser & Orgainisers Email fields I’ve created metadata fields & then used Conditional Keywords in the Paint Layout to display the fields when they’ve been filled in.

Another note here is that the DTSTART & DTEND sometimes needs to have a trailing “Z” for some Calendaring applications. Please check the output of your calendaring application for its preference.

[codebox]BEGIN:VCALENDAR
X-WR-CALNAME:%asset_attribute_name%
PRODID:-//CPIT Events//Library v1.0//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:(GMT+1200) New Zealand Standard Time
BEGIN:STANDARD
TZOFFSETFROM:+1300
TZOFFSETTO:+1200
DTSTART:20000405T000000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=4
TZNAME:New Zealand Standard Time
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+1200
TZOFFSETTO:+1300
DTSTART:20000927T000000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=9
TZNAME:New Zealand Daylight Time
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
X-GWITEM-TYPE:APPOINTMENT
SUMMARY:%asset_attribute_name%
TRANSP:OPAQUE
X-GWSHOW-AS:BUSY
%begin_No_End_Date%
DTSTART;TZID="(GMT+1200) New Zealand Standard Time":%event_start_time_ical%
DTEND;TZID="(GMT+1200) New Zealand Standard Time":%event_end_time_ical%
%else_No_End_Date%
DTSTART;TZID="(GMT+1200) New Zealand Standard Time";VALUE=DATE:%event_start_datetime_Y%%event_start_datetime_m%%event_start_datetime_d%
X-GWALLDAYEVENT:TRUE
DTEND;TZID="(GMT+1200) New Zealand Standard Time";VALUE=DATE:%event_start_datetime_Y%%event_start_datetime_m%%event_start_datetime_d%
%end_No_End_Date%
%begin_No_Description% DESCRIPTION:%asset_attribute_description%
%else_No_Description%
%end_No_Description%
%begin_meta_Location%
LOCATION:%asset_metadata_Location%
%end_meta_Location%
%begin_meta_Orgainiser%
ORGANIZER;CN="%asset_metadata_Orgainiser%":mailto:%asset_metadata_Orgainisers_Email%
%end_meta_Orgainiser%
END:VEVENT
END:VCALENDAR
[/codebox]

The Conditional Keywords I have set up are as follows;
[codebox]Condition Keyword Regexp
Keyword Name No_End_Date
Keyword is true if: The following keyword matches the specified pattern
Options
Keyword event_end_time_ical
Pattern ^([A-Za-z0-9-]+)

Condition Keyword Regexp
Keyword Name No_Description
Keyword is true if: The following keyword matches the specified pattern
Options
Keyword asset_attribute_description
Pattern ^([A-Za-z0-9-]+)

Condition Keyword Regexp
Keyword Name meta_Location
Keyword is true if: The following keyword matches the specified pattern
Options
Keyword asset_metadata_Location
Pattern ^([A-Za-z0-9-]+)

Condition Keyword Regexp
Keyword Name meta_Orgainiser_name
Keyword is true if: The following keyword matches the specified pattern
Options
Keyword asset_metadata_Orgainiser
Pattern ^([A-Za-z0-9-]+)

Condition Keyword Regexp
Keyword Name meta_Orgainiser_email
Keyword is true if: The following keyword matches the specified pattern
Options
Keyword asset_metadata_Orgainisers_Email
Pattern ^([A-Za-z0-9-]+)

Condition Logical
Keyword Name meta_Orgainiser
Keyword is true if: The following combination of keywords evaluates to True
Options
Logical Keyword 0 meta_Orgainiser_name
Logical Keyword 1 meta_Orgainiser_email
Logical Keyword 2 -- none --
Operator ALL
[/codebox]

3. OK, now for the magic bit ;), in order to get the individual events to output you’ll need to set up an Upcoming Events List (ha ha - saw that one coming). Then from that listing point to each of the individual events & then paint them with a second Paint Layout (Once again make sure you create a Custom Asset Type of Single Calendar Event to attach the Conditional Keywords to).

In our case we’ve laid it out in a table <hiss/> & the magic bit is: <a href="../event.ics?a=%asset_assetid%"> which points to a folder asset with a web path of “event.ics” & has the first Paint Layout applied to it. This way I don’t have to get people to create additional web paths (ones with .ics ) every time a new event is added :)' /> & yes I have tried to get a trigger to do it <img src='http://forums.matrix.squiz.net/public/style_emoticons/<#EMO_DIR#>/smile.gif' class='bbc_emoticon' alt=':) (of course if someone does know how … , although this method might be more robust).<br /> <br /> [codebox]<table id="eventTable" cellspacing="0" cellpadding="0"><br /> <tr class="table_odd"><br /> <td><strong>Event Name</strong></td><br /> <td>%asset_attribute_name%</td><br /> </tr><br /> <tr class="table_even"><br /> <td><strong>Start Date</strong></td><br /> <td>%event_start_date%</td><br /> </tr><br /> <tr class="table_odd"><br /> <td><strong>End Date</strong></td><br /> <td>%event_end_date%</td><br /> </tr><br /> <tr class="table_even"><br /> <td><strong>Duration</strong></td><br /> <td>%event_duration%</td><br /> </tr><br /> %begin_meta_Location%<br /> <tr class="table_odd"><br /> <td><strong>Location</strong></td><br /> <td>%asset_metadata_Location%</td><br /> </tr><br /> %end_meta_Location%<br /> %begin_meta_Orgainiser_name%<br /> <tr class="table_even"><br /> <td><strong>Orgainiser</strong></td><br /> <td>%begin_meta_Orgainiser_email%<a href="mailto:%asset_metadata_Orgainisers_Email%">%asset_metadata_Orgainiser%</a>%else_meta_Orgainiser_email%%asset_metadata_Orgainiser%%end_meta_Orgainiser_email%</td><br /> </tr><br /> %end_meta_Orgainiser_name%<br /> %begin_No_Description%<br /> <tr class="table_odd"><br /> <td><strong>Description</strong></td><br /> <td>%asset_attribute_description%</td><br /> </tr><br /> %end_No_Description%<br /> <tr class="table_even"><br /> <td>&nbsp;</td><br /> <td><a href="../event.ics?a=%asset_assetid%"><span>Download this Calendar Event</span><div id="iconDownload"></div></a></td><br /> </tr><br /> </table><br /> <br /> [/codebox]<br /> <br /> Conditional Keywords much the same as before … <br /> [codebox]Condition Keyword Regexp<br /> Keyword Name No_Description<br /> Keyword is true if: The following keyword matches the specified pattern<br /> Options Keyword asset_attribute_description<br /> Pattern ^([A-Za-z0-9-]+)<br /> <br /> <br /> <br /> Condition Keyword Regexp<br /> Keyword Name meta_Location<br /> Keyword is true if: The following keyword matches the specified pattern<br /> Options Keyword asset_metadata_Location<br /> Pattern ^([A-Za-z0-9-]+)<br /> <br /> <br /> <br /> Condition Keyword Regexp<br /> Keyword Name meta_Orgainiser_name<br /> Keyword is true if: The following keyword matches the specified pattern<br /> Options Keyword asset_metadata_Orgainiser<br /> Pattern ^([A-Za-z0-9-]+)<br /> <br /> <br /> <br /> Condition Keyword Regexp<br /> Keyword Name meta_Orgainiser_email<br /> Keyword is true if: The following keyword matches the specified pattern<br /> Options Keyword asset_metadata_Orgainisers_Email<br /> Pattern ^([A-Za-z0-9-]+<br /> <br /> <br /> <br /> [/codebox]<br /> <br /> & now everything should be all ticky-boo & working automagically B)

(Nic Hubbard) #2

Nice one!


(Tavernerj) #3

Here’s the examples of this in action.


Looks like this post got mangled when the new design was applied, will have a look at fixing it up (if I can remember what I did ;)), otherwise see you at the User Conference


(Steve Scamp) #4

I know it's been a while since this thread was last updated, but I was just wondering:


Has anybody been able to replicate this with an actual, individual Calendar Event record, rather than with an Upcoming Events List? I.e. when a Calendar Event is displayed at its own URL in the browser (as the end result of finding it through a calendar) would functionality like this allow for the inclusion of a link on the event's page that would let you export/download the event in .ics format?



We're trying to provide this kind of functionality at present and could usae any tips or pointers.



Thanks.


(Robin Shi) #5

It's cool, I will have a try!


(Steve Scamp) #6

[quote]
It's cool, I will have a try!

[/quote]



Thanks very much, Robin.


(Tavernerj) #7

[quote]
I know it's been a while since this thread was last updated, but I was just wondering:



Has anybody been able to replicate this with an actual, individual Calendar Event record, rather than with an Upcoming Events List? I.e. when a Calendar Event is displayed at its own URL in the browser (as the end result of finding it through a calendar) would functionality like this allow for the inclusion of a link on the event's page that would let you export/download the event in .ics format?



We're trying to provide this kind of functionality at present and could usae any tips or pointers.



Thanks.

[/quote]



You're always going to have to have a folder asset with a web path of “event.ics”, that's unfortunatly unavoidable (unless you're going to get people to create two urls for the asset every time an asset is created) as the browser needs to have something with a .ics file extension (I triedB)) in order to handle the file properly.


Custom Form Custom File Attachment stopping thank you page loading
(Robin Shi) #8

I changed a bit parse file so Matrix treats the url as a file.

    
    
    

I applied the design as 'User Defined File Design', so Julz's solution can be used with the individual event's own URL, for example: http://[event's URL]/?SQ_DESIGN_NAME=designname

It works great in IE: Matrix uses the event title as the file name, and ics for the ext name.

In FF, Matrix doesn't give ext name with ics and the filename looks odd, but my default calendar app is opened by the link.



It's really good to know (thanks for Julz) that we have a bit access to the response header in Matrix, it's flexible!



In our site, I had our programmer code in PHP just to rewrite the response header to achieve the downloadable ics. http://www.acu.edu.au/calendars_and_timetables/important_dates/calendar/this_month/