Monday, November 08, 2010 at 12:05 AM.

on viewStoryList (flNewStoryLink=false) {
		<<10/12/02; 3:56:52 AM by JES
			<<Localized the Link header, and the Delete button.
		<<6/17/02; 1:53:19 AM by JES
			<<Added checkboxes and a Delete button that can be used to delete stories.
		<<5/20/02; 12:33:08 AM by JES
			<<Added a globe icon which links to the upstreamed story file.
		<<1/30/02; 2:08:50 AM by JES
			<<Don't list files whose names being with the '#' character.
		<<1/14/02; 10:13:43 PM by JES
			<<Don't add the intro-text when rendering for upstreaming.
		<<1/4/02; 12:31:42 PM by JES
			<<Cleaned up the layout: added some space between the explanatory text and the list. Added a lint break between "There are no stories to list" and the explanatory text.
		<<1/3/02; 1:12:26 PM by JES
			<<Added intro text, and help link. Removed reads column.
		<<12/21/01; 4:22:42 PM by JES
			<<New optional parameter, flNewStoryLink determines whether there's a link at the bottom of the page that you can use to create a new story.
			<<List files in /stories/ instead of files in the folder in which this page resides. Links to stories in the dynamic site no longer include the file extension.
			<<Link the new story link to /system/pages/newStory.
		<<12/5/01; 7:56:28 PM by JES
			<<Localized. If there are no stories, add a bit of text to the page saying "There are no stories to list at this time."
		<<10/15/01; 1:49:37 AM by JES
			<<Don't add the read-count if doing static rendering -- it's not a real count, but is rather a count of hits for the page on the synamic site. It's also not updated when pages are read on the dynamic site.
		<<10/13/01; 4:19:49 AM by JES
			<<Don't add the create a story link if doing static rendering. When doing static rendering, patch the story URLs to use the .html extension. Don't list the index page or the new story page in the story list.
		<<9/24/01; 3:21:29 PM by JES
			<<Don't list invisible files.
	local (htmltext = "\r", indentlevel = 0);
	on add (s) {
		htmltext = htmltext + string.filledstring ("\t", indentlevel) + s + "\r\n"};
	local (pta = html.getpagetableaddress ());
	pta^.title = radio.string.getlocalizedstring ("viewStories.title");
	if not pta^.radioResponder.flStaticRendering {
		if flNewStoryLink {
			local (t); new (tableType, @t);
			t.url =;
			add (radio.string.getlocalizedstring ("viewStories.description", @t) + " " + radio.userInterface.helpLink ("The Stories page"))}};
	<<scratchpad.params = pta^; edit (@scratchpad.params)
	<<if defined (pta^.radioResponder.getArgs.command)
		<<if pta^.radioResponder.getArgs.command == "newStory"
			<<add (radio.userinterface.editorbox ("", 15))
			<<return (htmltext)
	local (pc = file.getpathchar ());
	local (indexfile = pta^.radioResponder.fileBeingRendered);
	local (folder = + + pc);
	local (globeicon = radio.images.systemImageRef ("qbullet/remote", flFileUrl:pta^.radioResponder.flSameMachine) );
	if pta^.method == "POST" { //delete stories
		local (adrargs = @pta^.radioResponder.postArgs);
		if defined (adrargs^.deleteButton) {
			local (storiesFolder = + + pc);
			local (lowerStoriesFolder = string.lower (storiesFolder));
			<< = pta^
			delete (@adrargs^.deleteButton);
			local (adr, flUpdateStoriesList = false);
			for adr in adrargs {
				local (f = string.urlDecode (nameOf (adr^)));
				try {
					file.delete (f);
					bundle { //flag the story list to be re-upstreamed
						if string.lower (f) beginsWith lowerStoriesFolder {
							flUpdateStoriesList = true}}}};
			if flUpdateStoriesList {
				if radio.file.locateFileIgnoringExtension (storiesFolder + "index", @indexPath) {
					if string.lower (f) != string.lower (indexPath) {
						local (adrfile =[indexPath]);
						if defined (adrfile^) {
							adrfile^.upstream.whenLastUploaded = date (0)}}}};
			local (redirectUrl = "http://" + pta^.host + pta^.uri);
			radio.webserver.redirect (redirectUrl);
			return ("")}};
	bundle { //add table of links to stories
		local (f);
		local (filelist = {});
		fileloop (f in folder, infinity) {
			local (lowername = string.lower (file.fileFromPath (f)));
			if lowername beginsWith "#" {
			if lowername beginsWith "newstory." {
			if lowername beginsWith "index." {
			if system.environment.isCarbon { //skip .DS_Store files
				if file.fileFromPath (f) beginsWith "." {
			if not file.isVisible (f) {
			filelist = filelist + {f}};
		local (i);
		if sizeOf (filelist) > 0 {
			if not pta^.radioResponder.flStaticRendering and flNewStoryLink { //form start
				add ("<form method=\"POST\">"); indentlevel++};
			add ("<table cellpadding=\"0\" cellspacing=\"8\">"); indentlevel++;
			if pta^.radioResponder.flStaticRendering or (not flNewStoryLink) {
				add ("<tr><td align=\"right\"><b>" + radio.string.getlocalizedstring ("viewStories.dateHeader") + "</b></td><td><b>" + radio.string.getlocalizedstring ("viewStories.titleHeader") + "</b></td></tr>")}
			else { //dynamic page
				add ("<tr><td></td><td align=\"right\"><b>" + radio.string.getlocalizedstring ("viewStories.dateHeader") + "</b></td><td><b>" + radio.string.getlocalizedstring ("viewStories.titleHeader") + "</b></td><td><b>" + radio.string.getlocalizedstring ("viewStories.linkHeader") + "</b></td></tr>")};
			for i = sizeof (filelist) downto 1 {
				f = filelist [i];
				if file.folderfrompath (f) != folder {
					local (adratts);
					radio.file.getFileAttributes (f, @adratts);
					add ("<tr>"); indentlevel++;
					if not pta^.radioResponder.flStaticRendering { //delete checkbox
						if flNewStoryLink {
							add ("<td valign=\"top\"><input type=\"checkbox\" name=\"" + string.urlEncode (f) + "\" value=\"x\" /></td>")}};
					add ("<td align=\"right\" valign=\"top\">" + date.shortstring (file.created (f)) + "</td>");
					local (title);
					bundle { //title
						if defined (adratts^.title) {
							title = adratts^.title}
						else {
							title = file.filefrompath (f)};
						local (url);
						if pta^.radioResponder.flStaticRendering == true { //get the URL from the filetable
							local (adrfile =[f]);
							if defined (adrfile^) {
								if defined (adrfile^.upstream.url) {
									url = adrfile^.upstream.url}}}
							<<if string.nthField (url, "/", string.countFields (url, "/")) contains "."
								<<url = string.popSuffix (url)
								<<url = url + ".html"
						else { //dynamic page -- point at the page in the /stories/ folder
							url = "/" + + "/";
							url = url + string.replaceall (string.delete (f, 1, sizeOf (folder)), pc, "/");
							url = string.popSuffix (url)};
						add ("<td><a href=\"" + url + "\">" + title + "</a></td>")};
					<<if not pta^.radioResponder.flStaticRendering
						<<add ("<td align=\"right\">" + adratts^.hits + "</td>")
					<<add ("<td align=\"right\">" + string.gigabytestring (adratts^.size) + "</td>")
					local (upstreamlink = "");
					if not pta^.radioResponder.flStaticRendering {
						if defined (adratts^.upstream) {
							if defined (adratts^.upstream.url) {
								if adratts^.upstream.url != "" {
									upstreamlink = "<a href=\"" + adratts^.upstream.url + "\" title=\"Permanent link to the public version of \'" + xml.entityEncode (title, true) + "\'.\">" + globeicon + "</a>"}}};
						add ("<td align=\"right\">" + upstreamlink + "</td>")};
					add ("</tr>"); indentlevel--}};
			add ("</table>"); indentlevel--;
			if not pta^.radioResponder.flStaticRendering { //delete button, form end
				if flNewStoryLink {
					add ("<p><input type=\"submit\" name=\"deleteButton\" value=\"" + radio.string.getLocalizedString ("buttons.delete") + "\" /></p>");
					add ("</form>"); indentlevel--}}}
		else {
			add ("<p>" + radio.string.getlocalizedstring ("viewStories.noStories") + "</p>")}};
		<<bundle //add create-story link
			<<if not pta^.radioResponder.flStaticRendering
				<<if flNewStoryLink
					<<local (t); new (tableType, @t)
					<<t.url =
					<<add (radio.string.getlocalizedstring ("viewStories.createStoryLink", @t))
	return (htmltext)}

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.