Monday, March 03, 2008

First steps in RDFa: Creating a FOAF profile

Please note that this article has been updated to Getting started with RDFa: Creating a basic FOAF profile.




Now that the RDFa syntax document is in last call, and people like Yahoo! are starting to index the data, it's worth putting more of your own data into your web-pages, using RDFa. A simple place to start is to modify your home-page or blog profile so that it includes FOAF information.

FOAF

If you're not familiar with FOAF, or Friend-of-a-friend, it's a set of terms that can be used to describe people, organisations, and their relationships to each other. For example, we can mark up our names, point to our home-pages, indicate the companies and projects we work on (and point to their home-pages), and so on.

Since this vocabulary is gaining in popularity, and since RDFa allows us to use any vocabulary we like without having to re-write it (or ask anyone), we'll use FOAF via RDFa to mark up our pages. We won't use every part the vocabulary, so if you want to find further properties, or more detail on the properties used below, look at the full FOAF specification.

Creating a person

The first thing we need to do is to create a person object that will hold our information. This is done using the RDFa typeof attribute, which is much like @class in HTML. The type of the object we want to add is a Person and since 'person' comes from the FOAF vocabulary, we write it like this:
<html xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head>
<title>Mark Birbeck's profile</title>
</head>
<body>
<div typeof="foaf:Person">
...
</div>
</body>
</html>
Now we're ready to add our personal information to this block.

Adding personal information

The FOAF vocabulary is packed with useful properties that we can set, so let's start with some basics such as our name and the URL for our blog.

We can add our name using the foaf:name property, which is set via the new RDFa property attribute:
    <div typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
</div>
Our blog is indicated using the foaf:weblog property. However, unlike foaf:name which is simply a string of text, the item we're going to refer to is a URL, so we must use the HTML rel attribute instead of @property:
    <div typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>
</div>

Creating a profile

We now have a person with some properties about them, but in FOAF terms that's slightly different to having a profile about the person. If that seems a little subtle, it is, but what it amounts to is that the document that contains information about me, is not actually me. In many situations it won't appear to make any difference, but unfortunately it can cause a lot of problems. For example, if the document is used to represent both my profile and me at the same time, what would be the result of adding some information about when the document was created? How do we know whether the information is indicating when I was born, or when the document was?

FOAF allows us to prise these two things apart with the foaf:primaryTopic property, so we're going to use this to say that the main subject-matter of our profile (a web document) is me (a person):
<html xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head>
<title>Mark Birbeck's profile</title>
<link rel="foaf:primaryTopic" href="#me" />
</head>
<body>
<div about="#me" typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>
</div>
</body>
</html>
Whilst we're here, it might be useful to use the foaf:maker property to indicate who created the profile; in this case it's the same as the subject of the profile (i.e., the person who the profile is about), so it's easily set as follows:
<html xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head>
<title>Mark Birbeck's profile</title>
<link rel="foaf:primaryTopic foaf:maker" href="#me" />
</head>
<body>
<div about="#me" typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>
</div>
</body>
</html>
Now we can read this whole thing as follows:
  • we have a person that is identified as #me;
  • this person has a name of "Mark Birbeck";
  • this person has a blog at <http://internet-apps.blogspot.com/>;
  • this person is the creator of the current document;
  • this person is the main subject of the current document.

Adding friends and colleagues

Now that we have our basic framework in place, it's pretty easy to drop more and more FOAF properties in. Perhaps the most commonly used is foaf:knows which is used to indicate the people that you know. Since the target of this property is once again a URL, we'll need to use the HTML rel attribute again:
    <div about="#me" typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>
<a rel="foaf:knows" href="http://www.w3.org/People/Ivan/#me">Ivan Herman</a>
</div>

Adding a picture

The FOAF vocabulary also allows us to indicate pictures that we appear in, and pictures that we might want others to use to represent us. To set a picture of yourself that other software might use to represent you, use the foaf:img property:
    <div about="#me" typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>
<a rel="foaf:knows" href="http://www.w3.org/People/Ivan/#me">Ivan Herman</a>
<span rel="foaf:img">
<img src="http://www.formsplayer.com/files/pictures/picture-11.jpg" alt="Picture of Mark Birbeck" />
</span>
</div>

Linking to a Twitter account

The final illustration we'll show is how to use the FOAF vocabulary to point to your Twitter account, which will make it easy to build tools that will allow people to follow you with one click. The first thing to do is create a relationship called foaf:holdsAccount, which will connect our 'person object' with an online account object. To connect two objects we use the HTML rel attribute again:
    <div about="#me" typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>
<a rel="foaf:knows" href="http://www.w3.org/People/Ivan/#me">Ivan Herman</a>
<span rel="foaf:img">
<img src="http://www.formsplayer.com/files/pictures/picture-11.jpg" alt="Picture of Mark Birbeck" />
</span>
<span rel="foaf:holdsAccount">
...
</span>
</div>
Next we create an object of type foaf:OnlineAccount, in exactly the same way that we did when creating a person earlier:
      <span rel="foaf:holdsAccount">
<span typeof="foaf:OnlineAccount">
...
</span>
</span>
Finally, we indicate that the particular type of account we're dealing with is a Twitter account (using foaf:accountServiceHomepage), and also provide our account name (using foaf:accountName):
      <span rel="foaf:holdsAccount">
