Archive Page 2

OAuth authentication flow

I came across this thread by Jeff Hodges on the Google OAuth group and thought it worth sharing.

OAuth authentication flow

In the wild snapshot#2:

An excellent in the wild post written by Josh Patterson about his project with some feedback from me, so the credit really goes to him. For those of you unfamiliar with this series of posts, the idea is to create blog-length interviews with various in the wild apps describing their processes and the technologies that they use with regards to data portability. The goal is to profile real use cases, solutions, and lessons learned when it comes to the current state of affairs for data portability technology. Note that these posts aren’t meant to recommend or not recommend certain technology, I leave that up to the developers/architects to decide based on their needs. If you have such an app and are interested in being interviewed, please leave me a comment on one of my posts and I will get in touch with you.

Application Overview
Basically with we started out just wanting to try out some video ideas we had. We started out with a simple playlist of videos on the internet linked together at a site, which evolved into a full own video editor. After a number of months of development we hit a point where the team sat down with some users and did a testing session, asking questions and gauging responses to see how well we were hitting our marks. We came to the subject of data storage, local hardrives, and getting media online, and just as a thought exercise I asked “well, what if just knew about all your online media by your login name, and referenced it automatically in your libraries the first time you logged in — just as if it was an app installed locally on your hd?” and immediately both of them became excited and one asked “can I do that right now? when can I use that?” and I knew from experience that the market was speaking very loudly and clearly in my direction, and that I had better listen very closely.

The very next meeting I posed this question to our team:

What if our app was “inherently installed” in the internet? What if someone logged in, and the app just acted like a desktop app that “knew” about your flickr images, your youtube videos, it knew about your myspace friends, facebook friends, and automatically treated them as one logical database, one logical social graph? And someone started right into an app tutorial right off the bat with their contacts, files, and assets already referenced (but fully respecting privacy, control, etc)?

So the next question naturally becomes “that all sounds really great, but … how do we get there?”

From there we really began to push a “what if this/that” scenario, and drew up our ideas into a document entitled WRFS and from that we began to re-engineer the app towards a truly linked data experience.

We are currently using FLEX/as3 for the editor and player with ASP.NET for the server technology. Discovery is a big deal with how I view next gen web apps — dynamically finding data at runtime without having to go through “Big Data’s” walls to get to it. How I see this happening is

  1. the user logs in with an identity url, be it an openID or a XRDS file location. is an openID only application, but user’s can map multiple openIDs to one account with it.
  2. the app authenticates the user, and then uses multiple fallback methods to find the XRDS-S file if not specified.
  3. The XRDS file is parsed, and relevant data types (here image and video) location uris are pulled out
  4. Each uri points to a data container, which is then queried via its API for a list of resources the user has stored there.
  5. these results are then aggregated back together into a single “recordset” to be returned to the application layer

The fallback methods for XRDS discovery (done in the FLEX client) are ordered as:

  1. First do basic yadis discovery to see if the identity delegate is the openID provider or a blog of some sort head link delegation setup. Either the openID provider or the XRDS location may here, or both. In some cases, such as the DiSo XRDS plugin, the XRDS file located in the head link tag will have the openID provider location.
  2. The secondary method we have kicked around is to query the openID provider for an Attribute Exchange key that points to the XRDS file. This is not well defined yet but has been discussed amongst various groups.
  3. Lastly we fallback to having our flex app prompt the user for a XRDS url so that we can “enhance their user experience”.

So although I think our secondary option with the AX key is a little shaky right now, overall we degrade gracefully.

For a quick demo of how some of the data query and aggregation mechanics might work, I’ve built a short demo illustrating the step by step mechanics.

Lessons learned
We aren’t done with this application, obviously, and a lot of work remains to be done – I should note that I am currently at Step 2 of 5 as stated above. However, the application is evolving into the embryo of what I think a linked data application can and will be. What I can share are the places that we are actively looking for solutions, simple decentralized solutions, that solve these issues.

