Syndication feeds from templates

Comments
Bookmark and Share

One of the must-have necessities for any blogging or other web publishing software is the RSS (Really Simple Syndication) feed. RSS, or its younger and sexier sibling Atom, is the file format used by news aggregators, which give you a frequent listing of posts and stories published by your favorite blogs, newspapers, journals, whatever you want, without you having to actually go to their website. Usually the RSS feed is generated by some library of code where you construct your feed as an array of objects or data structures. Here's how you put together an RSS feed with PyRSS2Gen, for instance:

rss = PyRSS2Gen.RSS2(
    title = "Andrew's PyRSS2Gen feed",
    link = "http://www.dalkescientific.com/Python/PyRSS2Gen.html",
    description = "The latest news about PyRSS2Gen, a Python library for generating RSS2 feeds",

    lastBuildDate = datetime.datetime.now(),

    items = [
       PyRSS2Gen.RSSItem(
         title = "PyRSS2Gen-0.0 released",
         link = "http://www.dalkescientific.com/news/030906-PyRSS2Gen.html",
         description = "Dalke Scientific today announced PyRSS2Gen-0.0, a library for generating RSS feeds for Python.  ",
         guid = PyRSS2Gen.Guid("http://www.dalkescientific.com/news/030906-PyRSS2Gen.html"),
         pubDate = datetime.datetime(2003, 9, 6, 21, 31)),
       PyRSS2Gen.RSSItem(
         title = "Thoughts on RSS feeds for bioinformatics",
         link = "http://www.dalkescientific.com/writings/diary/archive/2003/09/06/RSS.html",
         description = "One of the reasons I wrote PyRSS2Gen was to experiment with RSS for data collection in "
                       "bioinformatics.  Last year I came across...",
         guid = PyRSS2Gen.Guid("http://www.dalkescientific.com/writings/diary/archive/2003/09/06/RSS.html"),
         pubDate = datetime.datetime(2003, 9, 6, 21, 49)),
    ])

But here's another solution I like: use a template. After all, the whole point of templating is to separate the way you generate your content from the way you present it. Among other things, this makes it easy to produce multiple views of the same data, since you can reuse the code that generates it and just stick in a different template. And since each RSS feed is supposed to correspond to a web page, half the work the generation code — should be done already. You can just create an outline of an RSS feed in your favorite templating system (just read right off the spec line by line) and pick either the web page template or the RSS template depending on the URL. Look at this Clearsilver example I made:

<?cs each:item = feed.items ?><item>
    <?cs if:item.title ?><title><?cs var:item.title ?></title><?cs /if ?>
    <?cs if:item.link ?><link><?cs var:item.link ?></link><?cs /if ?>
    <?cs if:item.description ?><description><?cs var:item.description ?></description><?cs /if ?>
    <?cs if:item.author ?><author><?cs var:item.author ?></author><?cs /if ?>
    <?cs each:category = item.categories ?>
        <category<?cs if:category.domain ?> domain="<?cs var:category.domain ?>"<?cs /if ?>><?cs var:category ?></category>
    <?cs /each ?>
    <?cs if:item.comments ?><comments><?cs var:item.comments ?></comments><?cs /if ?>
    <?cs if:item.enclosure ?>
        <enclosure url="<?cs var:item.enclosure.url ?>" length="<?cs var:item.enclosure.length ?>" type="<?cs var:item.enclosure.type ?>"/>
    <?cs /if ?>
    <?cs if:item.publication_date ?><pubDate><?cs var:item.publication_date ?></pubDate><?cs /if ?>
    <source url="<?cs var:feed.url ?>"><?cs var:feed.title ?></source>
</item><?cs /each ?>

As a bonus, that actually looks like an RSS feed, so now you have a handy reference for all the different fields you can put in.