A few months ago, I read Adaptive Web Design by Aaron Gustafson. If you have anything to do with making web pages, read this book. And while you’re at it, also read the entire A Book Apart series. Excuse me while I wipe all that brown off my nose.
Anyway, among the 48 tons of awesome knowledge in Adaptive Web Design, Aaron introduced me to microformats. These are cool formats based on existing usage patterns that allow web designers and developers to include extra information in a page’s markup. In keeping with the spirit of responsive design, these extra bits of information enhance the experience for those who can use them and have no impact on those who can’t.
There are many kinds of microformats, but the one I was immediately interested in is called hCalendar. The hCalendar format basically embeds a calendar event into a web page with special markup. If a user has something to read hCalendar markup, like a plugin for Firefox or Chrome, that user can download the event, add the event to a calendar, or do anything else the app allows. Because we have a calendar on our home page, I figured it would be cool to add hCalendar code to our existing calendar items. With a very brief re-work of the existing calendar items, I was able to include hCalendar functionality:
<asp:Label ID="lblOpenAnchor" runat="server" class="vevent">
<a id="calendarLink" runat="server" href='<%# DataBinder.Eval(Container.DataItem, "calLink") %>' target='<%# DataBinder.Eval(Container.DataItem, "calTarget") %>'><%# ((Convert.ToDateTime(Eval("calDateStart")) == DateTime.Today) ? "Today" : Convert.ToDateTime(Eval("calDateStart")).ToString("MMMM d"))%>: <span class="summary"><%# DataBinder.Eval(Container.DataItem, "calTitle").ToString().Contains('&') ? DataBinder.Eval(Container.DataItem, "calTitle").ToString().Substring(0, DataBinder.Eval(Container.DataItem, "calTitle").ToString().LastIndexOf('&')) : DataBinder.Eval(Container.DataItem, "calTitle").ToString() %></span></a>
<span class="dtstart" title='<%# Convert.ToDateTime(Eval("calDateStart")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'-05:00'") %>'></span>
<span class="dtend" title='<%# Convert.ToDateTime(Eval("calDateEnd")).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'-05:00'") %>'></span>
That server-side code is part of an ASP.NET Repeater which is bound to calendar items in a data source. That repeater results in the following example markup in the browser:
<span id="rptCalendar_lblOpenAnchor_6" class="vevent">
<a href="http://www.co.frederick.va.us/board_of_supervisors/" id="rptCalendar_calendarLink_6" target="_self">January 25: <span class="summary">Board of Supervisors meeting</span></a>
<span class="dtstart" title='2012-01-25T19:15:00-05:00'></span>
<span class="dtend" title='2012-01-25T21:00:00-05:00'></span>
The class=”vevent” attribute tells the microformat parser that this is some hCalendar info. Then we have a summary and some start and end times. Here’s what it looks like in Chrome with the microformat parser:
Many people who use hCalendar actually use the <abbr> element for the times, but in HTML5, we have the <time> element. Unfortunately, at the time I was creating this, the CSS3 Working Group was unsure of supporting the <time> element moving forward. I did not want to use the <abbr> element for times because it just didn’t seem semantically appropriate (not that I never abuse semantics), so I opted to just mark a span up as time. That worked fine, made me feel good, and didn’t carry over any special formatting or functionality that browsers might apply to <abbr> in our CSS non-reset website.
Neat stuff. Now, if a user is extremely interested in that Lake Holiday Dam Working Group meeting, he can easily add it to his calendar. If a user doesn’t have something to parse microformats, he doesn’t even know he’s missing anything. That, I believe, is progressive enhancement.
Want to read more about time in a web page? Check out Write iCalendar file with C#.