Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenCalendar

Deutsch: README.de.md

CI License: MIT

OpenCalendar is a Grav CMS plugin that aggregates events from ICS, CalDAV, JSON, and local sources into a unified, searchable calendar with SQLite storage, flexible display options, and optional REST API access.

Overview

Modern sites often pull events from Google Calendar, Nextcloud, custom APIs, and static files at the same time. OpenCalendar normalizes these feeds into one queryable store and renders them through calendar views, lists, Twig templates, shortcodes, or JSON endpoints — all configurable from the Grav Admin or YAML.

Built for PHP 8.2+ with strict typing, PHPStan level 8, and PSR-12 code style.

Features

  • Multiple source types — ICS/iCalendar, CalDAV, JSON APIs, local files
  • Admin file upload — import .ics / .json from the Synchronization dashboard into SQLite
  • Grav 1.7 & 2.0 — classic Admin plus Admin Next (compatibility: ['1.7', '2.0'])
  • SQLite storage — fast queries, FTS search, no external database required
  • Background sync — configurable intervals with Grav Scheduler integration
  • Dual views — interactive calendar (month/week/day) and grouped list views
  • Search & filters — full-text search plus source, category, and date filters
  • Twig & shortcodes — embed anywhere in your theme or page content
  • Optional REST API — read-only JSON with rate limiting
  • Internationalization — English and German admin/frontend strings
  • Caching — parse and render caches for production performance
  • Admin UI — tabbed configuration (General, Storage, Sources, Display, Search, Filters, Synchronization, Advanced)

Architecture

OpenCalendar uses a layered design: source adapters fetch and parse feeds, a sync pipeline writes to SQLite, services handle queries/search/filters, and Grav integration (Twig, shortcodes, API) sits at the edge.

Sources (ICS/CalDAV/JSON/Local) → Sync → SQLite → Services → Twig / Shortcodes / API

See docs/en/Architecture.md for details.

Installation

Requirements

  • Grav 1.7.0+
  • PHP 8.2+ with pdo, pdo_sqlite, json, mbstring

GPM

bin/gpm install opencalendar

Manual

Download the release ZIP from GitHub Releases (filtered install package — no docs/tests/CI), extract to user/plugins/opencalendar, then clear cache:

bin/grav cache

Release and GPM packages include the production vendor/ tree — no Composer step on the server. Clone the git repo only for development (composer install adds test/tooling deps).

Enable in Admin → Plugins → OpenCalendar or set enabled: true in config.

Full guide: docs/en/Installation.md

Updating

  1. Back up user/config/plugins/opencalendar.yaml and data/opencalendar.db
  2. Update plugin files (GPM or git pull)
  3. Clear cache: bin/grav cache

Schema migrations apply automatically. See docs/en/Migration.md.

Configuration

Defaults live in opencalendar.yaml. Override in user/config/plugins/opencalendar.yaml:

enabled: true
timezone: Europe/Berlin
sync_interval: 15
sources:
  - name: Team Calendar
    enabled: true
    type: ics
    url: 'https://example.com/calendar.ics'
    color: '#3788d8'

Configure everything from Admin → Plugins → OpenCalendar with tabs for General, Storage, Sources, Display, Search, Filters, Synchronization, and Advanced settings.

To import a calendar file manually: Synchronization → Upload calendar file (.ics / .ical / .json). Guide: docs/en/Synchronization.md.

Full reference: docs/en/Configuration.md

Views

View Description
Calendar Month, week, day, or list-week layouts with navigation
List Grouped chronological list with pagination

Set default via display.default_view or per-page with shortcodes.

Twig

{% set events = opencalendar_events({ from: 'now', to: '+2 months', limit: 10 }) %}
{% for event in events %}
  <article>{{ event.title }} — {{ event.start|opencalendar_format_datetime('medium') }}</article>
{% endfor %}

Include plugin partials or override in your theme.

Guide: docs/en/Twig.md

Shortcodes

[opencalendar view="calendar" show_filters="true" /]
[opencalendar view="list" limit="5" from="now" to="+30 days" /]
[opencalendar-search /]

Guide: docs/en/Shortcodes.md

Searching

Full-text search across title, description, location, and categories. Configure in Admin or YAML:

search:
  enabled: true
  min_query_length: 2
  max_results: 25
  highlight: true

Guide: docs/en/Searching.md

Filtering

Filter by source, category, and date range. URL persistence enables shareable filtered views.

Guide: docs/en/Filtering.md

Synchronization

Remote feeds sync on a schedule (default: every 15 minutes). Per-source refresh overrides, deduplication, recurring expansion, and cleanup policies keep the database accurate without unbounded growth. The Admin Synchronization tab also supports force sync, rebuild, and manual calendar file upload.

Guide: docs/en/Synchronization.md

SQLite

Events persist in data/opencalendar.db with WAL mode, FTS5 search, and automatic schema migrations.

Guide: docs/en/SQLite.md

Caching

Parse cache avoids re-reading unchanged feeds; render cache speeds up Twig and API responses. Tune TTL for your traffic and update frequency.

Guide: docs/en/Caching.md

Performance

  • Enable WAL mode and caching in production
  • Use reasonable sync intervals (avoid polling every 5 minutes unless needed)
  • Limit recurring horizon for large infinite recurrences
  • Paginate list views and API responses

REST API

Optional read-only JSON API (disabled by default):

GET /opencalendar/api/events?from=2026-07-01&to=2026-07-31

Guide: docs/en/API.md

Troubleshooting

Common issues: sync failures, empty calendars, permission errors, scheduler not running.

Guide: docs/en/Troubleshooting.md

FAQ

Quick answers on sources, Google Calendar, SQLite, licensing, and more.

Guide: docs/en/FAQ.md

Documentation

Full index (EN + DE): docs/README.md

Document Topic
Installation Setup and requirements
Configuration All config options
Architecture Code structure
Sources ICS, CalDAV, JSON, local, Admin upload
ICS iCalendar specifics
Synchronization Sync, cleanup, Admin upload
SQLite Database storage
Twig Template integration
Shortcodes Page shortcodes
Subscribe / Abonnieren Network calendar / phone subscription
Documentation index English & German docs overview
Searching Full-text search
Filtering Event filters
Caching Cache layers
API REST endpoints
Development Contributor guide
Migration Upgrades
Troubleshooting Problem solving
FAQ Common questions
Publishing / GPM Official Grav repository listing

Roadmap

  • CalDAV discovery and multi-collection sync
  • JSON API and local file source adapters
  • Admin dashboard widget with sync status
  • Webhook-triggered sync for push updates
  • Export to ICS
  • Additional language packs
  • Event pipeline hooks for custom processing

Track progress on GitHub Issues.

Contributing

Contributions welcome! Read CONTRIBUTING.md (DE), follow composer check, and submit a pull request.

License

MIT — Copyright (c) 2026 TimUx

Author

TimUxgithub.com/TimUx

Repository: github.com/TimUx/grav-plugin-opencalendar

About

Grav CMS plugin: aggregate ICS, CalDAV, JSON, and local calendars into SQLite with calendar/list views, Twig, shortcodes, and API

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages