Favatars

Mix "favicon" and "avatar" and what do you get? A simple way to add avatars to your weblog posts.

Richard Rutter mentions the whole forum/comments avatars thing, and pointed us to Gravatar, an interesting project designed to enable any site to display someone's avatar by simply knowing their e-mail address.

I've always liked avatars, they not only enable you to quickly see who made which post without having to find and read their name from the posts metadata, but also give posters an identity. A great idea around since the birth of cyberspace, avatars are cool.

However, I thought there must be an neater way when it comes to comment posting on weblogs using the power of the Web and the fact that most people posting on weblogs have their own weblog.

And so was invented "favatars", named cunningly from a mixture of "favicon" and "avatar".

You can see where I'm going with this can't you?

The idea is this:

  1. User posts a comment on your site, giving their homepage URL.
  2. The server does a HTTP request on the URL and regex's the returned document for a shortcut icon link element.
  3. If found it assigns the icon URL to the post.
  4. If not found it does a HTTP request for "favicon.ico" at the given URL and if found assigns its URL to the post.
  5. If nothing is found then no favatar for our user.
  6. Then when our generates HTML for our comments, it includes an image element referencing the favatar URL.

Pros

Cons

The PHP code

This function returns the URL of the favicon of a given URL. It fetches the document pointed to by $url and looks for a favicon by searching for an icon link element.

In a nutshell, the code does this:

  1. Do a HTTP GET on the URL.
  2. Regex the returned document for a shortcut icon link element.
  3. If a URL is found and begins with a "/" then append it to the root of the URL.
  4. Otherwise if it begins with a "http://" then it's good as is.
  5. Otherwise if it ends with a "/" then append it to the URL as is.
  6. Otherwise append it to the URL with an a "/".
  7. If not found, do a HTTP request for "favicon.ico" at the root of the URL.
  8. Otherwise give up and return false.
function getFavicon($url) { $HTTPRequest = @fopen($url, 'r'); if ($HTTPRequest) { stream_set_timeout($HTTPRequest, 0.1); $html = fread($HTTPRequest, 4096); $HTTPRequestData = stream_get_meta_data($HTTPRequest); fclose($HTTPRequest); if (!$HTTPRequestData['timed_out']) { if (preg_match('/<link[^>]+rel="(?:shortcut )?icon"[^>]+?href="([^"]+?)"/si', $html, $matches)) { $linkUrl = html_entity_decode($matches[1]); if (substr($linkUrl, 0, 1) == '/') { $urlParts = parse_url($url); $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].$linkUrl; } elseif (substr($linkUrl, 0, 7) == 'http://') { $faviconURL = $linkUrl; } elseif (substr($url, -1, 1) == '/') { $faviconURL = $url.$linkUrl; } else { $faviconURL = $url.'/'.$linkUrl; } } else { $urlParts = parse_url($url); $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].'/favicon.ico'; } $HTTPRequest = @fopen($faviconURL, 'r'); if ($HTTPRequest) { stream_set_timeout($HTTPRequest, 0.1); $favicon = fread($HTTPRequest, 8192); $HTTPRequestData = stream_get_meta_data($HTTPRequest); fclose($HTTPRequest); if (!$HTTPRequestData['timed_out'] && strlen($favicon) < 8192) { return $faviconURL; } } } } return false; }

Thanks to Matt Round for bug fixes and suggestions.