One thing that is slowly changing is the perception of cross domain scripting on the internet. As services get more complex, and require more aggregation of data from multiple sources, we are going to push more data handling duties to the client, as scalability will suffer. For flash crossdomain scripting we need the crossdomain.xml file present on the server of the api would like to call for it to work. This is a trivial thing to setup as it consists of a simple xml file located off of the subdirectory level you wish to grant access to.
Once this file is exposed, the flash runtime will then allow calls from the client to those servers.

For cross domain client side javascript, things get a little bit trickier. A lot of cross domain tricks, such as widget embedding, is done via iframe embeds. This type of embedding significantly restricts access to the rest of the page, so effectively the widget is isolated in terms of interaction with the rest of the page DOM. Firefox 3 will allow cross domain client side scripting with certain http headers being present on the server response from the remote cross domain endpoint. I’m not sure how future versions of Internet Explorer will address this issue, but I think evolutionary pressure from both Firefox and Flash will yield some effect there. A new development that is supposed to make javascript more secure is Google Caja. I’ve begun to follow Google Gaja but I’ve yet to deeply jump into that project.

We’ve been waiting to see how the discovery wars pan out, as it stands now XRDS-S is looking like the service index of choice amongst the big players (presently Yahoo is endorsing it, hiring Eran Hammer Lahav as their Open Standards Evangelist. How the XRDS resource is discovered automatically without a tremendous amount of user interaction is something that we are taking many approaches towards, as discussed above. For now we’re going to focus on finding XRDS files as our catalog of service endpoints for a user. The DiSo project is going to be publishing its user’s service endpoints in the XRDS format and already has a plugin for it, so I think in the short term we’ll be focusing on consuming that data in terms of an early conceptual demo in runtime linked data.

Once we find the XRDS file, we aren’t out of the woods. How do I set my XRDS file up so that I can tell the application that I have “images in flickr”? This is a fundamental question being setup and worked on at the site by many different groups and people, and has yet to fully be fleshed out.

There’s also the issue of once we find a data endpoint, how do we talk to it? ATOM? Some sort of standard data interop api that spits out RDF? In a perfect world I’d love to see a self organizing web, a linked data web that can find a data endpoint at runtime, find its semantic schema, and wire itself such that it can talk to that api without ever needing user intervention — it simply will understand how to talk to it.

Another key development will be the permission system, possibly using OAuth+Discovery to automate the updating of a XRDS-S file for someone when they add data to a service. I need to learn a lot more about OAuth and the direction its heading. I’d prefer a world where the user doesn’t need to manually go to a site to allow their resources to be used by a third party, but for now, this is how we have to operate.

So really, I think I have more “lessons underway” than “lessons learned”, but sharing this information is key since it sparks interest in other like minded developers who may know a lot more about some of these areas than me. There’s going to be some places that we punt and just hard code some scaffolding code in to just get going, but over time I’d like to evolve towards a linked data web that auto discovers new connections at runtime and self organizes to give a smarter and far more intuitive user experience than we’ve seen so far.

If you are interesting in linking data or trying some data interop experiments, please feel free to email me (jpatterson at or check out the WRFS workgroup or my blog

Feedback and suggestions are welcomed.

I like to FOAF you

No, it isn’t a proposition, so get your mind out of the gutter đŸ™‚ FOAF stands for Friend-of-a-Friend and is a RDF taxonomy capable of describing a person and his/her friend(s) in far more glory details than XFN, in fact it is a competing standard. Reading your mind, you are probably going to ask me, what is RDF? RDF (first published specs in 1999) stands for Resource Description Framework which means absolutely nothing to most people however it is often touted as the foundation for the so-called semantic web. If you want a good introductory RDF post, check out What Is RDF. A synopsis of RDF extracted from this ReadWriteWeb post Semantic Web Patterns: A Guide to Semantic Technologies

RDF is a powerful, graph-based language for declaring things, and attributes and relationships between things. In a simplistic way, one can think of RDF as the language that allows expressing truths like: Alex IS human (type expression), Alex HAS a brain (attribute expression), and Alex IS the father of Alice, Lilly, and Sofia (relationship expression). RDF is powerful, but because it is highly recursive, precise, and mathematically sound, it is also complex.

On a high level, FOAF has the following categories

  • Person’s basic information such as name, nick, title, homepage, email, surname, first name, given name, email (expressed as mbox), etc.
  • Person’s extended information such as blog, interest, project, school home page, work home page, friend(s) he knows, etc.
  • Person’s online accounts (includes instant messaging)
  • Person’s projects and groups
  • Person’s documents and images

As you can see, it allows for extensive coverage of a person’s information. If you want the full details, check out FOAF Vocabulary Specification 0.91. Assuming you have a basic knowledge of XML, let’s take a simple example to illustrate how FOAF is actually written.


<foaf:name>John Doe</foaf:name>
<foaf:mbox rdf:resource="" />


The above XML snippet describes a person’s name and email, obviously John Doe is not a real name and is not a real email but you get the idea. Technically this describes a person, not the “me” identity as defined by XFN rel-me.

Let’s take a more slightly more complex example



<foaf:name>John Doe</foaf:name>
<foaf:mbox rdf:resource="" />
<foaf:mbox rdf:resource="" />
<foaf:name>Jane Smith</foaf:name>


Basically the above FOAF says there is a person John Doe, his email is, he “knows” Jane Smith, and her email is Note that “knows” does not necessarily equate to a friend, it simply means that you know someone, that person could be a friend, lover, co-worker, parent, sibling, or someone you met online but not in person, etc. For a more in-depth look at FOAF, check out XML Watch: Finding friends with XML and RDF.

Ok, now that you know how to create basic FOAF, what next. Unlike XFN / hCard / microformats, FOAF is delivered via a file separate from any HTML markup. Creating a FOAF file is not something that a Joe Blow user will ever do manually. However, if you are curious and want to play around with creating FOAF, you can use this handy tool FOAF-o-Matic. For most users, their service providers, the ones that support FOAF, will handle all the intricate details behind the scene. For example, if you have an account at MyBlogLog, you can check out their FOAF feature by appending “/foaf” to the end of your MyBlogLog member URL. If you aren’t a MyBlogLog member, here is Ken Brewster’s MyBlogLog FOAF file,, and check out his fun FOAF consuming app, picture below
Ken Brewster FOAF app

Since FOAF is a separate file, you have to link to it from a HTML page by adding the following HTML code within your <head> tag (using Kent Brewster’s FOAF URL)

<link rel="meta" type="application/rdf+xml" title="FOAF" href="; />

In MyBlogLog’s case, that HTML code is added automatically to a member’s profile page. I should note that in MyBlogLog’s case, the FOAF file is publicly available without any authentication allowing any search engine to crawl and index it, in fact, this information is available through Google Social Graph API but beware that there is a current limitation with Social Graph API in that Googlebot does not crawl a FOAF file linked from an HTML page, hence not making it available for the API to parse. In Brad Fitz own words,

I just verified that the problem is the crawl coverage. Historically Googlebot hasn’t cared about FOAF because it hasn’t used FOAF, so why hit your server fetching it just to throw it away? Now that the SGAPI is using it, though, I need to ask Googlebot to go get that FOAF that I know exists but is uncrawled.

A few parting thoughts…

  • Chris Messina thinks that FOAF baking in relationship information is a fundamental flaw, I have to respectfully disagree because I think it is a key missing feature from XFN/hCard, at least when it comes to my XFN consuming app. Upon further reflection, I think I understand Messina’s concern about FOAF being potentially convoluted. It is due to the powerful recursive nature of RDF that can lead to circular references and if a FOAF parser doesn’t account for this, it can lead to infinite loops.
  • Since FOAF only has a “knows” property, it is less descriptive, hence less useful, than XFN rel values (friend, acquaintance, co-worker, neighbor, sibling, parent, child, crush, date, etc)
  • Apparently FOAF does not have properties to specify an address, e.g.
    state/province, country, city, street address, quite odd indeed. However, it can be remedied by adding VCard namespace to RDF.

  • The general vibe in the web development community is that FOAF is more complicated than XFN so it is more likely to see XFN in the wild than FOAF
  • Firefox Operator plugin does not consume FOAF information
  • FOAF information is meant for app-to-app consumption unlike XFN / hCard which are embedded in HTML. Check out this post WordPress, FOAF, OpenID – updated for a WordPress plugin retrieving FOAF profiles when users authenticate a wordpress blog with OpenID.
  • There is a recent effort, hFOAF, to combine FOAF, hCard, and XFN

My data and having it my way

Quoting Burger King slogan “having it my way”, last week was a flurry of announcements, arguments, and personality clashes among tech pundits discussing, or rather arguing, the implications of user privacy following announcements from 3 big companies, MySpace, Google, Facebook, each announcing remarkably similar data portability features. I won’t belabor the details of each announcement because they have been covered in great details.

A controversial thing that came out of the announcements is Facebook blocking access to its users data from Google Friend Connect. The official reason cited by Facebook is that Google Friend Connect violated their TOS with regards to respecting their users privacy. IMO the real reason, as pointed out by several tech pundits already, is that Facebook wanted to continue to wall in their users data while conveniently citing the TOS privacy concern as the reason to block access.

What transpired afterward is even more controversial as several tech pundits, Steve Gillmor, Sam Whitmore, Marc Canter, Dana Gardner, Mike Arrington, Mike Vizard, Robert Scoble, self-invited guest Chris Saad (Gillmor’s words, not mine), weighed in about user privacy in general, and really ripped into each other at a Gillmore Gang conference call. You can read related posts on the subject at

Arrington and Scoble duked it out here Data Portability: It’s The New Walled Garden and later on in the Gillmor Gang conference call. I have also seen similar mulitiple discussions raised at without any conclusion.

Details notwithstanding, I had a epiphany about user privacy while trying to sort through the numerous and different opinions about what constitutes right and wrong user privacy controls. It dawned on me that user privacy is a personal and individual thing and is also dependent on the context of usage. IMO, this means no one can or should tell me what I consider private or not. Hence it is not meaningful to define a universal bill of rights for user privacy that works for everyone.

Let’s take the hotly debated example between Scoble and Arrington. Arrington’s position is that his data is his data and he should have the ultimate control over how that data is used which includes the ability to stop someone like Scoble with whom he has shared his email with to not use it on 3rd party services like Plaxo without Arrington’s explicit permission. Scoble’s counter argument is that once Arrington shares his email that he has given implicit permission for Scoble to use it elsewhere. He cited the examples of adding Arrington’s email to his Gmail and Yahoo mail accounts so he can email Arrington from either email account and Arrington has no issue with that. However, Arrington has an issue if Scoble wanted to expose Arrington’s email to a 3rd party service like Plaxo which according to Arrington has a tendency to spam people. If Scoble doesn’t care that Arrington use his email on Plaxo, then that’s Scoble’s right to not care, but if Arrington has an issue with Scoble using his email on Plaxo, then that’s Arrington right to care. Note that Arrington’s reaction is context based because he has no problem with Scoble adding his email to Gmail and Yahoo accounts, which brings me back to my point about user privacy being a personal and individual thing and is also dependent on the context of usage.

So how does this translate to implementing the right user privacy controls. IMO, a service should implement privacy controls ranging from air tight to I honestly don’t care who sees and uses my data along with a set of sensible defaults, e.g.,

  1. I am a private person and I want to explicitly approve every use of my data, WARNING: this might result in excessive permission requests but it’s what you asked for, think Microsoft Vista User Account Control feature.
  2. I am ok with sharing some but not all of my data with my friends and the world. Here’s where the sensible defaults come in, the challenge is to define a set of sensible defaults that makes sense for a particular service but needs to be contextual aware or requires contextual approval.
  3. I love attention and frankly don’t care who sees and uses my data. WARNING: you might regret this later on when you run for the post of US President or mayor when there are bikini pictures of you on the web but that’s a risk you accept.

I suspect most users will pick option 2, and that’s where the real fun begins, defining sensible defaults for each service while allowing for contextual awareness or approval. It’s interesting to note that in his post on How SHOULD dynamic privacy work?, Marc Canter also mentioned the need for privacy controls to be contextual aware although his example is different than mine. I like my example better =)

The above perspective is offered purely, and selfishly, from a user’s point of view without consideration for why big companies like MySpace or Facebook would want to provide free service and making their users data fully portable, hence loosing a competitive advantage. Does a service have a right to users data for providing free service in return, I think so. However, if the industry mindshare is moving towards making data portable, big companies are forced to go along so they don’t get left behind and that is exactly what Google, MySpace, Microsoft, and Facebook did though with varying degrees of data portability but it’s a good start.

One last thought, I believe it is Gillmor that posed this argument, when you sign up for a free service and agrees to their TOS, you have agreed to the terms that they laid out regarding usage of your data, so it’s a done deal and you have to abide by the terms you agreed to. First off, to be realistic, very few people read TOS in its entirety, if you do, you are in the minority. As they say, the devil is in the details which you unwittingly agreed to without reading in full because TOS are designed to be purposely mind numbingly boring and unnecessarily long to discourage a user from reading it in full and providing CYA coverage. And even if you read it in full, it’s not easy to decipher the legal jargon thrown in for further confusion. IMO, while this is technically a correct argument, it is not an effective argument.

In the wild snapshot#1: Lessons from my XFN coding experiment

In an offline conversation with Chris Messina, we discussed the idea of creating blog-length interviews with various in the wild apps describing their processes and the technologies that they use with regards to data portability. The goal is to profile real use cases, solutions, and lessons learned when it comes to the current state of affairs for data portability technology. I am using the term “data portability technology” loosely here and is in no way affiliated with the ongoings of

So I am giving it a go and see what comes of it because we both think this kind of information can be useful to others looking to understand the lay of the data portability land. As such, I will title all such future posts starting with “In the wild snapshot…” as well as assign the category (WordPress terminology) of “in the wild snapshot”. If any of you are interested in doing such an interview, leave a comment on here and I will get in touch with you. Note that these posts are generally meant for web developers but everyone is welcomed to read it of course.

First up, I interviewed myself on my recent XFN coding experiment, neat how that works.

Application Overview
Given the abundance of XFN producers available, I wanted to create a XFN consuming application instead. If you need an introduction to rel-me and XFN, check out my earlier post here. The basic idea is to extract XFN information from a URL and present it in a human readable form, in my case, grouping rel-me entries into “My Online Identities” and rel-contact entries into “My contacts”, that’s it, pretty simple thing to do.

Technology considered: XFN, FOAF, Javascript, JSON, DOM, server side platform (like Ruby on Rails, etc), Google Social Graph API, Google Social Graph Test Parser, lab.backnetwork ufXtract microformats parser

Technology used: XFN, Javascript, JSON, DOM, CSS, lab.backnetwork ufXtract microformats parser

To begin with, I considered client side (Javascript, JSON, DOM, CSS) vs. server side (Ruby on Rails) platforms and went with client side technologies primarily because I had a good example client side app to start with, courtesy of Kevin Marks (OpenSocial advocate and microformats founder). You will notice the very similar layout and fonts, I like to reuse code.

The next question is selecting an appropriate XFN parser. I can either try to find some Javascript library or write my own or use a 3rd party service. To make things easier, I decided to go with a 3rd party service. I have 2 choices to pick from 3rd parties, lab.backnetwork microformats parser and Google Social Graph API. I decided to use lab.backnetwork parser primarily because it parse pages in real-time whereas Google Social Graph API only parse pages crawled by Googlebot which can result in data staleness. With lab.backnetwork parser, I used the JSON callback to process the JSON data structure passed back by the parser. Once I have the JSON data, I then sliced and diced it to dynamically generate additional HTML using Javascript, DOM, and CSS.

If you want more details on how to use Javascript to call the lab.backnetwork parser, check out this excellent post Javascript badges powered by JSONP and microformats. Extracted from the post, here’s the script tag code calling lab.backnetwork parser

var script = document.createElement('script');
script.type = "text/javascript";
Badge.obj = badge;
script.src = "" + escape(link.href) + "&format=xfn&output=json&";

Lessons learned
As a newcomer to XFN, this is a good way, at least for me, to learn about XFN. lab.backnetwork parser works pretty well for extracting XFN information especially since it provides real-time parsing. However, unlike Google Social Graph API, it doesn’t currently parse FOAF. FOAF is a competing standard to XFN but can be used in conjunction with XFN. Here’s a post about XFN and FOAF. From the few profile pages I have seen, it is possible for people to use both XFN and FOAF. For example, on such a profile page, XFN is used to markup the multiple rel-me identities and FOAF (in a separate file) is used to list all his friends. However in other profile pages, FOAF is skipped altogether. It doesn’t appear that there is a best practice published on how to mix and match the various technology.

Another issue I ran into is parsing and displaying human readable names for XFN URLs. As it stands, XFN allows one to define relationship between oneself and friends all centered around the URLs. However, URLs are not designed for optimal human readability, some URLs are long and unruly and others employ the use of proprietary internal naming scheme, e.g. (actual site names changed to protect the innocent),

The reason why I think it is important to couple human readable names with URLs is that a consuming app usually wants to do something meaningful with the XFN information and URLs alone does not provide complete information resulting in the end user having to do more work filling in the human readable information after the initial extraction.

In my discussion with Kevin Marks, he indicated that hCard can and should be used along with XFN to provide complete information. For example, it is possible to have the following XFN and hCard markup

<li class=”vcard”><a class=”fn url” href=”; rel=”met colleague friend” >Joe Blow</a></li>
<li class=”vcard”><a class=”fn url” href=”; rel=”met colleague friend”>Jane Doe</a></li>

I think this is a best practice that is not obvious. Developers are generally familiar with each type of microformats standard but I haven’t seen much documentation in way of how to mix and match the various standards for optimal use. Each standard tends to be describe in silo without consideration for other standards, so hopefully revelations like this can help developers better understand how to use the standards.

Even though the XFN/hCard combination is more complete than just XFN, I still see some issues with it. For example, a parser has to understand the implied relationship between the hCard information and the XFN information and returns that information as a related entity meaning that hCard provides the human readable names for the XFN URL, a relationship that is currently not part of the hCard or XFN spec, so it has to be inferred by the developer. Also, I would like this type of cross standards best practices to also extend to XFN/FOAF, etc. Note that at this time, Google Social Graph APIs do not parse hCard information so even if someone put that information on their profile page, it won’t be useful if the consuming app uses Google Social Graph API. Kevin indicates that he might rectify this in the future and extends the API to also parse hCard.

One last thought, even though I started my application using Javascript, if I want to do more useful stuff, I would switch over to server side code. In particular, if I need to store persistent user information, I need a database and that’s best facilitated by server side platform.

Feedback and suggestions are welcomed.

Chris pointed me to a blog post he did on XFN, Portable contact lists and the case against XFN, it’s worth a read IMO.

A real life use case of Microformat hCard in action

Just yesterday, I was writing about rel=me, XFN, and microformats, check out the post A simple data portability project or is it if you haven’t read it already or just want some background on rel=me, XFN, and microformats.

Today I plan to attend the monthly DataPortability meetup at LinkedIn office in Mountain View. For directions, I would normally go through a series of steps to open a new tab, load google maps, find LinkedIn, etc. However, with my new found microformat knowledge, I immediately noticed that the Firefox Operator plugin lit up when the event page is loaded. As it turns out,, the event service provider in this case, supports microformats.

Here’s the Operator showing the contact details for the event
Event hCard Contact
To map it out, I clicked on “Find with Google Maps” and presto, it shows up on Google maps, very cool. Note that the contact information is using the hCard microformat. And hCard is actually based on another standard, vcard. hCard is just vcard expressed in HTML format. Here’s the actual HTML for that information

<div class="venue location vcard">
<span class="fn org">
<a href="/venue/59005/">LinkedIn</a>
<div class="address adr">
<span class="street-address">2029 Stierlin Court</span>
<span class="locality">Mountain View</span>
<span class="region">California</span>
<span class="postal-code">94043</span>
</div> deleted from brevity

The hCard bits are represented in class="street-address", class="locality", class="region", etc., attributes.

Here's the Operator showing the event calendar details
Event hCard Calendar
If you wish to add this event to your favorite calendar like Outlook, click on "Export Event" or perhaps "Add to Yahoo calendar" or "Add to Google calendar".

Here's the Operator showing the various event tagspaces
Event tags
Tagspaces is also another microformat standard but so far it hasn't been useful to me as a user. Tags are widely implemented in popular social networking sites, though in some places they are called keywords, e.g., if you add a video clip from the movie "Rush Hour 3", you can tag it with "Jackie Chan", "Martials arts", "Kungfu", "comedy", etc, you get the idea. The more tags you add, the easier it is for someone else to find it.

However, it hasn't translated well with most of the tags I have seen so far. Take a look at the tags for the event page, it lists "dataportability", "microformats", "relme", "upcomingevent472061". For "dataportability", it then list sub options for "Find products on", etc. Without putting my technical hat on, I would be totally puzzled by "dataportability", "microformats", "relme", "upcomingevent472061", let alone find "dataportability" product on In fact, I tried to find dataportability product on and guess what, it came up zippo as it should because there is no such thing. However to a first time user seeing and trying it, a likely first impression is that it is useless and broken. On other microformat capable pages, I saw duplicate (sometimes 3 or 4 times) tags making it even more confusing, this probably could have been handled by Operator removing the duplicate entries though but there shouldn't be dups in the first place. Anyway, I do think this is a useful feature but it requires more usability thoughts for Joe Blow users.

A simple data portability project or is it

As stated in my last post Storm in a teapot, has started a DIY project of the month on rel=me.

First off, a bit of background about rel=me (rel is short for relationship), XFN, and microformats. rel=me is merely one piece of XFN (XHTML Friends Network) microformat standard. XFN is a format to depict social relationships, i.e., friends, family, lovers, co-workers, etc. For a quick introduction to XFN, check out this page – assumes basic HTML knowledge.

What are microformats you ask. According to about page, microformats are designed for humans first and machines second. Well not really, especially for humans that are non-techies. It should have said that microformats are designed for humans with at least a basic knowledge of HTML otherwise it is just gibberish. HTML knowledge is primarily a domain expertise of web developers and designers which are a subset of developers. For example, I met with a friend of mine yesterday who is a software professional for over 20 years with extensive experience in Java / J2EE, security appliances, etc and he has never heard of any of the data portability technologies or even FriendFeed or Twitter for that matter. He is just as clueless as the non-techie users in terms of knowing what XFN is though he has the ability to learn about it far more quickly than a non-techie user.

XFN is only one microformat standard, other microformat standards are

  • hAtom – for marking up Atom feeds from within standard HTML
  • hCalendar – for events
  • hCard – for contact information; includes adr – for postal addresses, geo – for geographical coordinates (latitude, longitude)
  • hReview – for reviews
  • hResume – for resumes or CVs
  • rel-directory – for distributed directory creation and inclusion
  • rel-nofollow, an attempt to discourage 3rd party content spam (e.g. spam in blogs).
  • rel-tag – for decentralized tagging (Folksonomy)
  • xFolk – for tagged links
  • XOXO – for lists and outlines

Getting back to DIY rel=me project. For those of you that understand HTML, rel=me is an HTML attribute you can add to href link tags to describe your various online identities. For a full list of other rel values, check out this page. For example, here are some of my online identities in XFN rel=me format

<a href="" rel="me">Bob Ngu's Twitter profile</a>
<a href="" rel="me">Bob Ngu's LinkedIn profile</a>
<a href="" rel="me">Bob Ngu's FriendFeed profile</a>
<a href="" rel="me">Bob Ngu's Data Portability Blog</a>

Note that I did some HTML tricks to not display the above information as regular links, otherwise it would look like this normally

As you can see, the actual HTML output has no visual difference as far as a user is concerned, they are simply regular links. But to a XFN capable reader or browser, it can understand the rel=me attribute as semantically meaning “you”. Note that there are many different forms of online identity, not just profiles at popular social sites but also any blogs you own, etc. This is not immediately obvious to a regular user so it’s worth pointing out.

So assuming that you went through the trouble to write up your HTML with rel=me, what next, where is that information actually consumed. I don’t think the 2 most popular browsers (IE 7 and Firefox 2) at this time have native support for XFN, I hear Firefox 3 is suppose to have native microformat support but I haven’t looked for it and if it is there, it isn’t immediately obvious to me. The closest thing I can find is a Firefox plugin called Operator. Operator is a microformat capable reader and for the most part seems to be able to consume most of the above microformat standards except rel=me, kind of odd but kind of understandable.

Here’s an example of a microformat capable page, and this is the microformat information that the Operator (installed on Firefox 2) plugin extracted from the page. For example, there are 3 contacts information: deBurca Ltd, James Burke, Joscelyn Upendran. For all 3 contacts, you can export the contact information in vcard format, just select “Export Contact”.

If you want to test out microformats, you can also use tools like ufXtract – Microformats Parser (Beta 0.2.2) to read a microformat capable page. I don’t recommend nor expect a non-techie to use that tool though. If you are technically inclined, go ahead and plug in this post URL in the ufXtract tool and select “me” for format, click submit, and you will see the rel=me information extracted.


text: Bob Ngu’s Twitter profile

text: Bob Ngu’s LinkedIn profile

text: Bob Ngu’s FriendFeed profile

text: Bob Ngu’s Data Portability Blog

Another service capable of consuming XFN, including rel=me, is Google Social Graph APIs but again this is only for techies, specifically web developers. Non-web developers and even web designers might not be well suited to understand the APIs. I heard that Google Social Graph APIs came about after this excellent article Thoughts on the Social Graph by Brad Fitzpatrick (since hired by Google and is responsible for delivering Google Social Graph APIs) and
David Recordon (Six Apart).

Note that Googe Social Graph APIs only work on data after Googlebot has crawled it, so for real-time testing, Google created a test parser URL at
You can see the Google test parser documentation here. Anyone can send a HTTP POST request to the test parser URL and see the Google Social Graph API results. One of contributor, Julian Bond, implemented a simple wrapper page around the test parser URL. If you go to the wrapper page and enter this post URL, you will get the following results

SG Test Parser http response: 200
List of outgoing "me" edges
...the rest of the output deleted for brevity

Basically the list of outgoing “me” edges is the Google Social Graph output for the rel=me links I added in this post.

Final Thoughts
When I started looking at rel=me, my initial thought was, quoting Sherlock Holmes, “It’s elementary, my dear Watson” but it’s far from elementary as you can see. XFN and microformats are talked about way more in blogs than actually being practiced in the wild. I first started to check for XFN capable sites off this page and a lot of the XFN capable site links are broken, either the site no longer exists or the information is incomplete. It is definitely not a page for non-techies. I did find the one (as mentioned above) site that provided readable microformat information. I also know that Mahalo (a new search engine) also now supports microformat in their results.

At this time, I can honestly say that XFN rel=me proliferation is limited and experimental at best. It would take a while for mass adoption to happen and requires a lot of user education, adoption by popular social sites like Facebook, MySpace, etc, and native browser support.