Smokes your problems, coughs fresh air.

Tag: Atom

Posting to WordPress via the command-line

In February I was interested in posting to WordPress from the command-line, a possibility that I enjoyed when I wanted to apply some CLI-magic to some of my MediaWiki installations in the past.

I came across a great Perl module (WordPress::CLI) by Leo Charre. It depends on WordPress::XMLRPC

Another approach is to use the appfs FUSE filesystem, which uses WordPress’ support for the Atom Publishing Protocol. There’s another FUSE filesystem, BlogFS. This one depends on WordPress’ XML-RPC instead of its Atom interface.

Complete WordPress Atom feed: an XSLT transformation

Previously, I tried obtaining a full Atom feed without pagination from WordPress. I didn’t succeed, so I ended up writing an XSL transformation which merges all the pages of this Atom feed into one valid Atom XML stream.

The transformation: wordpress-full-atom-feed.xsl

<?xml version="1.0" encoding="UTF-8"?>
 
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:thr="http://purl.org/syndication/thread/1.0"
xmlns="http://www.w3.org/2005/Atom">
 
<xsl:param name="base_url" select="atom:feed/atom:link[@rel='self']/@href" />
 
 
<xsl:template match="/">
  <xsl:apply-templates select="node()" />
</xsl:template>
 
<xsl:template match="*">
  <xsl:element name="{name(.)}">
    <xsl:apply-templates select="node()" />
  </xsl:element>
</xsl:template>
 
<xsl:template match="@*|node()">
  <xsl:copy-of select="." />
</xsl:template>
 
<xsl:template match="atom:feed">
  <feed>
    <xsl:apply-templates select="@*|node()" />
 
    <xsl:call-template name="process_feed_page">
      <xsl:with-param name="page" select="number('2')" />
    </xsl:call-template>
  </feed>
</xsl:template>
 
<xsl:template name="process_feed_page">
  <xsl:param name="page" />
 
  <xsl:variable name="page_doc" select="document(concat($base_url, '?paged=', $page))" />
 
  <xsl:if test="$page_doc/atom:feed/atom:entry">
    <xsl:apply-templates select="$page_doc/atom:feed/atom:entry" />
  
    <xsl:call-template name="process_feed_page">
      <xsl:with-param name="page" select="$page + 1" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>
 
</xsl:transform>

The transformation works by processing the atom:feed element. Before closing that, the process_feed_page template is called. This template tries to open the next page and process all atom:entry elements in there. Then it tries to recurse to the next page.

The next page’s URL can be guessed because this is the normal feed URL with ?paged=[pagenum] appended to it. The feed URL can be found because WordPress adds it to the feed:

<link rel="self" type="application/atom+xml" href="http://blog.bigsmoke.us/author/halfgaar/feed/atom" />

For very old WordPress versions this doesn’t work, because the paged parameter isn’t supported there. Also, older versions might require you to supply the $base_url param to the XSLT processor, because the rel='self' link is incorrectly set to the URL of the default feed within all other feeds (such as the author feed or the tag feed).

Invocation

Invocation is simple. I use libxslt‘s xsltproc:

xsltproc wordpress-full-atom-feed.xsl http://blog.bigsmoke.us/author/halfgaar/feed/atom

That’s it. You end up with a full feed as if there never was any pagination to begin with; it almost looks as if WordPress does support the nopaging option for feeds.

WordPress feed pagination

Wiebe uses his author Atom feed to generate a list of his blog posts here on his own website. WordPress feeds only display the latest 10 entries. He has written 16 so far. What he needs is a feed with all his entries.

First, I tried if pagination works for feeds. Appending “/page/2” (as is used an non-feed lists) to a feed URL gives a 404 so I was kind of stuck there. Four days ago, after Googling for some time, unable to find a solution anywhere, I asked on the forum. Still no answer today so I tried to find out which parameters WordPress accepts in the QUERY_STRING. The WordPress Codex does explain how queries are handled but not which parameters are accepted.

Digging into wp-includes/query.php, with much trial and error, I found out that I can append ?paged=2 to the URL to get the next page. At least I got that sorted then. There are a number of much more promising parameters supported by get_posts(), but these don’t seem to be parsed by parse_query(). Next time, I’d like to find out how how to use two of these: nopaging and posts_per_page.

Wiebe could complete his list by merging together all the pages of the feed, but I’d much prefer to find a relatively painless method to produce a feed with an unlimited number of posts.

Notes

  • http://codex.wordpress.org/Query_Overview
  • http://codex.wordpress.org/Function_Reference/WP_Query
  • http://codex.wordpress.org/Template_Tags/query_posts

© 2024 BigSmoke

Theme by Anders NorenUp ↑