Deutsch: README.de.md
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.
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.
- Multiple source types — ICS/iCalendar, CalDAV, JSON APIs, local files
- Admin file upload — import
.ics/.jsonfrom 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)
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.
- Grav 1.7.0+
- PHP 8.2+ with
pdo,pdo_sqlite,json,mbstring
bin/gpm install opencalendarDownload the release ZIP from GitHub Releases (filtered install package — no docs/tests/CI), extract to user/plugins/opencalendar, then clear cache:
bin/grav cacheRelease 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
- Back up
user/config/plugins/opencalendar.yamlanddata/opencalendar.db - Update plugin files (GPM or git pull)
- Clear cache:
bin/grav cache
Schema migrations apply automatically. See docs/en/Migration.md.
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
| 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.
{% 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
[opencalendar view="calendar" show_filters="true" /]
[opencalendar view="list" limit="5" from="now" to="+30 days" /]
[opencalendar-search /]
Guide: docs/en/Shortcodes.md
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: trueGuide: docs/en/Searching.md
Filter by source, category, and date range. URL persistence enables shareable filtered views.
Guide: docs/en/Filtering.md
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
Events persist in data/opencalendar.db with WAL mode, FTS5 search, and automatic schema migrations.
Guide: docs/en/SQLite.md
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
- 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
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
Common issues: sync failures, empty calendars, permission errors, scheduler not running.
Guide: docs/en/Troubleshooting.md
Quick answers on sources, Google Calendar, SQLite, licensing, and more.
Guide: docs/en/FAQ.md
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 |
- 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.
Contributions welcome! Read CONTRIBUTING.md (DE), follow composer check, and submit a pull request.
MIT — Copyright (c) 2026 TimUx
TimUx — github.com/TimUx
Repository: github.com/TimUx/grav-plugin-opencalendar