Last updated 20 November 2011. Created on 19 February 2007.
Edited by KarenS, Shai, LeeHunter, tonyn. Log in to edit this page.

Also see Date documentation.

See the Calendar Project Page to download and install this module. Please report problems on the Issue queue rather than as comments on this page, since that makes the handbook quite messy and hard to read. Plus, many of the problems reported here are already reported or fixed, which you can see in the issue queue. I'm going to start removing comments that are bug reports or support requests from this page and asking you to report them on the issue queue instead. Comments that help clarify the handbook or point out ways that it could be improved are perfectly OK.

Requires Views and the Date API. This module will display any Views date field in calendar formats. Works with CCK date fields, Event module dates, node created and updated dates, and any other Views date field. The module does not create dates, it only displays dates that have already been created elsewhere, like CCK date fields.

Multiple calendars can be created for different purposes, i.e. one that displays node created dates as an archive calendar and another to display CCK dates for a custom content type, just give each a unique url.

You can use the supplied default calendar view as a starting point, or create one or more calendar views from scratch:


  • Select the Calendar display as the page type for your view. If you want to have a mini calendar available in a block, select the Calendar display as the block type as well as the page type.
  • Add any fields you want to display on the calendar as fields to the view. Be sure to include fields that contain the dates that need to be shown on the calendar. Date fields can include CCK date fields, event start and end dates, or dates like the node created or updated dates. If you use CCK date fields, set them to 'Do not group multiple values' so each value will display in its own date box.
  • Add three arguments to the view: Calendar Year, Calendar Month, and Calendar Day, in that order. Set each of them to 'Display All Values'.
  • Add sorts to the view for each date field so the dates are sorted correctly.
  • In most cases, add a Node: Type filter to filter the view by the content types that contain your selected date fields. The default view has a Node: Type filter that selects all node types. Change it to select only the node types you want in your calendar.

Updating From Earlier Versions

The Calendar module now uses the Date API from the Date module. The Date API was pulled out of the Date module so you can use the API with no dependence on CCK. For anyone updating a previous version of the Calendar module may run into problems on the update since the Calendar module will be installed but the Date API will not. The easiest way to make the transition is to uninstall the Calendar module (and Date module if you are using it) before uploading the latest code to your site, then go to the modules page and enable both Date API and the Calendar module. If you don't uninstall the Calendar module first, you will see some errors when you upload the new code, but it will automatically uninstall the Calendar module until you go to the modules page and install the Calendar module and the Date API module.

Other Features

Switch between year, month, week, and day views with back and next navigation.

A mini calendar is available using the block view if the block view is also set to the Calendar type.

Two other blocks are available. A legend block will display only on calendar pages and will show a legend of the color coding for field names and content types.

A Switch Calendar block will display only on calendar pages and allows the user to switch between calendar, list, table, teaser, and full node views for whichever time period is being viewed. The back/next navigation will remain at the top of the traditional views displays so you can move from one month to the next, for instance.

iCal Import and Export

To use iCal import or export, enable the new Calendar iCal module.

To export the calendar as an iCal feed, add a fourth Calendar argument to your view, the Calendar: iCal Feed argument.

To import iCal feeds from other locations into your calendar, choose the 'iCal' tab you see when looking at your calendar and fill out information about the feeds you want to insert into the calendar.

Combining Calendar and Traditional Views

There was lots of good discussion in the DrupalCon presentation on Date + Calendar. Based on Earl's suggestion to make sure the Calendar arguments will work with any view and requests from the audience for the ability to show a list in the full page and a calendar in the block, or other combinations of calendar and traditional views in the page and block, I've made reworked the argument handling to make the Calendar arguments work independently of the plugin theme.

In the lastest commit to the 5.x and HEAD versions, you can now add calendar arguments to any view with a date field (list, table, teasers, etc) and get date-based back/next navigation just like the calendar view has; you can have a mini calendar in the block view and a list in the page, or any other combination you like. Just be sure the date field you want to use as the filter is listed in the Fields list.

Themeing the Results

Calendar module results can be customized by changing the included css and/or themes. The key theme is located at the top of the calendar.theme file and looks like:

 *  Themeable node display
 *  appends the field name to the title
 *  constructs a teaser out of any non-date fields in the view
