iCalender Plugin for Grails
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
docs/gapi
gradle/wrapper
grails-app
src
.gitignore
.travis.yml
LICENSE.txt
build.gradle
gradle.properties
gradlew
gradlew.bat
readme.md
settings.gradle

readme.md

Grails iCalendar Plugin

Build Status

Grails Version Support

Grails 2.x

Use version 0.4.4 in Grails 2.x projects by adding it as a plugin dependency in BuildConfig.groovy.

plugins {
    ...
    compile ":ic-alendar:0.4.5"
}

Please not that the Grails 2.x plugin is end of life since 2017 and won't get any maintainance at all. To get support either upgrade to Grails 3.x or provide a pull request for the Grails 2.x plugin on branch grails2.    

Grails 3.x

Use version 0.5.0 or above for Grails 3.x projects by adding it as a dependency in build.gradle.

dependencies {
    ...
    compile "org.grails.plugins:iCalendar:0.6.1"
}

Introduction

This listing is only valid until plugin version 0.5.x

class TestController {
  def index = {

    render(contentType: 'text/calendar', filename: '<optional filename>') {
      calendar {
        events {
          event(start: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 14:00'),
                   end: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 15:00'),
                   description: 'Events description',
                   summary: 'Short info1') {
            organizer(name: 'Silvio Wangler', email: 'a@b.com')
          }
          event(start: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 14:00'),
                  end: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 15:00'),
                  description: 'hell yes',
                  summary: 'Short info2',
                  location: '@home',
                  classification: 'private'){
            organizer(name: 'Silvio Wangler', email: 'b.c@d.com')
          }
        }
      }
    }
  }
}

The Grails 3 version of the plugin starting from version 0.6.0 uses Groovy Traits to inject a render method into your controller.

// Since version 0.6.0
class TestController implements CalendarExporter {

  def index = {

    renderCalendar {
      calendar {
        events {
          event(start: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 14:00'), end: Date.parse('dd.MM.yyyy HH:mm', '31.10.2009 15:00'), description: 'Events description', summary: 'Short info1') {
            organizer(name: 'Silvio Wangler', email: 'silvio.wangler@gmail.com')
          }
          event(start: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 14:00'), end: Date.parse('dd.MM.yyyy HH:mm', '01.11.2009 15:00'), description: 'hell yes', summary: 'Short info2', location: '@home', classification: 'private')
        }
      }
    }
  }
}

This plugin uses the ical4j API and is therefore iCalendar RFC compliant. The output has been tested against the Google Calendar importer, Microsoft Outlook and Mozilla Sunbird.

The plugin is at the current stage of development limited to events only. That means that you currently can only export VEVENTS.

What else can you do?

This documentation does not claim to cover all the features that are implemented in the iCalendar plugin. But there is a Unit Test Suite that covers the feature set of this plugin and therefore a very good entry point if you are looking for an overview.

Disable the plugin per controller

(Only valid up to version 0.5.x)

If you do not want to have this feature injected into every controller you can specify which controllers to be excluded in Config.groovy

grails.plugins.ical.controllers.exclude = ['excludedTest']

This Configuration parameter has to be a list of controller names!

Invite attendees

render(contentType: 'text/calendar') {
    calendar {
        events {
            event(start: new Date(), end: (new Date()).next(), summary: 'We need to talk') {
                organizer(name:"Peter O'Brien", email:'abc@ch.ch')
                reminder(minutesBefore: 5, description: 'Your meeting starts in 5 minutes!')
                attendees {
                    attendee(email:'bill.gates@microsoft.com', role: REQ_PARTICIPANT, partstat: NEEDS_ACTION, cutype: INDIVIDUAL, rsvp: TRUE)
                    attendee(email:'carmen.breeze@google.com', role: REQ_PARTICIPANT, partstat: NEEDS_ACTION, cutype: INDIVIDUAL, rsvp: FALSE)
                }
            }
        }
    }
}

Use UTC dates

Since version 0.4.0 the plugin supports UTC dates. Each event accepts an optional parameter called utc. If the parameter is missing UTC is set to false.

render(contentType: 'text/calendar') {
    calendar {
        events {
            event(
                start: new Date(), 
                end: new Date(), 
                description: 'Some large text', 
                summary: 'Project stand up meeting', 
                utc: true // optional parameter (default = false)
            )
        }
    }
}

All day events

Version 0.4.1 introduces DSL support for all day events. You can use a String by defining a date like 12.10.2014.

calendar {
    events {
        allDayEvent(date: '12.04.2013', summary: 'Text') {
            organizer(name: 'Silvio', email: 'abc@ch.ch')
            reminder(minutesBefore: 5, description: 'Alarm 123')
        }
    }
}

Currently there is a limitation that the date format has to be DD.MM.YYYY. The fix of this limitation will be address in a future release.

Another way is to simply provide a Date instance

calendar {
    events {
        allDayEvent(date: new java.util.Date(), summary: 'Text') {
            organizer(name: 'Silvio', email: 'abc@ch.ch')
            reminder(minutesBefore: 5, description: 'Alarm 123')
        }
    }
}

Adding X-Properties to a calendar

For some calendar clients such as Microsoft Outlook it can be useful to set vendor specific properties such as X-PRIMARY-CALENDAR. Since version 0.4.5 (for Grails 2.x) and version 0.5.1 (for Grails 3.x) you can set custom properties like this.

calendar(xproperties: ['X-WR-RELCALID': '1234', 'X-PRIMARY-CALENDAR': 'TRUE']) {
    events {
        allDayEvent(date: new java.util.Date(), summary: 'Text') {
            organizer(name: 'Silvio', email: 'abc@ch.ch')
            reminder(minutesBefore: 5, description: 'Alarm 123')
        }
    }
}