As more of our lives revolve around our calendars — when things are due, where we have to be right now — it's useful to see other information with our dates. This could mean seeing the weather forecast or not missing one of the Google Doodles. If you use Google Calendar, we've recently added support for Calendar Gadgets. This feature enables you to add just about any kind of content to your calendar and leverage the growing Google Gadgets developer community. Intrigued? Read on! This article will go on to show you what they look like, what they can do, and how you can get in on the action.
This document is intended for anyone interested in learning more about Calendar Gadgets — what they are, how to use them, and how to write and adapt gadgets for Google Calendar.
Calendar Gadgets are special events that appear as icons above a day's events. When clicked, the icon can pop up with any image, webpage, or Google Gadget. Try it out below!
Let's go over the extra fields that make Calendar Gadgets different than a run of the mill "Lunch with Steve" appointment in your calendar.
Additionally, Calendar Gadgets are specified as all-day events. To specify all-day events, set the start time and end time one day apart. For example, if you want your Calendar Gadget to appear on 2007-03-14, then the start time is 2007-03-14 and the end time is 2007-03-15.
The only required field is the icon URL. In its most simple form, Calendar Gadget content can consist of just the icon above the day's events — like the Phases of the Moon calendar above. If you want to point to a webpage or image, the type, width, and height must also be provided. For example, the birthday reminder below pops up with an image (click the birthday hat), and the Movie Releases calendar pops up with an HTML page with movie details (click the movie reel).
For full Google Gadgets to be included as Calendar Gadgets, user preferences may also be required. This document will focus on full Google Gadgets, but for more information the simple form of Calendar Gadgets, see the protocol guide. The Labpixies my del.icio.us gadget takes a del.icio.us username as a user preference (click the del.icio.us logo).
Let's say that you want to have your favorite Google Gadget - Word of the Day, added as a Calendar Gadget in your calendar. (All in the pursuit of personal edification, of course.) There are many ways to add a gadget and varying degrees of difficulty.
We'll go into more detail about using the "of the day" Calendar Gadget creator, the various ways to use the iCal format, and the Calendar data API. It's helpful to have programming knowledge and internet hosting in general, but there are many things you can do with minimal coding and no internet hosting. There is also a difference in how the Calendar Gadgets are added to users' calendars. Published iCal files and URLs generated by the "of the day" creator are maintained as separate calendars that users can add to their list of calendars. Importing an iCal file and using the Calendar data API actually inserts these events into the given calendar. If you just want to convert an existing Google Gadget to a Calendar Gadget, the "of the day" Calendar Gadget creator is an easy way to do so without maintaining any additional files. If you want to provide a Calendar Gadget that pops up a picture on every US Holiday, publishing a static iCal file can be done without any coding - you could even use Google Pages to host the iCal file and photos.
Of course, doing more sophisticated things with the gadget itself may take expertise and hosting, but how to write gadgets is out of scope for this document. Please visit the Google Gadgets documentation for a great starting place. We can even provide hosting for your Google Gadget specification if you use the Google Gadget Editor.
You should peruse all the available methods and decide which works best for you.
If you already have a Google Gadget specification, then you're almost done! A handy tool has been written to convert an existing specification into a Calendar Gadget. The tool is actually a gadget too — we've embedded it in this document over to the right. You can even add it to your iGoogle by clicking on the '+' icon in the bottom left.
Given a valid Google Gadget spec, the "of the day" Calendar Gadget creator will fetch the user preferences, display them for editing, and then create a URL to add the gadget to your calendar. Try it for yourself!
Click on the "Load" button to the right to bring up the user preferences for our Word of the Day gadget. Edit any preferences - for example, try changing the icon URL from the default to "http://www.thefreedictionary.com/favicon.ico". Then, click "Create Calendar." Once the URL is generated, click on the link to add it to your Google Calendar. It will appear in the list of your calendars on the left hand side and display the Google Gadget as an icon on the current day.
The "of the day" creator is easy to use, but since it only displays the gadget on the current day, it has limited flexibility.
For the next step up, there's the iCal format, a standard for calendar data exchange. See below for the Word of the Day example converted into iCal format.
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME;VALUE=TEXT:Word of the Day
VERSION:2.0
BEGIN:VEVENT
DTSTART;VALUE=DATE:20070720
DTEND;VALUE=DATE:20070721
SUMMARY:Word of the Day - with pronunciation audio!
X-GOOGLE-CALENDAR-CONTENT-TITLE:Word of the Day
X-GOOGLE-CALENDAR-CONTENT-ICON:http://www.thefreedictionary.com/favicon.ico
X-GOOGLE-CALENDAR-CONTENT-URL:http://www.thefreedictionary.com/_/WoD/wod-module.xml
X-GOOGLE-CALENDAR-CONTENT-TYPE:application/x-google-gadgets+xml
X-GOOGLE-CALENDAR-CONTENT-WIDTH:330
X-GOOGLE-CALENDAR-CONTENT-HEIGHT:100
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=Format:0
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=Days:1
END:VEVENT
END:VCALENDAR
There are two ways to add events using iCal:
Try importing the event above into your calendar by copying and pasting it into a text document. Save the document with an ".ics" extension, then upload it into your calendar. For instructions on how to import iCal files into your calendar, see here.
You can also provide the URL to a published iCal file - add the above event as a separate calendar by clicking here. Maintaining a published iCal file is a good way to add content programmatically. You can set up a script to periodically update content for anyone who's added your gadget to their calendar. The downside to this method is that updates may take a few hours for the new information to be parsed and viewable by your users.
Note: The uploaded file must be accessible publicly on the internet. It will not be indexed if located on, say, an intranet.
Google Calendar allows client applications to view and update calendar events in the form of Google data API ("GData") feeds. Your client application can use the Google Calendar data API to create new events, edit or delete existing events, and query for events that match particular criteria. Requiring the most programming knowledge, the Calendar data API can be used to insert gadgets by specifying extra fields in a calendar event. Using the Google data protocol, events are actually added to the user's calendar instead of included as an external calendar. Because write calls are being made to a user's calendar, user authentication has to be dealt with. For more information on authentication, please see the Account Authentication documentation and the developer guides.
A standard calendar event entry in the GData format looks something like this:
<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:gd='http://schemas.google.com/g/2005'>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/g/2005#event'></category>
<title type='text'>Word of the Day</title>
<gd:when startTime='2007-07-17'
endTime='2007-07-18'></gd:when>
</entry>
The extra GData elements in a calendar event entry for a Calendar Gadget would look like this for the Word of the Day gadget:
<atom:link rel="http://schemas.google.com/gCal/2005/webContent"
title="Word of the Day"
href="http://www.thefreedictionary.com/favicon.ico"
type="application/x-google-gadgets+xml">
<gCal:webContent url="http://www.thefreedictionary.com/_/WoD/wod-module.xm"
width="300"
height="136">
<gCal:webContentGadgetPref name="Days" value="1" />
<gCal:webContentGadgetPref name="Format" value="0" />
</gCal:webContent>
</atom:link>
To make your lives easier, however, GData offers client libraries in many different languages. Inserting Calendar Gadgets using the Java and Python client libraries are covered below. More information on the raw XML involved can be found in the protocol section of the Google Calendar developer's guide.
The Java client library has a WebContent object and associated helper functions to help create Calendar Gadgets (formerly called Web Content Events) to insert.
First, however, a CalendarEventEntry is needed to hold the WebContent object. As mentioned before, a Calendar Gadget is just a fancy calendar event. The main thing that needs to be set here is the date. For more information on how to use the Java client library with Google Calendar, see the developer's guide for Java.
CalendarEventEntry myEvent = new CalendarEventEntry();
myEvent.setTitle(new PlainTextConstruct("Word of the Day"));
DateTime startTime = DateTime.parseDateTime("2007-03-14");
DateTime endTime = DateTime.parseDateTime("2006-03-15");
When eventTimes = new When();
eventTimes.setStartTime(startTime);
eventTimes.setEndTime(endTime);
myEvent.addTime(eventTimes);
Note: The title that is set in the event is not seen in the normal display. It will only be displayed to describe the event in Agenda view, e-mail, pop-up, or SMS alerts associated with the event.
Next, create a WebContent object and set all the familiar fields associated with our Word of the Day example. The gadget's user preferences are stored in a HashMap as name/value pairs. After the WebContent object is good to go, it can be added to the newly created event by using setWebContent.
WebContent wc = new WebContent();
wc.setTitle("Word of the Day");
wc.setType("application/x-google-gadgets+xml");
wc.setIcon("http://www.thefreedictionary.com/favicon.ico");
wc.setUrl("http://www.thefreedictionary.com/_/WoD/wod-module.xml");
wc.setWidth("300");
wc.setHeight("136");
Map prefs = new HashMap<String,String>();
prefs.put("Format", "0");
prefs.put("Days", "1");
wc.setGadgetPrefs(prefs);
myEvent.setWebContent(wc);
The Calendar Gadget can now be inserted by an authenticated CalendarService object. For more information about how to authenticate a service object, see the Java developer's guide.
CalendarEventEntry insertedEntry = myService.insert('/calendar/feeds/default/private/full', myEntry);
There are three classes that deal with Calendar Gadgets (formerly called Web Content Events) in the Python client library: WebContent, WebContentGadgetPrefs, and WebContentLink. These classes correspond heavily with the structure of the raw XML and it may be helpful to look at the protocol guide for more information on the XML structure.
To continue our Word of the Day example, a CalendarEventEntry is first created to enclose the WebContentLink object. A Calendar Gadget, as you'll remember, is just a special calendar event. The date, a When object, is the most important thing to set here. As mentioned earlier, Calendar Gadgets must be all-day events; specified by setting the start_time and end_time one day apart. For more general information about using the Python client library with Google Calendar, see the Python developer's guide.
event = gdata.calendar.CalendarEventEntry()
event.title = atom.Title(text='Word of the Day')
event.when.append(gdata.calendar.When(start_time='2007-03-14', end_time='2007-03-15'))
Note: The title that is set in the event is not seen in the normal display. It will only be displayed to describe the event in Agenda view, e-mail, pop-up, or SMS alerts associated with the event.
Now, the Gadget-specific objects have to be created. The WebContent class holds the URL of the content (in this case, a Google Gadget spec), the width and height of the popup box, and the name/value pairs for all the user preferences. The preferences are stored as WebContentGadgetPref objects, and appended to the gadget_pref array under the WebContent class. The WebContentLink object holds the title of the pop-up box, the location of the icon, the type of the content, and a WebContent object. The populated WebContentLink object is then added to the newly created event.
wc = gdata.calendar.WebContent()
wc.url = 'http://www.thefreedictionary.com/_/WoD/wod-module.xml'
wc.width = '300'
wc.height = '136'
wc.gadget_pref.append(gdata.calendar.WebContentGadgetPref(name='Days', value='1'))
wc.gadget_pref.append(gdata.calendar.WebContentGadgetPref(name='Format', value='0'))
wcl = gdata.calendar.WebContentLink()
wcl.title = 'Word of the Day'
wcl.href = 'http://www.thefreedictionary.com/favicon.ico'
wcl.link_type = 'application/x-google-gadgets+xml'
wcl.wc = wc
event.link.append(wcl)
The CalendarEventEntry can now be inserted by an authenticated CalendarService object. The Python developer guide for Google Calendar has further details on how to create and authenticate a Calendar client object.
client.InsertEvent(event, '/calendar/feeds/default/private/full')
Here are some things to keep in mind when planning out a Calendar Gadget.
Hopefully, you've been inspired to create useful and fun additions using Calendar Gadgets; whether it be a daily event that shows today's top Digg stories, or new videos from your favorite artists on YouTube. The possibilities are only limited by what can be shown on a webpage. Try it out and give us feedback in the Google Calendar discussion group. Happy coding!