Posts Tagged 'hCard'

In the wild snapshot#3: DiSo profile plugin

I had an excellent conversation with Stephen Paul Weber, an active DiSo plugin developer, on his experience with the DiSo profile plugin. 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.

DiSo Project Background
Straight from the DiSo Google group About page

Social networks are becoming more open, more interconnected, and more distributed. Many of us in the web creation world are embracing and promoting web standards – both client-side and server-side. Microformats, standard apis, and open-source software are key building blocks of these technologies.

DiSo (dee • zoh) is an umbrella project for a group of open source implementations of these distributed social networking concepts. or as Chris Messina puts it:“to build a social network with its skin inside out”.

You can also listen to an interview by Chris Messina on Chris Messina about DiSo.

At this stage, DiSo plugins only work on self-hosted WordPress blogs which means if you have a blog on, you are out of luck. Also, all DiSo plugins currently are written in PHP, WordPress’s choice of language. Visit the WordPress site to get instructions on how to host your own WordPress blog and install plugins.

Application Overview
The DiSo WordPress profile plugin has the following main features

  • When a user signs up for a WordPress account, the plugin makes it easier to import the user’s profile information via hCard and XFN (if available)
  • Once a user has signed up for a WordPress account, the plugin makes it easier for the user (now blog owner) to publish their own profile with standards like hcard, XFN
  • Supports permission features allowing blog owner to restrict access to his information based on predefined relationship, e.g., I can’t see his phone number but friends of him who login with their OpenID and are present on his authorized list of friends can see his phone number
  • There is a sidebar widget that displays names/avatars of most recently logged in visitors

The key technical pieces are hCard, XFN (rel-me, rel-contact), PHP5, and standard WordPress plugin architecture. The plugin should work on WordPress 2.0 and above, and has been tested on 2.3 through 2.5. Currently the plugin mimics SGAPI functionality without the FOAF bit. Also, FOAF was considered but not implemented, another item for the future perhaps. He plans to add Google Social Graph API (SGAPI) support, but it wasn’t available when the plugin was written, so it is something to consider for the future – Steve Ivy wrote a PHP wrapper for SGAPI.

While the plugin works with OpenID, it does not require OpenID. There is a button to import profile and can fetch profile information if it is not an OpenID URL. OpenID profile extraction for XFN and hCard is automatic upon registeration and login. For OpenID feature to work, it needs the WP-OpenID plugin. No other libraries or plugins are required, in fact the import button works fine if the WP-OpenID is not installed. To display the user’s profile, the user needs to add a WordPress template tag. There is a page token for rendering on a WordPress page and a PHP function for addition directly to the template (documented on the plugin page). So far, most people don’t use it as a sidebar widget and instead display their profile information inline in the blog.

For an example of the plugin in action, check out Stephen’s blog, it powers the top half of his main page and the avatars of recent visitors in his sidebar.

Lessons learned
Some people have hCard on their OpenID pages via OpenID delegation usually or directly on the page. A large number of people have rel-me links going to their main profile somewhere else. In his opinion, the biggest hurdle is still HTML parsing in PHP which is surprsing to me since PHP is such a popular web development language. Event though PHP has excellent XML support but if the HTML is broken or incomplete as it is often the case in the world wild web, there is no library to handle that. An option is to fix it with HTML Tidy but most shared service providers (like DreamHost) do not have HTML Tidy installed. Without HTML Tidy, the plugin has to run the page through W3C remote tidy proxy which can be slow. Another option is to use HTML Purifier which is a re-implementation of HTML Tidy in PHP.

The current plugin user base is primarily DiSo developers and he has not gotten any feedback from non-DiSo developers. He noted that there is a goofy WordPress thing where the permissions model is based on the contacts list but WordPress only supports one blogroll list, so everyone on that list has the same permission. This is not a problem for most blogs but it could be a problem for multi-authors blog. There is no affiliation with WordPress other than it is a WordPress plugin.

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

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.

DaPo Acronym Soup

In my first post, I said that DaPo list of existing open source technology reads like an acronym soup, here’s why (below extracted from DaPo site).

Authentication Standards

  • User authentication – openID
  • API authentication – oAuth

Data Transfer, Interchange, and Exchange Standards

These standards enable data dumps via import and export across data spaces on the Web. They also aid publish and subscribe methods of data exchange. The list includes:

  • Messaging – XMPP
  • Syndication – Atom and RSS
  • Attention – APML
  • Services and Service Discovery – YADIS and XRDS
  • Subscriptions – OPML
  • Personal details – hCard
  • Relationships – XFN
  • Personal Profile Data & Social Networks – FOAF
  • Online Communities – SIOC (discussed at SIOC-DEV)
  • Publishing data – AtomPub

Linked Data or Data Referencing Standards

These standards enable access to data by reference via HTTP based data object identifiers called URIs. The list includes:

  • HTTP based URIs (for Location, Value, and Structure independent Object / Resource Identifiers)
  • Personal Profile Data & Social Networks – FOAF
  • Online Communities – SIOC (discussed at SIOC-DEV)
  • Other Schemas and Vocabularies in the Semantic Web realm

Other standards

Other standards groups and initiatives that may not yet have a place in the Blueprint, but still deserve help and support!

  • Content Identity Validation – MicroID
  • REST

Despite the acronym soup, I found it to be the most useful page on the site because it lists all the open source technology promoted by DaPo. Now I just need to research each acronym to understand the technology, I will write subsequent posts on each technology as I get to it.

Note that there are policies and legal aspects to DaPo also which I am ignoring, at least for now.