Cleaner RSS Feeds in TiddlyWiki

After playing a bit with TiddlyWiki, I decided that I wanted a cleaner RSS feed from it. It has always bothered me a little that any tiddler I changed always ended up in the RSS stream that TW generates, even tiddlers that a “normal” reader of a TW-based site wouldn’t (and probably shouldn’t) care about. So I tweaked the generateRss() function from version 1.2.35 (look for it down around line 2500 of the TW source) to provide some control over which tiddlers end up being included.

My hacked version of the generateRss() function (below) differs only in the section that generates the “body” of the RSS feed. If each tiddler is tagged specifically for RSS inclusion OR is tagged for neither exclusion from the TW lists nor from the RSS stream, it is included in the RSS stream. This logic is based on case-insensitive checking for the presence of the includRSS, excludeLists, excludeRSS tags on the tiddler. I have submitted this tweak to Jeremy Ruston, the author and maintainer of TW, for incorporation into TW.

function generateRss()
{
  var s = [];

  var d = new Date();
  var u = store.getTiddlerText("SiteUrl",null);
  // Assemble the header
  s.push("< " + "?xml version=\"1.0\"?" + ">");
  s.push("<rss version=\"2.0\">");
  s.push("<channel>");
  s.push("<title>" + store.getTiddlerText("SiteTitle","").htmlEncode() + 
    "</title>");
  if(u)
    s.push("<link>" + u.htmlEncode() + "</link>");
  s.push("<description>" + store.getTiddlerText("SiteSubtitle","").htmlEncode() + 
    "</description>");
  s.push("<language>en-us</language>");
  s.push("<copyright>Copyright " + d.getFullYear() + " " + 
    config.options.txtUserName.htmlEncode() + "</copyright>");
  s.push("<pubdate>" + d.toGMTString() + "</pubdate>");
  s.push("<lastbuilddate>" + d.toGMTString() + "</lastbuilddate>");
  s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
  s.push("<generator>TiddlyWiki " + version.major + "." + 
    version.minor + "." + version.revision + "</generator>");
  // The body
  var tiddlers = store.getTiddlers("modified");
  var n = 0; // Count of tiddlers included in RSS
  var t = tiddlers.length - 1; // Tiddler index
  while ((n < config.numRssItems) && (t >= 0))
  {
    var tTags = tiddlers[t].getTags().toLowerCase();
    // If this tiddler is flagged specifically for inclusion OR this tiddler
    // is not specifically flagged for exclusion (either by the "excludeLists"
    // or "excludeRSS" tag)...
    if ((tTags.indexOf("includerss") >= 0) || 
       ((tTags.indexOf("excludelists") == -1) && 
       (tTags.indexOf("excluderss") == -1)))
    {
      s.push(tiddlers[t].saveToRss(u)); // Generate the RSS entry for this tiddler
      n++; // Increment the count of tiddlers in the feed
    }
    t--;    // Next tiddler...
  }
  // And footer
  s.push("</channel>");
  s.push("</rss>");
  // Save it all
  return s.join("\n");
}