Creating an Atom Feed in Radiant

Updated: I’ve updated the code to use Radiant 0.6’s <r:date for="updated_at"/> to get the last updated dates right for the feed and its articles.

Out of the box, Radiant and its sample blog templates include an RSS feed. Having recently taken an interest in Atom I thought I’d try building an Atom feed. Here’s how I did it.

Atom Requirements

Creating the Atom feed itself is fairly straightforward, but there are a few things to be aware of.

Atom feeds use the application/atom+xml Content-Type so the first step is to create an appropriate Layout. [Note: To edit the layout’s Content-Type click the More link that appears under the Name field.]

Screen capture of creating a new Layout in Radiant and setting the Content-Type field.

The feed and its entries each require an id element. There are many possible schemes for ids but I’ve chosen URLs to keep things simple. Also, the feed has an updated element to indicate when the feed was last updated. Finally, all timestamps in the feed must conform to RFC 3339.

Building the Feed

The beginning of the feed is quite simple. The root is a feed element in the Atom namespace. There’s a title element and separate link elements for links to the feed itself and to the page associated with the feed (in this case, my home page). The generator element indicates that the feed was created using Radiant.

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us">

  <title type="text">Sean Santry</title>

  <link rel="self" href="http://seansantry.com<r:url />" />
  <link rel="alternate" type="text/html" href="http://seansantry.com/" />

  <id>http://seansantry.com/</id>

  <generator uri="http://radiantcms.org/"
    version="0.5.2">Radiant CMS</generator>

Next is the author element with my name and the uri for my site. An email element is optional (for feeding spammers).

  <author>
    <name>Sean Santry</name>
    <uri>http://seansantry.com/</uri>
  </author>

I mentioned that the feed has an updated element with a timestamp that indicates when the feed was last updated. Since this timestamp depends on when an entry was most recently added or modified Radiant’s r:date tag won’t work. That would give the date when the Atom feed itself was last edited, which isn’t correct.

The solution is to find the most recent article using a combination of Radiant tags. The r:find tag gets all the articles in my blog and the r:children:each tag sorts by the published_at date in descending order. Setting the limit attribute to 1 gets back just the most recently updated page. Finally the r:date tag with the RFC 3339 date format (%Y-%m-%dT%H:%M:%SZ) populates the feed’s updated element.

  <updated><r:find url="/articles/">
    <r:children:each limit="1" order="desc">
      <r:date format="%Y-%m-%dT%H:%M:%SZ" for="updated_at" />
    </r:children:each>
  </r:find></updated>

Adding the entries themselves is simple. Once again the r:find and r:children:each tags get the appropriate pages. Within the entry element are the entry’s author, the dates on which the entry was last published and updated and the entry’s title. The entry’s URL serves as the entry’s id and as the entry’s permalink (in the link element).

I like providing the full content for entries in my feeds, so the content element has the full output from the r:content tag. If your entries have summaries stored in a page part, you could use that instead.

  <r:find url="/articles/">
  <r:children:each limit="10" order="desc">
    <entry>
      <author><name><r:author /></name></author>
      <published><r:date format="%Y-%m-%dT%H:%M:%SZ" /></published>
      <updated><r:date format="%Y-%m-%dT%H:%M:%SZ" for="updated_at" /></updated>
      <title><r:title /></title>
      <link rel="alternate" type="text/html"
        href="http://seansantry.com<r:url />" />
      <id>http://seansantry.com<r:url /></id>
      <content type="html"><r:escape_html>
        <r:content /></r:escape_html></content>
    </entry>
  </r:children:each>
  </r:find>

</feed>

You can see the results of this feed at http://seansantry.com/atom/. Download the source to get started. Once you've created your feed you can check it for validity using the feed validator.