function theme_calendar_calendar_node($node, $type) {
   // Display the regular teaser view for local events.
   if (!$node->remote && $type == 'calendar_node_day') {
     $node = node_load($node->nid);
     $node->teaser = node_view($node, TRUE, FALSE);
     $node->title = '';
   // For other views, construct a teaser out of the provided fields.
   else {
     if ($node->label && !strstr($node->title, $node->label)) {
       $node->title .= ' ('. $node->label .')';
     if ($node->fields) {
       foreach ($node->fields as $field) {
         $node->teaser .= '<div>'. $field .'</div>';
     if (!$node->url && !$node->remote) {
       $node->url = "node/$node->nid";
   // Remote nodes may come in with lengthy descriptions that won't fit
   // in small boxes of year, month, and week calendars.
   if ($type != 'calendar_node_day' && $node->remote) {
     $node->teaser = '';
   return theme($type, $node);

This default theme will display the node title with the field label appended to it, the date, and any other fields that were added to the view. This 'teaser' will be sent to a theme from based on the $type chosen. The types are 'calendar_node_month', 'calendar_node_day', 'calendar_node_week', and 'calendar_node_year'. The theme can be overridden in the same way other themes are, by copying that function to template.php and changing 'theme' to the theme name, then making any appropriate changes.

For instance, if you want different results when looking at the 'day' view, you could add a switch to the above theme based on the type, then if it is a 'day' type, do a node_load() to pick up more node information and print it out, or node_view() to display the complete node.


  • If you see things consistently one day off or sometimes missing from a time period they should appear in, it is most likely a timezone conversion issue, so double check the timezone configuration for that item.
  • If you use CCK dates and have them set up with no hours granularity, you must also set the field up to use no timezone conversion. The current version of the Date module requires this, but date fields created with earlier versions may be set up incorrectly. Dates with no hours get the hour set by default to midnight, so any negative timezone conversion will move it back to the previous day.

Looking for support? Visit the forums, or join #drupal-support in IRC.


JohnG’s picture

Paste this code into the Calendar View Block Footer field (with input format on PHP code):
Change the name of the node type from #event to whatever you're using.

global $user;
global $base_url;
$output = '';
if (is_array($user->roles)) {
   if (isset($user->roles [2]))  {         // <- crude permission check ;)
    $output .= '<a href="' . $base_url . 'node/add/#event">Create new #Event</a><br />';
   else {
    $output .= '';
return $output;

Note the crude permission check to hide the link from anonymous users ($user->roles [1]). Of course if authenticated users ($user->roles [2]) don't have 'Create #event content' perm, the link will return Access Denied ;) If anyone knows how to improve the perm check please pass it on :)

Initially I had this in the Calendar Page View Footer, but it's much more evident and user friendly under the Calendar Block.

Enjoy :)

mooffie’s picture

Or just do:

if (node_access('create', '#event')) {
  return l('Create new #Event', 'node/add/#event');
danielpacker’s picture

I had some trouble figuring out what styles to override in calendar.css to get them transparent. Here's a list. This doesn't include the nav bars on the very top.

.calendar-calendar tr
.calendar-calendar td
.calendar-calendar tr.even
.calendar-calendar tr.odd
.calendar-calendar td.sat, .calendar-calendar td.sun

If the style isn't in calendar.css, create it. Then set the background property to 'none' or 'transparent'. To use a background image, obviously use the background-image property!

UPDATE: This is tested in firefox. If you set background to 'inherited' on all of this and then in the table set a background, it will apply to all the child styles. Much cleaner. Ah crap, I just tested in safari and no go with the inherited...

hillaryneaf’s picture

In the Setup (bullet 3) when arguments are set up, you need to do one more thing to get the breadcrumb to work correctly:

In Calendar: Year argument - Title field you must put %1
In Calendar: Month argument - Title field you must put %2

matt_harrold’s picture

If you have a CCK date field in your content type, you can link it back to the Calendar view with the following snippet in your node.tpl.php or Contemplate:

  // assuming your date field is called "field_date".
  $date = strtotime($node->field_date[0]['value']);
  print l(date('l dS',$date),'calendar/'.date('Y/m/d',$date)).' '.l(date('F',$date),'calendar/'.date('Y/m',$date)).' '.l(date('Y',$date),'calendar/'.date('Y',$date));
StevenPatz’s picture

If you are looking for the name of the Block ( to use for the mini calendar ) on the Block admin page, it will be the name of the View you created.