0

First off I apologize for be a slacker and not having time to post anything on this blog for quite some time. I’d like to say that I’m going to get better at it, but I probably won’t!

This past week I needed to get an iCal feed created for my DotCMS Calendar.  What I came up with might not be the most elegant solution, but it does the trick for Outlook and Google Calendars at least.  So I thought I’d post up my process …

First I started by creating an HTML page in DotCMS, and choosing the Blank Template.  The next thing I did was create a new contentlet.  The important thing to remember about this step is to name your contentlet something that is going to be ewasy to remember.  The reason for this is that doing this will break the DotCMS Page Editor.  You’ll see why a little latter.

Now for the code:

$response.setContentType('text/calendar')
$response.setHeader("Content-disposition","attachment;filename=calendar.ics")
#set($today = $UtilMethods.now())
#set($fromDate = $date.format("MM/dd/yyyy", $today))
#set($endDate = $UtilMethods.addDays($today, 30))
#set($toDate = $date.format("MM/dd/yyyy", $endDate))
#pullContent("+structureInode:135155  +date1:[01/01/1900 00:00:00
TO $toDate 23:59:59] +date2:[$fromDate 00:00:00 TO 01/01/3000 00:00:00]
+languageId:1 +deleted:false +live:true" '0' 'date1')
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
CALSCALE:GREGORIAN
X-WR-TIMEZONE:America/New_York
X-WR-CALNAME:EUP Events
BEGIN:VTIMEZONE
TZID:US-Eastern
LAST-MODIFIED:19870101T000000Z
BEGIN:STANDARD
DTSTART:19971026T020000
RDATE:19971026T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19971026T020000
RDATE:19970406T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE
#foreach($content in $list)
BEGIN:VEVENT
DTSTAMP:$date.format("yyyyMMdd'T'HHmmss", $content.startDate)
DTSTART:$date.format("yyyyMMdd'T'HHmmss", $content.startDate)
DTEND:$date.format("yyyyMMdd'T'HHmmss", $content.endDate)
SUMMARY:$!content.title
UID:$!content.identifier
PRIORITY:3
CATEGORIES:MEETING
LOCATION:Edinboro
END:VEVENT
#end
END:VCALENDAR

Let me pick this apart section by section. First off we have what I like to call, “The Magic” of this whole thing:

$response.setContentType('text/calendar')
$response.setHeader("Content-disposition","attachment;filename=calendar.ics")

What this little bit of code does is set content type for the page, and tells the browser that this should be downloaded, not displayed in the screen. It also tells the browser exactly what the filename should be that they are downloading. This allows us to set the extension of .ics.

#set($today = $UtilMethods.now())
#set($fromDate = $date.format("MM/dd/yyyy", $today))
#set($endDate = $UtilMethods.addDays($today, 30))
#set($toDate = $date.format("MM/dd/yyyy", $endDate))
#pullContent("+structureInode:135155  +date1:[01/01/1900 00:00:00
TO $toDate 23:59:59] +date2:[$fromDate 00:00:00 TO 01/01/3000 00:00:00]
+languageId:1 +deleted:false +live:true" '0' 'date1')

Note:  I had to break up the #pullContent into 3 lines so it would fit on the page, this should be one line.

This bit of code is probably fairly familiar to most of you reading this. Basically it is pulling the events from the last 30 days. You will of course need to make sure you change the structureInode to match what your Event Structure’s Inode is.

BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
CALSCALE:GREGORIAN
X-WR-TIMEZONE:America/New_York
X-WR-CALNAME:EUP Events
BEGIN:VTIMEZONE
TZID:US-Eastern
LAST-MODIFIED:19870101T000000Z
BEGIN:STANDARD
DTSTART:19971026T020000
RDATE:19971026T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19971026T020000
RDATE:19970406T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
END:VTIMEZONE

This is the begining of the iCal Code. It defines the Time Zone, the name, the version, and various other tidbits. I found it was necessary to put in the vTimeZone element for the calendar to show up in Google in the right times. I also found a nifty reference of the iCal Format Here.

#foreach($content in $list)
BEGIN:VEVENT
DTSTAMP:$date.format("yyyyMMdd'T'HHmmss", $content.startDate)
DTSTART:$date.format("yyyyMMdd'T'HHmmss", $content.startDate)
DTEND:$date.format("yyyyMMdd'T'HHmmss", $content.endDate)
SUMMARY:$!content.title
UID:$!content.identifier
PRIORITY:3
CATEGORIES:MEETING
LOCATION:Edinboro
END:VEVENT
#end
END:VCALENDAR

The rest of the code is fairly straight foward I think. Loop through each contentlet and create a vEvent item then bookend with your ending vCalendar. The hard part is the Time Format. I found putting in the Timezone here did not work in Google, perhaps you will have better luck.

Now, I know this isn’t perfect. I haven’t put in descriptions and nice locations and all that. This was a quick and dirty write-up to get what I needed done. I hope it benefits you, if you have any questions or suggestions I’d love to hear from you in the comments.

Where to go from here? I would love to see this macroized and/or wigitized and put into a plugin. I hope some day I have time to beef it up and learn more about what I can and can’t do with iCal. I would also like to put in the ability to give iCal Feeds for specific categories and tags. Ultimately, I would like to see the iCal download servelet that already exists in DotCMS fleshed out to this natively within the CMS.

Please if you have any suggestions on how to make this better or any improvements you’ve made on this, I’d love to hear about it in the comments.

No comments yet.

Leave a Reply