WordPress Plugin: FOAF Output

A while ago I hacked WordPres into emitting FOAF, but even though it worked fine, the amount of WordPress-tweaking wasn’t for the faint of heart.

Since then, I have looked a little deeper into WordPress, and now it’s finally ready: The FOAF Output Plugin (view source).

Note: If you want to try running this with WordPress > 1.2, please fix the .htaccess rewrite rule for the author pages like this, otherwise the FOAF file will result in a 404:

RewriteRule ^author/([^/].+)/?$ /<SITEHOME>/index.php?author_name=$1 [QSA,L]

The current version is 1.17 (released 2005-08-31).

Changes since 1.16:
  • Fixed errant line breaks in links.
  • Added generator comment to RSS output.
Changes since 1.15:
  • Added oneline bio on profile page, not HTML-escaped.
  • Added link to RSS channel from author list.
  • Tweaked prefix usage for namespaces.
Changes since 1.14:
  • Added check for array being returned from get_the_category().
  • Added check for get_Lat and get_Long for > 1.2 compatibility.
Changes since 1.13:
  • Fixed category/interest when no categories were found.
  • Changed skos:externalID to dc:identifier.
  • Updated SKOS generation with SKOS extensions vocabulary.
  • Fixed generation of author list URI.
Changes since 1.12:
  • Changed a wrong foaf:made to foaf:page, caught by Ian Davis.
  • Fixed erroneous output of homepage URI on profile page.
  • Fixed a problem with statements being added to Atom feeds, thanks Danny/Sam.
Changes since 1.11:
  • Added blog-wide FOAF output (blogroll) with seeAlso’s to authors’ individual files (example).
Changes since 1.10:
  • Added SKOS output (example) and enhanced RSS output.
  • Added document level RDF/XML API hook, foaf_output_profile_rdf_document, to allow for additional properties by add-ons, e.g. generator information.
  • Fixed possible missing namespace declarations for dcterms in RSS/Atom.
  • Tweaked initialisation code to increase reusability.
Changes since 1.9:
  • Fixed limited interest generation for HTML profile page.
  • Multiple URIs per interest is now handled correctly (if separated by whitespace).
  • Only categories with posts by author are deemed “interesting”.
  • Added bio:olb per B.K. DeLong’s suggestion.
  • Added trust ratings for friends.
Changes since 1.8:
  • Renamed foaf_output_the_date to get_foaf_output_profile_page to better reflect the functionality.
Changes since 1.7:
  • Improved identification of “active” author / user.
  • Now really only shows profile on first archive page, even in paged mode.

Features:
  • A FOAF profile document (example).
  • Extended author profile page (example).
  • Enhanced RSS feed with author, topic, spatial and link information (example).
  • List of friends based on supplied XFN information, optionally with trust ratings for the Trust and Reputation project.
  • List of interests based on post category descriptions.
  • Automatic auto-discovery on pages with posts by a single author — try it with the bookmarklet from the FOAF Explorer.
  • Extensible via new API hooks, see e.g. WordPress Plugin: Semantic Visits.
Requirements:
  • WordPress 1.2 (later versions not tested but might work).
  • PHP 4.3, for the sha1 function — if you have an earlier version, grab this SHA1 PHP implementation, drop it in the plugins directory and activate it. Note that the plugin will still work without a sha1 function, but email addresses will be disclosed.
Installation:
  1. Download the FOAF Output Plugin, rename to foaf-output.php and place it in the plugins directory.
  2. Activate it in the administration interface under Plugins.
  3. Optional: Make your name or nick link to the profile page by editing index.php, changing
    <?php the_author(); ?>

    into

    <?php the_author_posts_link(); ?>
  4. Optional: Add a link to your FOAF file in the section with syndication links by adding
    <?php if(function_exists('get_foaf_output_profile_link')) print get_foaf_output_profile_link(); ?>

    to index.php. Note that the link will only be displayed on pages with posts by a single author.

  5. Optional: If you have changed index.php to display post headers before the date/time of the post, include the following lines below the line with the call to start_wp():
    <?php if(function_exists('get_foaf_output_profile_page')) { remove_filter('the_date', 'get_foaf_output_profile_page'); print get_foaf_output_profile_page(); }; ?>
  6. If you have previously installed the hack version, make sure you remove it completely, as it’ll otherwise interfere with the operation of the plugin.
