tattali/calendar-bundle
A Symfony bundle for rendering responsive calendars in Twig, with month, week, and day views. Feed events through flexible providers, customize templates and styling, and add schedulers or event calendars to any Symfony app with minimal configuration.
timeZone parameter is now supported (#102), meaning the endpoint accepts the client's timezone context instead of us translating it in a shim. Combined with ISO 8601-only start/end dates (#149), the transport contract becomes well-defined. What is not solved: our policy for which timezone a calendar defaults to, how users perceive all-day events, and how we display times across regions. Those stay ours, but the plumbing below them is now less custom.304 Not Modified and avoid re-sending unchanged payloads. For a PM this creates a decision surface: freshness expectations ("why hasn't my calendar updated?"), cache invalidation on write, and the guarantee that private caching respects per-user event visibility. It also directly addresses the previously-flagged scaling concern at realistic event volumes — a genuine roadmap de-risker for high-traffic calendar surfaces.final (#147, #148) removes subclass-based customization. That is a constraint if anyone assumed we'd extend the parser to bend the contract. But wiring the controller to parser/serializer interface aliases (#146) preserves the important thing: we can swap implementations through the container. Decision supported: compose and decorate behind our own adapter; do not plan on inheritance.Consider it when:
private ETag revalidation on the GET path, so cached-feed behavior is available without custom code.timeZone support).Look elsewhere when:
timeZone support and GET/ETag caching, and you carry the earlier request-parsing defect if you are below 8.2.1 — treat the upgrade as a scheduled item, not an indefinite deferral.final; you'd be forking.To executives (one paragraph): We evaluated a small, actively maintained open-source PHP package that supplies the server-side plumbing behind a calendar view — the part that answers "which events fall in this date range, with these filters." It is not a scheduling engine; it does not store events, handle permissions, recurrence, or booking logic. Its value is narrow and concrete: it removes roughly one to two weeks of undifferentiated engineering per calendar surface and replaces it with a dependency. The new release, v8.3.0, is a feature release with breaking changes: it adds timezone-aware requests, supports GET requests with client-side revalidation (fewer redundant payloads), and tightens date handling and internal quality gates — all of which reduce the custom code we'd otherwise own. It also raises the platform requirement to PHP 8.4 and Symfony 8, so adoption now includes a genuine upgrade workstream alongside the integration spike. Recommendation: approve as a scoped dependency behind a thin internal adapter, fund the PHP 8.4 upgrade as a separate, scheduled line item, and run a short integration spike against v8.3.0 (not an older pin). The package is healthier than at the last review, but it is moving quickly — we should expect to budget an upgrade each minor release rather than assume a one-time integration.
To engineering: Still a request-parsing and event-feed transport layer, not a domain model. v8.3.0 is a breaking release — follow docs/upgrade-to-83.md, which lists one migration step per change. Practical implications: (1) Platform floor — PHP 8.4+ and Symfony 8; validate this against Laravel's component versions and our runtime image before committing, and plan the upgrade explicitly. (2) Timezone — the timeZone parameter (#102) is now accepted and passed through, with immutable request dates handed to listeners (#144); we no longer need our own translation shim, but display/default-timezone policy stays ours. (3) GET + ETag — the feed accepts GET with private ETag revalidation (#101); ensure we never front it with a shared cache, since private is what keeps per-user event visibility safe, and define invalidation on write. (4) Dates — only ISO 8601 start/end are accepted (#149); DateTimeInterface is accepted and immutable dates are returned from getters and constructor/setter paths (#141–#145), which removes a mutation-bug class. Verify our client emits compliant ISO 8601. (5) Extensibility — parser, serializer, and exception classes are final (#147, #148); do not plan on subclassing. Instead, bind the parser/serializer interface aliases (#146) to our own implementations or decorators. This reinforces the existing decision: wrap the endpoint in an application-level adapter with our own DTOs so a swap or fork stays contained. Caveats to validate in the spike: Laravel routing/middleware fit against the Symfony 8 constraint, authorization enforcement on event visibility combined with ETag caching, timezone display policy, and behavior at realistic event volumes with and without cache hits. If the spike shows integration friction exceeding ~2 weeks or the PHP 8.4/Symfony 8 upgrade proves costly, build the thin endpoint ourselves — the scope is genuinely small.
How can I help you explore Laravel packages today?