Using the Atom Publishing Protocol in WordPress

After getting more comfortable with WordPress (See The WordPress Post Editor Is Limited, I started looking at mechanisms to make posting/post updates even easier. I first started writing my own importer based on the Atom Publishing Protocol. And then, much to my delight, looked at a little file called wp-app.php which has the comment Atom Publishing Protocol support for WordPress. Wouldn’t it be great if this did what I want?

So I started research it as the already-coded-and-tested-and-pretty-good solution for what I want to do. I almost immediately encountered WordPress should allow input of XHTML/HTML via Atompub and became a little despondent. So, I enabled the Atom Publishing Protocol in the options-writing.php form and tested it out. WordPress was, indeed, stripping out the HTML element tags, even when I used the XML CDATA section. I started digging into the code. First I wrote a couple test programs using the PHP XML Parser library just to see how it works. It did everything I wanted, even CDATA sections.

Okay so the problem is in the WordPress Atom Publishing Protocol (WP-APP) code. So I hacked around in it some and came across atomlib.php, the guts of WP-APP implementation. I stepped through the code and found that the PHP XML Parser retains the format of CDATA blocks but doesn't indicate to the application that the text is CDATA. Thus WordPress has no way of knowing what is CDATA text and what isn't.

But then I found a lot of logic around the type attribute for some elements, which WordPress calls the ATOM_CONTENT_ELEMENTS. If the type is html or xhtml, the XHTML tags are not stripped out. Problem solved! Sort of…

Which is how I'm writing this post right now (for a big test.) And I’m updating it via Atompub also. The “sort of” part is because the embedded XHTML inside the content block has to be clean. Any error and the APP interface rejects it with a HTTP 400 “Bad Request” code. But I use a pretty good HTML editor so that’s not really an issue.

As a sidebar, it took a little digging to figure out how to communicate with WordPress to publish Atom-based posts. I'm not sure why this hasn't been documented using a common tool set.

Here are some pointers using cURL. Most importantly to use the WP-APP, one must have edit rights on the post, even to retrieve it (and, of course, the site admin must enable WP-APP).

  • To retrieve (GET, which is the default) a specific post, all posts or all categories:
    curl -u 'user:pass' https://www.mysite/wp/wp-app.php/post/307
    curl -u 'user:pass' https://www.mysite/wp/wp-app.php/posts
    curl -u 'user:pass' https://www.mysite/wp/wp-app.php/categories
    Note that permalink URIs don’t appear to work here; you need to use the post id.
    Also note it is important to use HTTPS to protect your username and password, which goes across as plain text in an HTTP session.
  • To add an entry do:
    curl -u 'user:pass' -H "Content-Type: application/atom+xml" -X POST -T "atompost.xml" https://mysite/wp/wp-app.php/posts
    WP-APP will accept only a content-type of application/atom+xml and cURL defaults to text/html. Also, it looks like one can only add wordpress posts using APP and not pages. The atompost.xml file contains the post wrapped in an Atom Publishing Protocol document. As stated earlier, any invalid XHMTL will cause the upload to fail with a HTTP 400 Bad Request error code.
  • To update an entry (fully replace with the uploaded elements) do:
    curl -u 'user:pass' -X PUT -H "Content-Type: application/atom+xml" -T "entries.xml" https://mysite/wp/wp-app.php/post/258
    One needs to use the PUT method here and give the post id. You can find the post id by retrieving all posts, searching on the post you want and look right after the content block for <link rel=”edit”. This will contain the URL to use for edits.
  • To delete an entry do:
    curl -u 'user:pass' -X DELETE https://mysite/wp/wp-app.php/posts/258
    Again, you need the post id.
The cURL calls are pretty ugly but a lot of boilerplate so I wrap them in a shell script that takes the operation (Create, Update, Delete, Show, ShowAll, ShowCategories) and possible postid.

Leave a Reply