Added preliminary support for generating RSS feeds

Which also included adding the shadow shadow tiddlers that are built
into TiddlyWiki's source code, and are not handled by cook.rb and
ginsu.rb
print-window-tiddler
Jeremy Ruston 2011-12-08 16:20:11 +00:00
rodzic e9d3a878c1
commit c3331cb090
2 zmienionych plików z 117 dodań i 11 usunięć

Wyświetl plik

@ -165,15 +165,6 @@ Recipe.prototype.processRecipeFile = function(recipe,text,contextPath) {
});
};
// Special post-processing required for certain ingredient types
Recipe.prototype.readIngredientPostProcess = {
"shadow": function(fields) {
// Add ".shadow" to the name of shadow tiddlers
fields.title = fields.title + ".shadow";
return fields;
}
};
// Read a tiddler file and callback with an array of hashmaps of tiddler fields. For single
// tiddler files it also looks for an accompanying .meta file
Recipe.prototype.readTiddlerFile = function(filepath,contextPath,callback) {
@ -284,5 +275,80 @@ Recipe.tiddlerOutputter = {
}
};
// Cook an RSS file of the most recent 20 tiddlers
Recipe.prototype.cookRss = function()
{
var me = this,
numRssItems = 20,
s = [],
d = new Date(),
u = this.store.getTiddler("SiteUrl").getParseTree().render("text/plain"),
encodeTiddlyLink = function(title) {
return title.indexOf(" ") == -1 ? title : "[[" + title + "]]";
},
tiddlerToRssItem = function(tiddler,uri) {
var s = "<title" + ">" + utils.htmlEncode(tiddler.fields.title) + "</title" + ">\n";
s += "<description>" + utils.htmlEncode(tiddler.getParseTree().render("text/html")) + "</description>\n";
var i;
if(tiddler.fields.tags) {
for(i=0; i<tiddler.fields.tags.length; i++) {
s += "<category>" + tiddler.fields.tags[i] + "</category>\n";
}
}
s += "<link>" + uri + "#" + encodeURIComponent(encodeTiddlyLink(tiddler.fields.title)) + "</link>\n";
if(tiddler.fields.modified) {
s +="<pubDate>" + tiddler.fields.modified.toUTCString() + "</pubDate>\n";
}
return s;
},
getRssTiddlers = function(sortField,excludeTag) {
var r = [];
me.store.forEachTiddler(function(title,tiddler) {
if(!tiddler.hasTag(excludeTag)) {
r.push(tiddler);
}
});
r.sort(function(a,b) {
var aa = a.fields[sortField] || 0,
bb = b.fields[sortField] || 0;
console.error("Comparing %s (%s) and %s (%s)",a.fields.title,util.inspect(a.fields[sortField],false,8),b.fields.title,util.inspect(b.fields[sortField],false,8));
if(aa < bb) {
return -1;
} else {
if(aa > bb) {
return 1;
} else {
return 0;
}
}
});
return r;
};
// Assemble the header
s.push("<" + "?xml version=\"1.0\"?" + ">");
s.push("<rss version=\"2.0\">");
s.push("<channel>");
s.push("<title" + ">" + utils.htmlEncode(this.store.getTiddler("SiteTitle").getParseTree().render("text/plain")) + "</title" + ">");
if(u)
s.push("<link>" + utils.htmlEncode(u) + "</link>");
s.push("<description>" + utils.htmlEncode(this.store.getTiddler("SiteSubtitle").getParseTree().render("text/plain")) + "</description>");
//s.push("<language>" + config.locale + "</language>");
s.push("<pubDate>" + d.toUTCString() + "</pubDate>");
s.push("<lastBuildDate>" + d.toUTCString() + "</lastBuildDate>");
s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
s.push("<generator>https://github.com/Jermolene/cook.js</generator>");
// The body
var tiddlers = getRssTiddlers("modified","excludeLists");
var i,n = numRssItems > tiddlers.length ? 0 : tiddlers.length-numRssItems;
for(i=tiddlers.length-1; i>=n; i--) {
s.push("<item>\n" + tiddlerToRssItem(tiddlers[i],u) + "\n</item>");
}
// And footer
s.push("</channel>");
s.push("</rss>");
// Save it all
return s.join("\n");
}
exports.Recipe = Recipe;

Wyświetl plik

@ -47,6 +47,40 @@ var switches = parseOptions(Array.prototype.slice.call(process.argv,2),"dummy"),
lastRecipeFilepath = null,
currSwitch = 0;
// Add the shadow tiddlers that are built into TiddlyWiki
var shadowShadowStore = new WikiStore(null),
shadowShadows = [
{title: "StyleSheet", text: ""},
{title: "MarkupPreHead", text: ""},
{title: "MarkupPostHead", text: ""},
{title: "MarkupPreBody", text: ""},
{title: "MarkupPostBody", text: ""},
{title: "TabTimeline", text: "<<timeline>>"},
{title: "TabAll", text: "<<list all>>"},
{title: "TabTags", text: "<<allTags excludeLists>>"},
{title: "TabMoreMissing", text: "<<list missing>>"},
{title: "TabMoreOrphans", text: "<<list orphans>>"},
{title: "TabMoreShadowed", text: "<<list shadowed>>"},
{title: "AdvancedOptions", text: "<<options>>"},
{title: "PluginManager", text: "<<plugins>>"},
{title: "SystemSettings", text: ""},
{title: "ToolbarCommands", text: "|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|"},
{title: "WindowTitle", text: "<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>"},
{title: "DefaultTiddlers", text: "[[GettingStarted]]"},
{title: "MainMenu", text: "[[GettingStarted]]"},
{title: "SiteTitle", text: "My TiddlyWiki"},
{title: "SiteSubtitle", text: "a reusable non-linear personal web notebook"},
{title: "SiteUrl", text: ""},
{title: "SideBarOptions", text: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options \u00bb" "Change TiddlyWiki advanced options">>'},
{title: "SideBarTabs", text: '<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>'},
{title: "TabMore", text: '<<tabs txtMoreTab "Missing" "Missing tiddlers" TabMoreMissing "Orphans" "Orphaned tiddlers" TabMoreOrphans "Shadowed" "Shadowed tiddlers" TabMoreShadowed>>'}
];
store.shadows.shadows = shadowShadowStore;
for(var t=0; t<shadowShadows.length; t++) {
shadowShadowStore.addTiddler(new Tiddler(shadowShadows[t]));
}
var processNextSwitch = function() {
if(currSwitch < switches.length) {
var s = switches[currSwitch++],
@ -119,8 +153,14 @@ var commandLineSwitches = {
if(!recipe) {
callback("--savewiki requires a recipe to be loaded first");
}
fs.writeFile(args[0],recipe.cook(),"utf8",function(err) {
callback(err);
fs.writeFile(path.resolve(args[0],"index.html"),recipe.cook(),"utf8",function(err) {
if(err) {
callback(err);
} else {
fs.writeFile(path.resolve(args[0],"index.xml"),recipe.cookRss(),"utf8",function(err) {
callback(err);
});
}
});
}
},