Implementing FOAF in Rails

By tony | 5 Comments

FOAF is an RDF spec for describing people and the relationships between them. I thought FOAF had mostly died and been replaced by hcard/XFN. However, it looks like FOAF is going to make a come back as one of the technologies that people build their OpenSocial APIs on top of. So I decided to add it to CrowdVine. You’d think this would be simple but I couldn’t find anyone who described it clearly.

Define a MimeType in config/initializers/mime_types.rb so that we can use respond_to to implement FOAF as a second view on on existing profile page. This file is new in Rails 2.0, otherwise it would have gone in environment.rb. I’ve seen FOAF returned as either “application/rdf+xml” or “text/xml.” I don’t know the repercussions of choosing one over the other.

Mime::Type.register("application/rdf+xml", :rdf)

If your profile urls are something like /profiles/42 then we want the FOAF url to be /profile/42.rdf. I was already using map.resources :profiles which set up that route for me. However, it didn’t create a named route that would take the format (rdf), so let’s do that:

map.foaf 'profiles/show/:id.:format', :controller => "profiles", :action => "show"

Now let’s go into our controller and use respond_to to tell our action to choose a template based on the requested format.


respond_to do |format|
  format.html
  format.rdf
end

Now you’re ready for a FOAF template. If your profile template is named show.html.erb (or show.rhtml) then you want to create a new template called show.rdf.builder. The file name lets Rails know that it’s the template that should be used for RDF requests and that the template should be parsed with the builder template engine (good for XML templates). Below is the template I used. You’ll need to make modifications based on the meta data you have for your users.


xml.instruct!
xml.rdf(:RDF,
        "xmlns:rdf"  => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
        "xmlns:foaf" => "http://xmlns.com/foaf/0.1/",
        "xmlns:rdfs" =>"http://www.w3.org/2000/01/rdf-schema#") do

  xml.foaf(:Person) do
    xml.foaf(:name, @person.name)
    xml.foaf(:mbox_sha1sum, Digest::SHA1.hexdigest("mailto:" + @person.email))
    xml.foaf(:homepage, "rdf:resource" => profile_url(@person))
    xml.foaf(:depiction, "rdf:resource" => "http://" +
           request.host_with_port + url_for_file_column("person", "image"))   

  @person.friends.each do |friend|
      xml.foaf(:knows) do
        xml.foaf(:Person) do
          xml.foaf(:name, friend.name)
          xml.rdfs(:seeAlso, "rdf:resource" => foaf_url(friend, :rdf))
        end
      end
    end
  end
end

At this point you should be able to go to a URL like /profile/1.rdf and get back a FOAF file. If you don’t get anything back, then that means I explained something wrong. Once you are getting something back you should run the output through a FOAF validator. Unfortunately the validator everyone points to, FOAF Lint, doesn’t seem to be working. Instead, you should try the W3C RDF Validator and FOAF Explorer. FOAF Explorer lets you walk the FOAF graph. It’s really cool and I wasn’t confident I’d gotten the FOAF right until I’d seen it in Explorer.

Now that you have working FOAF, you need to make it auto-discoverable. You want to to get something in the HEAD section of your profile pages that looks like this:

<link rel="meta" type="application/rdf+xml" title="FOAF"
 href="http://example.com/profiles/id.rdf"/>

Since the FOAF file is only going to be auto-discoverable on profile pages you can’t just hard code that into your layout. I used the content_for helper to get around that. You define the auto-discovery link in your profile template with code like this:


<% content_for("header") do %>
<link href="<%=foaf_url(@profile, :rdf) %>" rel="meta"
type="application/rdf+xml" title="FOAF" />
<% end %>

Then you put a line in the HEAD section of your layout to display it.

<%= yield :header %>

Here are some other links that I found helpful.
XML.com article on FOAF
FOAF Spec

Related Posts:

  • No Related Posts

5 Responses to Implementing FOAF in Rails

  1. Pingback: Nodalities » Blog Archive » This Week’s Semantic Web

  2. Justin D-Z says:

    Thanks for this. I had FOAF on a list of things to try and your tutorial was easy to follow. FOAF Explorer seems to think I’m working. I took a slightly different path on the auto-discovery link, but otherwise went right on down the line. Bang up job!

  3. Anthony Eden says:

    Thanks for the clear tutorial…made setting things up a breeze.

  4. Tom Morris says:

    Excellent tutorial. You should serve RDF/XML as “application/rdf+xml”, especially as Rails does content negotiation to make sure that when you request a URL with the “.rdf” left off, it can and will serve up the relevant MIME type if it’s available.

  5. degsy says:

    Thanks for the tips.

    I was trying to do this, then found this which made my life easier!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>