the Blogger, Movable Type and MetaWeblog XMLRPC APIs

The first XMLRPC blog API was the Blogger API which was very limited – you could create and edit very simple representations of posts. This was extended by both Movable Type and MetaWeblog, adding more complicated post types (you could set titles, keywords categories, etc) and the ability to get a list of posts available on the server. All of these APIs have their own namespaces, their own variable name prefixes, and varying support from clients. An example

  • metaWeblog.getCategories ( MetaWeblog API )

    metaWeblog.getCategories (blogid, username, password) returns struct

    The struct returned contains one struct for each category,
    containing the following elements: description, htmlUrl and rssUrl.

  • mt.getCategoryList ( Movabletype API )

    Description: Returns a list of all categories defined in the weblog.

    Parameters: String blogid, String username, String password

    Return value: on success, an array of structs containing String
    categoryId and String categoryName; on failure, fault.

Because you don’t know which clients will be making which calls, you need to implement both. Further, the MetaWeblog API doesn’t support post excerpts or extended content, but the MovableType API extends certain MetaWeblog calls with extra parameters to get and set these properties.

Essentially, if you have a blog that supports excerpts, keywords – anything other than posts with a title and content – then you need to implement all of the APIs. Then you find that some clients have arbitrarily decided that the blogid parameter must be an integer, despite the specs explicitly giving it a ‘String’ type.

It all works in the end, though.

This post has been spillover from a post on the Zimki blog about implementing the MetaWeblog API on Zimki. As the Zimki blog has a very simple post structure at the moment (just titles and content right now, although annoyingly we use a markup engine that no GUI client understands) I could get away with a nice basic implementation of just the core MetaWeblog API, and so a rant about the complexity of the APIs didn’t really seem to fit there. Having written it, though, I felt it should go somewhere, and I did run into all these issues writing the MetaWeblog server.

Adding a metaweblog interface to django

I tend to reimplement the CMS that drives more often than I add content to it, but the current Django based incarnation seems to have decent sticking power. A lot of this is Django’s magic admin interface middleware. When I add, say, a tagging engine to the site, I only need to worry about the object model and presenting it on the site itself. All the boring and much harder to write admin pages to add and remove tags just write themselves. But the other reason I’m staying with it is that I’ve now added so many features to it (because it’s easy!) that a re-write in another language would be a huge amount of effort.

This weekend, for instance, I’ve added an implementation of the metaweblog API to the site, using the excellent code on allyourpixel as a base. The main source of pain is the persistent weirdness of implementing the Movable Type extensions to the metaweblog extensions to the Blogger XMLRPC API. How can you call something a metaweblog API and not allow for post excerpts, for instance? So annoying.

editing using ecto

While implementing it, I found the TextPattern API reference to be far more useful than the official spec, mostly because it covers everything up to the Movable Type extensions, which you need if you want to edit page excerpts. The other problem I encountered was that Ecto won’t talk to an endpoint over HTTPS with a self-signed certificate unless the SSL cert is in the local machine X509 database. The way it fails is incredibly unhelpful and annoying, too. The simplest way to fix it (assuming a recent macos) is to visit the endpoint in Safari. It’ll complain about the certificate – click the ‘always trust this site’ box, and it’ll stop.


Ah ha! I have a blogroll. Ph33r me.

In other news, Template::Plugin::XML::Simple is really nifty.

<p class="code">
[% USE blogroll = XML.Simple('/export/home/tomi/web/') %]
&lt;p class=header&gt;blogroll&lt;/p&gt;
[% FOREACH section = blogroll.body.outline %]
  &lt;a href="[% section.htmlUrl %]"&gt;[% section.text %]&lt;/a&gt;
  [% UNLESS loop.last %]&lt;br /&gt;[% END %]
[% END %]