For those of us working in specialized industries, investing in the strict microformat standardization process for most of the data we trade in is a lofty goal, with little reward. Microformats are standardized to encourage the browser and other software to apply behavior to the marked-up data (say, extracting a vCard and adding it to your email client). Furthermore, they’re generally, if not necessarily, used to mark up very common data—what customer facing website doesn’t have contact information?—not industry- or application-specific data formats.
But surely we’re already using lovely Plain Old Semantic HTML (POSH), and I think it can solve a long-standing problem: getting server-side data into JavaScript data structures on pageload.
The Problem
Any website that remotely resembles an application (blogs included) is working with page templates, which are populated with data from a database on pageload (at least if a responsible, progressively-enhancing web developer is behind it). If and when AJAX functionality is added to these pages, the application’s JavaScript code needs to know about these data.
The goal is to get a chunk of data into the markup and into some sort of JavaScript data storage without making multiple database queries for the same data, repeating myself, or violating any other rules of good coding.
Common Approaches
(Please note that these examples all assume Ruby on Rails and jQuery and are wildly simplified.)
Insert JavaScript into the body of the document:
Not bad, but thou shalt not include JavaScript in the body of the page, right?
Moreover, I would have already spit my data into the view (HTML) file when I generated the markup. I’m only making one database query, but I’m printing my data to the template twice. I’d like to avoid this redundancy.
Make an AJAX call after pageload:
This method eliminates the problem of putting JavaScript in the body of the document, but it means that I’m fetching data that I already fetched when I generated the markup. That is, I’m making the same database query twice.
Generate JavaScript on the server side
There’s another solution, which involves generating JS files on the server side, but since the data I’m trying to get from the server may be different on a request-by-request basis, I’d have to generate the file on every request, rather than compile it once at build or deploy time. This would inhibit or eliminate the possibility of caching, so we can give a pretty definitive thumbs down to this approach. I’m only mentioning it for the sake of thoroughness.
Enter poshformats
According to microformats.org:
the term “poshformats” distinguishes these one-off, ad-hoc or more informal class-name based formats efforts (based on long-standing modern web design POSH practices) from the more formally researched and documented microformats.
A poshformat looks like a microformat, but it hasn’t been defined and vetted with as much rigor.
For example: The markup (poshformat)
Say I work for a website that analyzes baseball statistics. I’m always displaying players’ stats and information on my pages, then doing all kinds of fancy AJAX-y things to these player representations. The POSH markup for one of these player representations might look like this:
What we have here is a “poshformat.” According to microformats.org, “When the author of that POSH declares it to be a ‘format’ of some sort, then they’ve created a poshformat.” Well I just did.
For the sake of simplicity, the “player” instance above only includes a name, a photo, and some “vitals.” But it could easily include basic stats, like batting average, hits, and runs, plus advanced stats, like OPS and VORP. Good poshformatting is perfectly extensible.
“But I’ve got the HTML5 itch!”
The HTML5 data-* attributes are commonly used to provide data relevant to JavaScript hook-ins.
“That’s what this is, right?”
Well, sort of.
Regarding data-* attributes, the HTML5 specification says this:
Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
These player data will appear in search engine results; they may appear in an RSS feed. In other words, they aren’t private. However, what I have isn’t a microformat or RDFa; the labels I provide to it are not for the benefit of these or any other applications outside my page.
A microformats.org article, Microformats in HTML5, says this:
Note that the data-* stuff is explicitly not for microformats. […] They are intended for script authors to have a space in which they can play without ever clashing with anything the browser does. There may be some cases of private poshformats that are never intended for interchange that may be used in data-* attributes.
We’re getting some mixed signals, but they seem to be pointing towards sticking with good old classnames.
Sure, I could use CSS attribute selectors to style elements by their data-* attributes, but classes were always perfectly good for this. And, if I’m bearing in mind the tenets of progressive enhancement, as I should be, I’ll ignore my intention to eventually add JavaScript functionality when marking up the data. Surely, then, I’ll mark it up with good POSH classnames from the beginning, and only add data-* attributes if and when I need them for my scripting.
That said, some data is not displayed but is vital for any JavaScript code that will be making AJAX calls to the server. For instance, it doesn’t do Google or my RSS reader or any average reader of the site any good to know what unique ID Casey Atthebat’s database entry has been assigned, but I need it if I’m telling the server which database row to update. This is where data-* attributes are perfect. I can just add data-player-id=”1234567″ to the section.player tag, and make sure I look for it when scraping my poshformatted markup. I could also consider using the itemid microdata attribute.
JSONifying our poshformat
I know I’m going to be manipulating this data and the corresponding DOM (Document Object Model) representation via JavaScript, so I want to get it into everyone’s favorite data exchange format, JSON, as soon as the page loads:
I’ve already reviewed the old ways of doing this and decided I can do better. Here’s where JavaScript and poshformats play nicely.
The POSH way
When my page loads, and I initialize my JavaScript, I can say something like this (I’m assuming jQuery, for simplicity’s sake):
Problem solved!
A note on Skytap’s use of this technique: SmartClient presents a tricky problem: it is possible to open SmartClient for an environment that has no VMs, but to which VMs could be added by another user or from another page. If SmartClient loads with an empty environment, there is no poshformatted data from which to gather the structure of VM data. In such cases, we reload the page after the first VM is added.
Next steps
The astute reader will point out that the above code is extensible only by adding additional lines of code and not very generic either. That’s true. The next step is to develop a generic way to define a model and automatically extract instances of that model from the poshformatted DOM.