<span typeof="foaf:OnlineAccount">
<a rel="foaf:accountServiceHomepage" href="http://twitter.com/">Twitter</a>
<span property="foaf:accountName">markbirbeck</span>
</span>
</span>

Human and machine-readable

Everything we've marked up so far is human and machine readable, but the layout is not great for a human. Although the links to the blog will work, and the text will show names and accounts correctly, there is no context information. However, additional mark-up can be placed in the document, and as long as it is outside of the scope of the RDFa attributes it won't be classed as metadata. For example:
<html xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head>
<title>Mark Birbeck's profile</title>
<link rel="foaf:primaryTopic foaf:maker" href="#me" />
</head>
<body>
<div about="#me" typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span> writes a blog called
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>.
He knows
<a rel="foaf:knows" href="http://www.w3.org/People/Ivan/#me">Ivan Herman</a>.
<span rel="foaf:img">
<img src="http://www.formsplayer.com/files/pictures/picture-11.jpg" alt="Picture of Mark Birbeck" />
</span>

His inane comments are available on his
<span rel="foaf:holdsAccount">
<span typeof="foaf:OnlineAccount">
<a rel="foaf:accountServiceHomepage" href="http://twitter.com/">Twitter</a>
account. His ID is '
<span property="foaf:accountName">markbirbeck</span>'.
</span>
</span>

</div>
</body>
</html>

The whole shebang

If you want to use the mark-up as a template, then here is everything that we've seen, above. Just replace the values in red with your own details, add any human-readable text you want around it, and you are off and running:
<html xmlns:foaf="http://xmlns.com/foaf/0.1/">
<head>
<title>Mark Birbeck's profile</title>
<link rel="foaf:primaryTopic foaf:maker" href="#me" />
</head>
<body>
<div about="#me" typeof="foaf:Person">
<span property="foaf:name">Mark Birbeck</span>
<a rel="foaf:weblog" href="http://internet-apps.blogspot.com/">XForms and Internet Applications</a>
<a rel="foaf:knows" href="http://www.w3.org/People/Ivan/#me">Ivan Herman</a>
<span rel="foaf:img">
<img src="http://www.formsplayer.com/files/pictures/picture-11.jpg" alt="Picture of Mark Birbeck" />
</span>

<span rel="foaf:holdsAccount">
<span typeof="foaf:OnlineAccount">
<a rel="foaf:accountServiceHomepage" href="http://twitter.com/">Twitter</a>
<span property="foaf:accountName">markbirbeck</span>
</span>
</span>

</div>
</body>
</html>

Publishing your FOAF page

Since our FOAF page is embedded into an HTML page, then you can publish your FOAF profile pretty much anywhere that you are able to publish HTML or XHTML. Unfortunately, I was not able to update my Blogger profile to include RDFa, so instead I've created a new blog page, which contains my profile. You'll see a few minor changes to the structure described above, to take into account that we're not creating the entire page, but essentially it's the same.

Labels: , , , , , , , , , , , , , , ,

7 Comments:

Blogger Pierre Lindenbaum said...

Nice Tutorial, thank you

March 03, 2008 3:14 PM  
Blogger Martin McEvoy said...

Thanks Mark Very nice Introduction I have made an example here http://weborganics.co.uk/ and extended it a little thanks again keep up the good work

March 21, 2008 12:47 PM  
Blogger petesop1 said...

Thanks for this Mark, nice simple introduction to FOAF, it's funny how complicated some descriptions make this stuff sound. Had a go at creating my own profile (obviously very basic just yet)

May 07, 2008 8:43 PM  
Blogger petesop1 said...

Thanks for this Mark, nice simple introduction to FOAF, it's funny how complicated some descriptions make this stuff sound. Had a go at creating my own profile (obviously very basic just yet)

May 07, 2008 8:44 PM  
Blogger ffreak said...

Looking at how tricky it is to describe on-line accounts or that we have to use another vocabularies to describe most basic properties like birth date there is a long way to go before major adoption will happen (and it's a goog thing, because I believe that FOAF isn't ready to be adopted - it has too many flaws).
And don't get me wrong - I think that RDFa is pretty much simple, but present vocabularies aren't well suited to be embedded into XHTML (and vocabularies like FOAF definitely should be).

Anyway I've just annotated my own website and I feel great with it ;-)

October 03, 2008 5:06 PM  
Blogger mischat said...

It's really easy to list online account in foaf.

All you need are the following triples:

<foaf:Person rdf:ID="me"> <foaf:holdsAccount>
<foaf:OnlineAccount> <foaf:name>flickr</foaf:name>
<foaf:accountServiceHomepage rdf:resource="http://www.flickr.com/"/>
<foaf:accountName>mischatuffield</foaf:accountName>
</foaf:OnlineAccount>
</foaf:holdsAccount>
</foaf:Person>

March 30, 2009 9:10 PM  
Blogger ffreak said...

@mischat: Yes, it is easy with FOAF as XML, but not so with FOAF in RDFa notion.

April 14, 2009 1:14 PM  

Post a Comment

Links to this post:

Create a Link

<< Home