Managing friends:
Friends are managed as usual — in the link manager. To keep the FOAF output sane, the following conventions must be followed:
  • The URI field must point to the persons weblog, e.g. “http://dannyayers.com/“.
  • The Link Name field must contain the title of the persons weblog, e.g. “Raw”.
  • The Short description field must contain the name of the person, e.g. “Danny Ayers”.

Only links with attached XFN information will be included in the friends list. If you assign a rating to a link, it will be taken as a statement of trust, per the definitions of the Trust and Reputation project.

Managing interests:
Interests are based on categories, under the assumption that people write about what they are interested in. As with friends, the category field usage must follow special conventions:
  • The Category name field must contain the name of the category, e.g. “FOAF”.
  • The Description field must contain a URI for a page about that category/topic/interest, e.g. for the category named “FOAF” one might put “http://www.foaf-project.org/“.

Only categories with a URI in the Description field are included in the list of interests.

API extensions, filters:
foaf_output_profile_rdf_namespaces:
This filter is applied when the FOAF RDF/XML profile is created, at the time where the namespace declarations are made. To add a prefix mapping for a namespace, simply append a string like “ xmlns:ex="http://example.com/" ” (don’t forget the surrounding spaces).
foaf_output_profile_rdf_person:
This filter is applied while creating the foaf:Person element for the author, to allow for more properties to be added. Simply append a string like “<gender>male</gender>“.
foaf_output_profile_rdf:
A filter that is applied at the outmost level of the FOAF RDF/XML profile, before the closing </rdf:RDF>.
foaf_output_profile_html_person:
This filter is applied inside the <dl> on the HTML profile page, to allow for additional information to be displayed.
foaf_output_profile_html:
A filter that is applied before the closing <div> containing the HTML profile.
API extensions, functions:
get_foaf_output_email_property($email):
Get an RDF/XML-formatted email property, preferably foaf:mbox_sha1sum, but foaf:mbox if no sha1 function is available.
get_foaf_output_profile_link():
Return a link, enclosed in <li></li>, to the FOAF RDF/XML profile of the author on the current page.
get_foaf_output_profile_uri():
Return the URI for the FOAF RDF/XML profile document.
get_foaf_output_profile_page():
Return the HTML profile, but only on the first page of author archive. Useful for situations where the standard function the_date() isn’t called from index.php.

Thanks to Danny Ayers, Matthew Mullenweg, Dan Brickley, Christopher Schmidt, Jim Ley and Randy Brown for helping out.

