Monday, November 08, 2010 at 12:05 AM.
system.verbs.builtins.radio.weblog.publishCategoryRss
on publishCategoryRss (flOnlyWriteChanges = true) {
<<Changes
<<1/20/03; 5:41:21 PM by DW
<<Set a "thread" global so that callback scripts can tell which category the RSS is being generated for. To get the address of the category:
<<adrcat = ["_adrcat_"]
<<More information about thread globals is in the comment at the head of this script:
<<thread.getGlobalAddress
<<3/12/02; 2:59:11 PM by JES
<<Implement a getUrl callback to be called by radio.weblog.writeRssFile. The callback determines the url for a given post, and returns true if the url can be determined, or false if not.
<<1/20/02; 11:10:12 AM by DW
<<Overhaul. Calls radio.weblog.writeRssFile to generate the RSS file. Caught a lot of inconsistencies here. Now we have one place to upgrade if we need to fix bugs or add features.
<<Old code is here.
<<local (xmltext = "")
<<bundle //build xmltext
<<local (indentlevel = 0)
<<on add (s)
<<xmltext = xmltext + string.filledstring ("\t", indentlevel) + s + "\r\n"
<<add ("<?xml version=\"1.0\"?>")
<<add ("<!-- RSS generated by Radio UserLand v" + frontier.version () + " on " + date.netstandardstring (now) + " -->")
<<add ("<rss version=\"0.92\">"); indentlevel++
<<add ("<channel>"); indentlevel++
<<add ("<title>" + encode (user.prefs.name + ": " + adrcat^.displayName) + "</title>")
<<add ("<link>" + htmlUrl + "</link>")
<<if defined (adrcat^.description)
<<add ("<description>" + encode (adrcat^.description) + "</description>")
<<add ("<language>" + "xxx" + "</language>")
<<add ("<copyright>" + "Copyright " + date.year () + " " + adrblog^.prefs.authorName + "</copyright>")
<<add ("<lastBuildDate>" + date.netstandardstring (now) + "</lastBuildDate>")
<<add ("<docs>http://backend.userland.com/rss092</docs>")
<<add ("<managingEditor>" + encode (adrblog^.prefs.managingEditor) + "</managingEditor>")
<<add ("<webMaster>" + encode (adrblog^.prefs.webmaster) + "</webMaster>")
<<bundle //add cloud element
<<with user.radio.prefs.rssCloud
<<add ("<cloud domain=\"" + server + "\" port=\"" + port + "\" path=\"" + path + "\" registerProcedure=\"" + registerProcedure + "\" protocol=\"" + protocol + "\"/>")
<<bundle //add the items
<<local (storyname, ctitems = 0, i)
<<for i = sizeof (adrcat^.storylist) downto 1
<<local (storynum = adrcat^.storylist [i])
<<local (adrpost = @adrblog^.posts.[string.padwithzeros (storynum, 8)])
<<if defined (adrpost^)
<<add ("<item>"); indentlevel++
<<add ("<description>" + encode (string (adrpost^.text)) + "</description>")
<<if defined (adrpost^.sourceName) and defined (adrpost^.sourceUrl)
<<add ("<source url=\"" + encode (adrpost^.sourceUrl) + "\">" + encode (adrpost^.sourceName) + "</source>")
<<if defined (adrpost^.enclosure)
<<if defined (adrpost^.enclosure.length) //05/28/01; JES: length may be undefined if the URL could not be read -- don't generate an error
<<with adrpost^.enclosure
<<add ("<enclosure url=\"" + url + "\" length=\"" + length + "\" type=\"" + type + "\"/>")
<<add ("</item>"); indentlevel--
<<if ++ctitems >= adrblog^.prefs.maxOutputItemsPerChannel
<<break
<<add ("</channel>"); indentlevel--
<<add ("</rss>"); indentlevel--
<<xmltext = enableCurlyBraces (xmltext)
<<12/20/01; 2:08:35 AM by JES
<<Use file.writeTextFile instead of file.writeWholeFile to write the RSS.
<<12/9/01; 12:42:35 PM by DW
<<Get in synch with radio.weblog.publishRss, they have the same parts, similar values.
<<12/7/01; 11:21:48 AM by JES
<<Undid the last change. Category RSS files need to be stored in their own folders so that you can give them their own upstream locations by dropping a #upstream.xml in the folder.
<<12/6/01; 11:23:56 PM by JES
<<Changed the location of RSS files. Now they're stored in the rss folder specified in your prefs, with a filename which corresponds to adrcat^.filename, instead of storing the rss in a sub-folder named adrcat^.filename.
<<11/14/01; 12:44:00 PM by JES
<<Don't build the html files here. This is now done via radio.weblog.publish. Save the rss.xml file in the category's folder instead of in a file named for the category.
<<Store the correct html and rss urls in the category's table. Use the correct html url for <link> in the xml rendering.
<<10/28/01; 10:37:35 AM by DW
<<Set adrcat^.htmlUrl unconditionally. For some reason it would only set the URL if it wasn't already defined. That means that if you change the location of a file, the URL wouldn't change. Watch for breakage.
<<10/19/01; 3:09:50 AM by JES
<<Moved changes from radio.weblog.generateOutputChannels to here. This was the correct place to make category publishing work.
<<10/8/01; 6:40:14 PM by JES
<<Ported from myUserLandSuite.generateOutputChannels. Removed "temporary band-aids" (yay!).
<<Changes before 10/8/01
<<Wednesday, December 20, 2000 at 2:00:00 PM by DW
<<Created.
<<Thursday, December 28, 2000 at 4:47:53 PM by DW
<<The <link> element in the RSS file had the incorrect filename.
<<1/5/01; 11:31:25 AM by DW
<<Add support for <cloud>.
<<1/6/01; 5:13:06 PM by DW
<<Respect myUserLandData.prefs.maxOutputItemsPerChannel.
<<1/13/01; 8:38:28 AM by DW
<<Clear the dirty bit on channels after generating. This bug was causing every channel to rebuild every time one channel changed.
<<1/21/01; 2:48:41 PM by DW
<<Major rewrite.
<<Loose-end, setting the rssUrl in the category.
<<Blog post tables need to have information for the source. Right now they don't and we don't generate the <source> element.
<<1/22/01; 11:30:26 AM by DW
<<Use user.playlist.prefs.wwwUpstreamFolderUrl to set the rssUrl element in every category.
<<1/22/01; 1:18:58 PM by DW
<<Whew! Now we write out the <souce> element. That was tricky.
<<1/22/01; 3:22:59 PM by DW
<<Make sure all categories have flDirty booleans. It's a temporary band-aid.
<<1/23/01; 12:53:11 AM by DW
<<Make sure all categories have storyList lists. It's a temporary band-aid.
<<1/25/01; 2:20:13 PM by DW
<<Let blog.publish do the HTML rendering.
<<2/22/01; 9:49:31 PM by JES
<<If this is a Mac, convert strings in the RSS XML to Latin text.
<<3/1/01; 11:44:29 PM by JES
<<Use Frontier.id instead of hard-coding 'Radu'.
<<3/4/01; 6:38:58 PM by JES
<<The <title> tag now contains the displayName of the category, instead of the name of its table.
<<3/4/01; 11:44:27 PM by JES
<<Removed \r\n from the begining of both the RSS and the HTML renderings. Set adrcat^.rss to the rendered RSS text, since it's used by myUserLandSuite.html.viewXmlSource when clicking the XML button for a category on the Categories page.
<<5/28/01; 11:39:05 PM by JES
<<Add <enclosure> in a try block, since if the URL could not be read, length will be undefined, which will cause an error window to continusouly, and annoyingly pop up.
local (adrblog = radio.weblog.init ());
local (rssfolder = radio.file.getAbsolutePath (adrblog^.prefs.rssCategoryFolderPath));
local (htmlfolder = radio.file.getAbsolutePath (adrblog^.prefs.htmlCategoryFolderPath));
local (adrcat, flwrite);
for adrcat in @adrblog^.categories {
flwrite = true;
if flOnlyWriteChanges {
if not adrcat^.fldirty {
flwrite = false}};
if flwrite {
local (htmlurl = radio.upstream.getFileUrl (htmlfolder + adrcat^.filename + file.getpathchar ()));
bundle { //1/20/03 by DW -- set thread global
["_adrcat_"] = adrcat};
adrcat^.htmlUrl = htmlurl;
local (title = user.prefs.name + ": " + adrcat^.displayName, description = "", language = "none");
if defined (adrcat^.description) {
description = adrcat^.description};
if defined (adrcat^.language) {
language = adrcat^.language};
local (f = rssfolder + adrcat^.filename + file.getpathchar () + "rss.xml");
adrcat^.rssUrl = radio.upstream.getFileUrl (f);
on callback (adrpost) { //return true if the post is included
return (adrcat^.storylist contains number (nameof (adrpost^)))};
on getUrlCallback (adrpost, adrurl) { //return true if adrurl^ could be set
return (radio.weblog.getUrlForPost (adrpost, adrurl, nameOf (adrcat^), adrblog) )};
local (xmltext = radio.weblog.writeRssFile (f, title, htmlurl, description, language, adrcallback:@callback, adrblog:adrblog, adrGetUrlCallback:@getUrlCallback));
wp.newtextobject (xmltext, @adrcat^.rss); //03/04/2001 JES: this is used by myUserLandSuite.html.viewXmlSource, when clicking the XML button for a category on the Categories page
adrcat^.dateLastUpload = clock.now ();
adrcat^.flDirty = false}}}
<<bundle //test code
<<local (tc = clock.ticks ())
<<weblogData.categories.test.flDirty = true
<<publishCategoryRss ()
<<dialog.alert (clock.ticks () - tc)
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.