A Hesitant Upgrade
I’ve gone on record many times as a self-deprecating coder. I despise a lot of what I’ve created — especially the really early stuff. So when the newest version of SilverStripe finally reached its stable release, I was pretty well convinced that none of my antiquated, convention-breaking work would ever see the light of the polished and affection-worthy 3.0 world. For the most part, that has stayed true. Goodbye, DOM, hello GridField. Goodbye, Uploadify, hello, UploadField. Goodbye, ImageGallery, hello — well, something will come along, right?
Then a project came along that was to be built in 3.0 that required an event calendar. I looked for every possible way around using the tired old beast of a module, but when all was said and done, it made more sense to improve what was there than to reinvent the wheel.
Rebuilding EventCalendar for 3.0 was actually a nourishing and cathartic experience. It felt good to have a reason to clean up and enhance a tool that has offered so much utility to so many users. Along the way, a lot of new features were added — some entirely new ideas, and others improvements on old functionality.
Here are some of the highlights you’ll find in EventCalendar 3.0, now in the master branch on Github.
Rebuilt from the ground up. Almost.
It was overwhelming looking at everything that needed improvement in the EventCalendar codebase. Rather than take a hatchet to the existing code, I started with a blank slate and included only what was good in the old codebase. The result is a much cleaner architecture that takes advantage of the things that SilverStripe 3 does best.
Templates that stay out of your way.
The default templates for EventCalendar 3.0 are exceedingly minimal in design. Rather than have users fight with tangled HTML structures and hundreds of lines of CSS selectors, the module uses the templates to show off its features and functionality rather than offering up an opinionated layout and design.
An improved (Live)CalendarWidget
The old EventCalendar offered two types of calendar widgets. The first was a plain client side calendar that had no communication with the database. The second, $LiveCalendarWidget offered asynchronous communication with the database, allowing users to see which days had events. Since $LiveCalendarWidget was generated server side, it had severe latency problems.
The new $CalendarWidget template variable combines the best of both worlds. The widget now operates mostly client side, but polls the database in broad strokes to get information about many months at a time. If the information for the current month already exists in memory, it doesn’t run the request. The result is a much faster and user-friendly calendar.
More i18n options
The last version of EventCalendar had several challenges with localization and translation. The CalendarWidget did not translate easily, and there was a lot of trouble negotiating the cultural definition of the first day of the week. In the United States, it’s Sunday, but elsewhere it’s Monday.
This is all cleaned up in the new version of EventCalendar. There’s even a translatable field for “FIRSTDAYOFWEEK” to make things extra simple.
More intelligent handling of the default view
One of the challenges for any calendar is figuring out what to show on the default page. If the calendar is densely populated, maybe you want to show just this week. But what if it’s Friday? If the calendar is lightly populated, maybe you just show this month, but what if it’s the 27th? You can show the next 30 days, but if there’s nothing happening on the horizon, it can create a spooky place for a user to hang out.
The last version of EventCalendar addressed this by showing the next X number of events, with a limit into the future that could be defined in the CMS — i.e. “Show the next 10 events, but don’t go farther than six months from today.”
The new version of EventCalendar offers many more options:
- Show a list of upcoming events: Show the next X events, within the next Y months, where X and Y are both defined in the CMS.
- Show this month’s events: If it’s August 27th, show August 1 – 31.
- Show this week’s events, and fall back on this month: Show Monday-Sunday (or Sunday-Saturday), but if the set is empty, fall back on the month view.
- Show today’s events, and fall back on this week: Show today, and if nothing is happening today, show this week.
- Show this weekend’s events: If it’s Sunday, show the next weekend.
This highly granular level of control will help content editors deliver something truly meaningful to their users.
In addition to CalendarWidget, there is now a $MonthJumper widget that allows a user to select a month and year from a pair of dropdowns.
Also, the new “QuickNavBar” include allows easy filtering of events for this month, week, weekend, or today.
Pagination on a calendar never seemed appropriate to me. Who cares what’s on page 8 when you’re on page 2? But there are clear benefits to pagination when it comes to database overhead. To that end, the pagination in event calendar is more of an “infinite scroll” approach, where the user is offered a link for “more events” that append to the existing event list.
Further, each view has “next” and “previous” links that are context aware. When viewing a month, the “next month” and “previous month” links are available. When viewing a weekend, it changes to “next weekend” and “previous weekend,” etc.
With the migration to InnoDB, we don’t have much in the way of fulltext search options without a thirdparty tool, but EventCalendar does support a simple search of events. Just append ?s=your+search+query to the URL.
Every component of EventCalendar now offers itself up to the decorator pattern. Customize as you see fit.
There are a ton of features that have yet to be implemented, including the import of ICS files, inclusion of remote feeds, and a calendar filter form. Further, there still needs to be a lot of testing for i18n users, and lang files need to be created and populated.
What you can do
Try it out, test it, and by God, submit those pull requests!