53 thoughts on “WordPress Plugin: FOAF Output

  1. Morten – I have had the hack version working for some time. Installed the plugin just now, removed the additions to the index.php relative to the hack version. Left the change: the_author_posts_link(). Plugin does not display the Foaf profile like the hack version. Must be an installation problem on my end. Ideas?

  2. Randy,

    This is likely due to the fact that the plugin works by intercepting the the_date function/filter, and it looks like you aren’t using that on your pages.

    You should be able to achieve the intended functionality anyway by doing print foaf_output_the_date(''); somewhere inside the main loop.

  3. The FOAF profile link (in right meta bar) works, but the listing of the profile info by clicking on the authorname does not. I don’t see a reference to the_author_posts_link in the plugin source.

  4. Right, the call to the_author_posts_link call isn’t made from within the plugin, that’s to be placed in index.php, just like you did.

    The FOAF RDF/XML part is working fine, it’s the HTML output that isn’t. Try the suggestion above and let me know how it went.

  5. Yes, I had the the_author_posts_link call in the index, but it wasn’t working. That call is not in the plugin source, right? I replaced some of the original additions to the index, per your “hack” version and at least the authorname is now appearing, but it’s not working 100% yet. Seems like I’m missing something; with a clean index, will the instructions above work?

  6. Yep, a clean index.php should work, but the problem is not with the call to the_author_posts_link, it’s with the missing call to the_date (which calls foaf_output_the_date in the plugin). The problem may be that the old hack is interfering with the plugin, try to remove that and/or see if there’s anything in the error logs.

  7. the_date is being called. I removed all previous “hack” additions, still no luck, although the wp_head filter in the plugin is now placing its goodies in.

  8. Hmm, it seems there’s something wrong with the automatic author-identification. On the fourth page of your “profile” pages, it finally showed up, because the first post on that page is by you – the rest, the small blurbs, is by another user (admin)? This also show up with the links in the head section pointing at the admin user’s FOAF file.

    I’m not sure what to do about that, especially since the plugin expects all posts on an author page to be by that author…

  9. The posts are all by the same author. The snippets just dont’ show the author name. Interesting. I’ll do some additional playing around here and see if I come up with something useful to tell you.

  10. I’ve deactivated the plugins I have installed to see if there was any conflicts; there wasn’t. One additional thing I noticed was that with the foaf plugin installed, when I save an option in the admin, the page does not display properly, only the last couple lines of the admin page displays.

    But, I am pretty sure the problem is on my end, as I installed a fresh index and the plugin worked correctly. Still interesting….

  11. I already have a couple of foaf files lying around, any chance of being able to merge all of them together and have it displayed using this plugin.
    (One is the LJ foaf file, and another that I wrote using a web-tool)

    Thank you!

  12. Carthik,

    I like the idea, but it’s not quite as easy as it sounds — it involves parsing the files and sorting out identity merging and duplicates.

    However, I’ll think about how to do it, so do come back, at some point it might just be there…

  13. Morten – After installing v1.8 and putting the lines you mentioned in my index.php:

    foaf_output_the_date();
    remove_filter('the_date', 'foaf_output_the_date');

    … the FOAF profile worked, but not the HTML listing. I looked at my error log this evening and noticed errors coming from foaf_output_the_date (missing argument 1). So I took those lines out of the index.php and now all works well….

    Thanks!

  14. Randy,

    That is great news.

    Regarding the instructions I sent you, it seems I should have tested them first… In any case, you will now see an extra item in the installation instructions that should be correct for v1.9 — and this time I actually did test it :-) — that should make your profile page prettier, showing the profile before the posts, not within the headers for the first post.

    Thanks for your help!

  15. I get the following error

    Warning: Invalid argument supplied for foreach() in /home/kernel/public_html/wp-includes/functions.php on line 1121

    with the output plugin when I add

    <?php if(function_exists(‘get_foaf_output_profile_page’)) { remove_filter(‘the_date’, ‘get_foaf_output_profile_page’); print get_foaf_output_profile_page(); }; ?>

    Also, my <?php the_author_posts_link(); ?> link only does my name, nick, and part of the homepage part of my foaf.

    Anyone know what might be wrong?

  16. g8rgeek,

    I suspect that the warning message is due to some other plugin that is munging with the internal WP data structures, I have never seen that message before. You might want to try disabling some of your other plugins to see which one is acting up.

    As for your profile page, it can only display information that you have entered, and it seems you haven’t indicated any XFN relations on your links, nor links for any of your categories, per the instructions above.

    Aside from that, it seems there’s a buglet with the “homepage” display on the profile page, as it shouldn’t display the item at all when no homepage link has been entered. I’ll make sure to fix that in the next version.

  17. Morten – Wanted to report a problem with RSS feeds on my weblog since installing the 1.13 update. Basically, they don’t work. Don’t know precisely what’s up, but the plugin is the cause (I uninstalled, and the RSS feeds work fine.) Atom feed works fine with plugin installed.

  18. I should have said that the RSS2.0 feed doesn’t work. I noticed you use RSS1.0 here. The only thing I noticed was that the 2.0 file had a space as the first character of the file. But removing that still didn’t seem to solve the problem when reading the file in the browser.

  19. Randy,

    That sounds really strange.

    I have a test installation here, which is a completely raw WP 1.2 install, and the RSS 2 output is (as it should) not changed in any way by activating the plugin. It really sounds like it’s some other plugin or hack that’s responsible.

  20. Hi there

    Thanks for a great script. I have a little problem with it as I just turned to WP and would like to use your script on my site. I am using the show-hide categories script and with a sideblog I have the start_wp() on 2 places in my index.php. I think this causes the profile page to print out twice on the same page, in the main content and in the sideblog and I would like to know if you can turn off the function for the sideblog.

  21. Hi there, I love this plugin, but I’m getting an error message whenever I post or go to the links tab in my admin panel. The error message is:

    Warning: Cannot modify header information – headers already sent by (output started at /home/.abbottwasher/dsasaki/el-oso.net/blog/wp-content/plugins/foaf-output.php:738) in /home/.abbottwasher/dsasaki/el-oso.net/blog/wp-admin/link-manager.php on line 563

    Warning: Cannot modify header information – headers already sent by (output started at /home/.abbottwasher/dsasaki/el-oso.net/blog/wp-content/plugins/foaf-output.php:738) in /home/.abbottwasher/dsasaki/el-oso.net/blog/wp-admin/link-manager.php on line 564

    I’ve tried disabling all my other plugins, but I still get the error message. Using wp 1.2.1. Thanks!

  22. Hey oso,

    It looks like there’s an extraneous linefeed at the end of the plugin file, it may be my mistake, as my editor doesn’t always tell me – I’ve tried removing it here, you may want to try the same.

  23. Thanks Morten – works like a charm. The only thing is I can’t get the function < ?php get_foaf_output_profile_link(); ?> to generate a link to my foaf file. It doesn’t come up with an error message or anything. Not a big deal though I can write that in html.

    Thanks so much for the plugin.

  24. Oso,

    Happy it worked out for you.

    Please note that the get_foaf_output_profile_link() function only “works”, i.e. outputs anything, on a page with a single author. I see your blog is a multi-author one, so the link will only show up on individual posts. It’s a feature, not a bug. :)

  25. I’ve got the error too:
    Warning: Invalid argument supplied for foreach() in /home/kernel/public_html/wp-includes/functions.php on line 1121
    What can I do to invoild the error?

  26. Sorry Morten,

    The no input file specified message was my own fault. I know have the foaf output plugin up and working. I can see my foaf file, but unfortunately it only picks up on my friends from links. The other information is left out.

    Looking forward to seeing how it shapes with 1.5.

  27. I just installed the FOAF output and semantic visits plugins and they work fine… I have just two questions looking at your profile page. You have a short bio and a homepage link… I can not find a place in WP to input this data.

    And I can not find a way to limit the number of post in my author page. I get all the post written and the page is huge :-( How do you limit them?

    I am using WP 1.2

    Thanks
    Fabio

  28. I just tested 1.16RC a little more, it seems that arround line 577 something goes wrong with the author blogroll (at least in WP1.5). The code produces a redundant line of <link rel="meta" type="application/rdf+xml" title="FOAF" href="http://www/datenbrei/wp-rss.php" /> which is added by the default header.

  29. While I understand the necessity of it, I wish we had a better way to link categories than overloading the description field. I usually use that field for, well, descriptions :)

    Perhaps in a future version of WP, we can have a cat_meta table similar to the current post_meta, and the planned user_meta.

  30. With WP-1.5.1.1 i get
    Fatal error: Call to undefined function: get_userdata() in /var/kunden/webs/web1/wordpress/wp-content/plugins/foaf-plugin.php on line 691

    instead of the foaf.rdf file

  31. I can confirm a fatal error on WP-1.5.1 as reported in comment #47. Could be related to the fact that get_userdata() is in wp-includes/pluggable-functions.php which are loaded after the plugins are.

    P.S. The difference in line number where the error occurs (as reported in comments #47 and #48) is because one author is using a “nice” url rewriting (resulting in get_authorbynicename) and the other is not.

  32. I get this error too, both with a 1.15 earlier today, and a fresh 1.17 just now:

    Fatal error: Call to undefined function: get_userdata() in
    foaf-output.php on line 701

    WordPress version: 1.5.1.3

Comments are closed.