Drupal is a registered trademark of Dries Buytaert
Release: Leaflet 10.4.11 Minor update available for module leaflet (10.4.11). Release: Session Inspector 1.0.8 Minor update available for module session_inspector (1.0.8). Release: Migrate QA 2.0.4 Minor update available for module migrate_qa (2.0.4). Release: CKEditor Description List 3.0.0 Major update available for module ckeditor_descriptionlist (3.0.0). Release: FlowDrop 2.4.0 Minor update available for module flowdrop (2.4.0). Release: JWT Token Refresh 1.0.4 Minor update available for module jwt_token_refresh (1.0.4). Release: ConReg 1.0.0-beta1 First beta version released for module conreg (1.0.0-beta1). Release: AI Image Studio 1.0.0-beta8 New beta version released for module ai_image_studio (1.0.0-beta8). Usage Milestone: Statistics Counter Module statistics_counter crossed 1,000 active installs. Module Revived: Decoupled Router 2.0.7 Module decoupled_router updated after 11 months of inactivity (2.0.7).

This module displays a user's Microsoft 365 calendar within a Drupal view using FullCalendar. It fetches calendar events on demand, respecting privacy settings and allowing for customization through CSS and hooks.

Shows the signed-in user's Microsoft 365 (Outlook) calendar inside a
FullCalendar view,
alongside the Drupal content that view already renders.

A site builder enables it per display: open a view whose format is
FullCalendar, expand Microsoft 365 calendar, and tick
Show Microsoft 365 events. FullCalendar then fetches only the
visible date range on every navigation, so a year of appointments is never
loaded to show one week.

Features

  • Personal calendar of the signed-in user, read-only, via Microsoft Graph
    /me/calendarView, so recurring series arrive already expanded
    into individual occurrences.
  • Lazy per-range loading driven by FullCalendar itself. No custom
    JavaScript, and no patch to the FullCalendar module.
  • Private and confidential appointments show as "Busy" with no
    subject, location or meeting link. On by default, switchable per
    display.
  • Optional filtering on Outlook's free/busy status, and hiding of cancelled
    appointments.
  • Per-status CSS classes, so a theme can style tentative, out-of-office and
    cancelled appointments distinctly.
  • hook_o365_fullcalendar_event_alter() for modules that need to
    reshape an event before it reaches the browser.
  • An example view ships as optional configuration, so there is something
    working to look at immediately after install.
  • Degrades quietly: an expired token or a Graph outage leaves the calendar
    rendering its Drupal events, never an error page.

Requirements

  • Microsoft 365 Connector
    with the Microsoft 365 SSO submodule configured. Each user
    must have signed in through it; users without an o365_sso
    authmap entry simply see no Microsoft 365 events.
  • FullCalendar 4.x
    and its JavaScript library.
  • Drupal 11.1 or newer. The module uses attribute-based hook discovery,
    which core only supports from 11.1. Note this is narrower than
    o365 itself, which still supports Drupal 10.

Configuration

Per-display settings live on the FullCalendar format settings of each view.
Site-wide guard rails — the maximum date range a single request may span, the
maximum number of events requested from Graph, and how long results are cached
— live at
Administration › Configuration › System › Microsoft 365
› FullCalendar
.

Customising how an event looks

FullCalendar draws events in JavaScript from a JSON feed, so there is no Twig
template per event. There are three levers instead, in increasing order of
power:

  • CSS. Every event carries o365-event plus a
    status class — o365-event--busy, --free,
    --tentative, --oof,
    --workingElsewhere — and o365-event--cancelled
    where it applies.
  • PHP. Implement
    hook_o365_fullcalendar_event_alter() to change the title,
    colour, classes or extra data. See o365_fullcalendar.api.php.
    Implementations must respect the masking the module has already applied.
  • JavaScript. Listen for the
    fullcalendar:preBuild DOM event that FullCalendar 4.x
    dispatches and set calendarOptions.eventContent to render your
    own markup, reading extendedProps.o365 for the location and
    meeting link.

Privacy

Each user only ever sees their own calendar; the module only ever calls
Graph's /me/ endpoints. The HTTP response is marked
private, no-store and never enters a shared or CDN cache. The raw
Graph payload is cached server-side, keyed per user, for a configurable
interval; set cache_ttl to 0 to disable that
entirely.

Related modules

Activity

Tracked releases
3
Tracked since
Aug 2026
Latest release
4 days ago
Releases (12 mo)
3 ▲ from 0
Maintenance
Active

Release Timeline

Releases

Version Type Release date
1.0.0 Stable Aug 19, 2026
1.0.0-alpha1 Pre-release Aug 19, 2026
1.0.x-dev Dev Aug 19, 2026