Create an iCal feed for a single node in Drupal 7

calendar.jpg

Recently I found myself needing to create iCal feeds for individual event nodes on a Drupal 7 site. Initially, I thought this would be a quick process, but it turned out to be a little more complicated than I had planned.

Required Modules:
Views
CTools
Calendar - Includes Calendar_iCal module
Date - Includes Date API module

Step 1 - Create an event content type

To start things off, you'll need a content type to use for event listings. There needs to be a date field associated with this content type in order for the iCal feed to work correctly.

Step 2 - Add a calendar view to display events

Once an event content type exists, you'll most likely be putting together some sort of events list in views. This can be put together using either the calendar display mode provided by the calendar module or just a standard list of events. Now, on to creating the iCal feed.

Step 3 - Create a feed display mode

Add a new display to your events view using the feed display mode.
Give your feed a URL, something like 'events/feed.'
Set the format of the feed display to iCal feed and give the feed a description in the settings.
Configure the format to show iCal fields and in the settings be sure to select the date field associated with your event content type or your feed won't have anything to base event dates off of.
Once the format has been set, configure the filter criteria to show only events content and sort however you'd like it to appear.

I'm not too sure how it affects the field when it's set otherwise, but I set my pager to display all items regardless of the number of events. Since this is a feed, it shouldn't be an issue to display everything on a single page.

Step 4 - Add a Contextual Filter (Date)

Next comes the the most important part.
Add a contextual filter to the display for date:date (node).
Once that filter has been selected, you'll need to configure it. When the filter value is not in the url set the radio button to 'display all results for the specified field.'
After that's been set scroll down and choose the date field your contextual filter will be based on, you can select start and end date separately if need be.

Once that contextual filter has been applied to the display you should be able to preview your feed in the views preview and see the full feed with all events included.

Step 5 - Add a Second Contextual Filter (NID)

The last step that will generate a feed for a single node is adding a second contextual filter.
This one will be based on the Node ID.
Configure this contextual filter to display all results for the specified field when the filter value is not in the url as well.
After this filter has been added, be sure it's being applied before the date field contextual filter or your single node feeds will be empty.

Step 6 - Preview a Single Node Feed

If those filters are both added correctly you should be able to enter the node ID for one of your event nodes in the views preview with contextual filters field and see what the feed for your single node will look like.
To view or link to the single node feed on your site you just add the node ID to the url of your feed like so: events/feed/[nid].
I added the .ics file extension to these URLs to make things a little easier for users downloading these files.

These links can be added to nodes a number of ways, but I just added mine through the preprocess_node function in my theme's template.php file.

Step 7 - Troubleshooting

Finally, you may notice your dates are not correct upon import into iCal. I was having this issue and found this thread in the calendar issue queue on drupal.org. Changing !empty() to isset() in the calendar_plugin_row_ical_node.inc file fixed the issue and single node events worked as expected upon import to iCal.