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

on weblogPostForm (adrdata=radio.weblog.init (), {
		<<8/22/04; 12:32:38 PM by SK
			<<Changed default size of title and link text areas to 45 characters to allow for easier theme compatibility.
		<<8/11/03; 3:21:14 AM by JES
			<<Give the weblog post form a name -- editPostForm. Needed for Mozilla rich text editor support.
		<<8/5/03; 6:03:14 PM by JES
			<<Added support for Mozilla's rich text editor.
		<<7/21/03; 1:29:18 AM by JES
			<<Added support for outgoing TrackBack pings.
		<<10/21/02; 4:55:05 PM by JES
			<<If posting an item from the News page, and the item is cached, delete the item from the cache so the checkmark will appear on the News page.
		<<10/15/02; 3:17:57 AM by JES
			<<Reduced the size of the title and link fields from 85 to 75 to reduce unnecessary whitespace when rendering in browsers that like to use a fixed-width font for text input fields.
		<<10/4/02; 9:18:26 PM by JES
			<<When posting a story from the news aggregator, don't decode entities in the story text and channel title through a call to radio.string.decodeEntities. The aggregator now does all the decoding needed, and any extra decoding here is double-decoding.
		<<Changes before 7/1/2002
			<<6/23/02; 9:59:20 PM by JES
				<<Fixed a bug which would prevent posts from being added to categories whose names contain a colon character.
			<<6/13/02; 3:38:13 PM by JES
				<<Call callback scripts at and Docs are here:
			<<4/10/02; 11:55:16 PM by JES
				<<When setting adrPostToEdit, only call radio.weblog.initPost if the post exists. If not, display an error message.
			<<4/6/02; 1:30:45 PM by DW
				<<Create shortcuts for titled blog posts, see call to radio.shortcuts.addTitledPost.
			<<3/25/02; 8:14:53 PM by JES
				<<If is defined, initialize the Link field with its value and consume it.
			<<3/13/02; 2:50:24 PM by DW
				<<If the link is the empty string, don't do a link for the post. 
			<<3/11/02; 11:46:23 AM by DW
				<<Add title and link to the form, only if weblogData.prefs.flTitleAndLinkOnPostForm is true.
			<<2/14/02; 11:32:46 PM by JES
				<<Call radio.weblog.initPost after setting adrPostToEdit, to make sure that required sub-elements of the post table are present.
			<<2/13/02; 3:52:45 PM by JES
				<<When a post is removed from the Home Page pseudo-category, re-publish the main rss file, in addition to the weblog index, and archive pages.
			<<2/13/02; 2:16:03 PM by JES
				<<Fixed a bug where posts that were routed to categories wouldn't update the category's storyList.
			<<2/13/02; 11:58:44 AM by JES
				<<Re-write of weblog post-handling code.
			<<1/28/02; 6:29:21 PM by JES
				<<If this is MacOS, convert text to Latin text before sending to the browser for editing.
			<<1/26/02; 5:55:29 PM by DW
				<<If is defined, initialize the edit box with that text and consume it.
			<<1/25/02; 2:29:52 PM by JES
				<<Handle the flPostToHomePage postArg -- set adrpost^.flNotOnHomePage to true or false accordingly.
			<<1/9/02; 1:35:06 AM by JES
				<<Fixed a bonehead bug: macro error "Macro error: Can't delete "t" because it hasn't been defined" when posting an edited item.
			<<1/9/02; 12:19:27 AM by JES
				<<When redirecting after editing a post, remove teh "uid" searchArg from the URL. See change note in radio.macros.weblogRecentPosts @ 1/9/02; 12:18:21 AM by JES.
			<<1/1/02; 10:24:26 PM by JES
				<<Added some whitespace after the error message.
			<<12/28/01; 2:51:09 AM by JES
				<<Don't allow empty weblog posts.
			<<12/26/01; 5:28:45 PM by JES
				<<In the three-button version, the Post button always says "Post", even if you're editing an item. No more "Post Changes".
			<<12/23/01; 11:31:02 PM by JES
				<<Don't pass a value to radio.userInterface.editorBox for ctrows.
			<<12/22/01; 4:54:46 PM by JES
				<<Respect the pref at weblogData.prefs.flPublishOnPost. If true, you get only a Post button. If false, you get a Post, a Publish, and a Post and Publish button.
			<<12/18/01; 3:41:56 PM by JES
				<<After editing a post, redirect to this page, but without the itemToEdit searchArg. This gets you a blank form for creating a new post. To edit the post you just made, scroll down a touch, and click the Edit button.
			<<12/12/01; 10:45:25 PM by JES
				<<Always allow edited posts to be posted, even if the text is the same as the post that was already there.
			<<12/12/01; 1:05:53 PM by JES
				<<When posting an item from the News page, use "Post to Weblog" for the button text, not "Post Changes". Don't add the text of the post above the editing form.
			<<12/10/01; 1:26:10 PM by JES
				<<Prevent duplicate posts. Put a friendly error message on the page, saying why the text wasn't posted. Localized.
			<<12/10/01; 12:43:04 PM by JES
				<<Replaced some missing functionality. In 7.0.1, when you edit a post, you see the rendered version of the post above the editing box. This had been missed in the port to 7.1. When posting items from the News page, this worked, but when editing weblog posts, it didn't.
			<<12/1/01; 3:24:16 PM by JES
				<<When posting an item from the News page, decode entities and untaint channel titles and news items' text.
			<<11/30/01; 2:44:30 AM by JES
				<<Entity-encode carriage returns to preserve line breaks in weblog posts. This prevents double-line breaks from being converted to <p> tags.
			<<11/14/01; 1:41:33 AM by JES
				<<Update pages by calling radio.weblog.updatePagesForPost, which updates all relevant files for weblog and weblog archive pages, and for category index and calendar pages. If editing a post, the button says "Post Changes" instead of "Post to Weblog".
			<<11/13/01; 9:58:46 PM by JES
				<<Don't call radio.string.untaint on weblog post text. Allows people to call macros in weblog posts.
			<<11/3/01; 10:51:34 PM by JES
				<<Get the redirect URL from the getArgs, instead of using the referer url.
			<<10/29/01; 4:57:32 PM by JES
				<<Added optional parameter, bgcolor.
			<<10/28/01; 9:29:52 AM by DW
				<<Don't embed the category checkboxes in a <p> element to tighten the display on the "Status Center" home page.
				<<Move the help link to the right of the post button instead of just below the edit box.
			<<10/19/01; 3:24:57 PM by JES
				<<Add categories after all the other meta-data, so that we're sure it makes it into the xml for the category. Add enclosures to posts here, instead of in radio.userInterface.enclosureField. This fixes a bug where enclosures could not be added for new posts.
			<<10/9/01; 5:04:26 PM by JES
				<<Add categories to posts here, instead of in radio.userInterface.categoryCheckboxes. This fixes a bug where categories could not be added for new posts.
			<<9/19/01; 12:36:58 PM by JES
				<<When posting a story from the News page, maintain the link between the news story and the post, and add the source data to the post.
			<<9/18/01; 2:24:04 PM by JES
				<<Various small optimizations.
				<<Only redirect after a post, if the referer is non-empty.
			<<9/17/01; 2:08:01 AM by JES
				<<Migrated code which dealt with the post button on the news page. This was completely broken with the last release. Now the news-page's post buttons work again.
	local (pta = html.getpagetableaddress ());
	<<scratchpad.pagetable = pta^; edit (@scratchpad.pagetable) //debugging code
	local (adrBeforeFormCallbacks =;
	local (adrAfterFormCallbacks =;
	if defined (adrdata^.prefs.editingToolName) {
		pta^.editingToolName = adrdata^.prefs.editingToolName};
	local (adrprefs = @adrdata^.prefs);
	local (adrPostToEdit, initialenclosureurl = "http://");
	local (adrGetArgs = @pta^.radioResponder.getArgs);
	local (errorMessage = "");
	bundle { //set adrPostToEdit, initialenclosureurl
		if defined (adrGetArgs^.itemToEdit) {
			local (adr = @adrdata^.posts.[string.padWithZeros (adrGetArgs^.itemToEdit, 8)] );
			if defined (adr^) {
				adrPostToEdit = @adrdata^.posts.[string.padWithZeros (adrGetArgs^.itemToEdit, 8)];
				radio.weblog.initPost (adrPostToEdit);
				if defined (adrPostToEdit^.enclosure) {
					initialenclosureurl = adrPostToEdit^.enclosure.url}}
			else {
				local (t); new (tableType, @t);
				t.postToEdit = adrGetArgs^.itemToEdit;
				errorMessage = radio.string.getlocalizedstring ("weblogPostForm.postDoesNotExistError", @t)}}};
	local (htmltext = "", indentlevel = 0);
	on add (s) {
		htmltext = htmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n");};
	local (flRedirect = false);
	if pta^.method == "POST" {
		<< = pta^; edit ( //debugging code
		local (adrargs = @pta^.radioResponder.postArgs);
		on addCatsTo (adrpost) {
			local (adrarg, name, adrcats = @adrpost^.categories);
			if defined (adrcats^) {
				local (adr);
				local (id = number (nameof (adrpost^)));
				for adr in @adrdata^.categories {
					if adr^.storyList contains id {
						adr^.storyList = adr^.storyList - {id};
						adr^.flDirty = true}};
				new(tableType, adrcats)};
			for adrarg in adrargs {
				name = nameof (adrarg^);
				if name beginswith "cat:" {
					local (catname = string.delete (name, 1, 4));
					radio.weblog.addPostToCategory (adrpost, catname, adrdata)}}};
					<<if not defined (adrcats^)
						<<new (tabletype, adrcats)
					<<adrcats^.[catname] = true
			<<bundle //see which RSS files need to be rebuilt
				<<local (adr)
				<<for adr in @adrdata^.categories
					<<local (fldirty = false)
					<<local (id = number (nameof (adrpost^)))
					<<if defined (adrcats^.[nameof (adr^)]) //it's part of the category
						<<if not (adr^.storyList contains id)
							<<adr^.storyList = adr^.storyList + {id}
							<<fldirty = true
					<<else //it's not part of the category
						<<if adr^.storyList contains id
							<<adr^.storyList = adr^.storyList - {id}
							<<fldirty = true
					<<if fldirty //don't clear it here
						<<adr^.flDirty = true
						<< = true
		on isDuplicate () {
			if adrPostToEdit != nil { //always allow edits -- return false
				return (false)};
			local (ctposts = sizeOf (adrdata^.posts));
			if ctposts > 0 {
				local (lastposttext = string (adrdata^.posts[ctposts].text));
				return (adrargs^.itemtext == lastposttext)};
			return (false)};
		on postIt () { //post to the weblog
			local (adrpost);
			adrpost = (adrargs^.itemtext, adrdata, adrpost:adrPostToEdit);
			if defined (adrargs^.sourceName) {
				adrpost^.sourceName = adrargs^.sourceName};
			if defined (adrargs^.postTitle) {
				radio.shortcuts.addTitledPost (adrpost, adrargs^.postTitle); //4/6/02 DW
				if adrargs^.postTitle != "" {
					adrpost^.title = adrargs^.postTitle}
				else {
					try {delete (@adrargs^.postTitle)}}};
			if defined (adrargs^.postLink) {
				local (lowerlink = string.lower (adrargs^.postLink));
				if (lowerlink != "http://") and (lowerlink != "") {
					adrpost^.link = adrargs^.postLink}
				else {
					try {delete (@adrargs^.link)}}};
			if defined (adrargs^.sourceUrl) {
				adrpost^.sourceUrl = adrargs^.sourceUrl};
			if defined (adrargs^.sourceTime) {
				adrpost^.sourceTime = adrargs^.sourceTime};
			if defined (adrargs^.idSourceStory) { //link the story to this post
				local (adrstory = radio.aggregator.getStoryAddress (adrargs^.idSourceStory));
				adrstory^.adrBlogPost = adrpost;
				xml.aggregator.clearCache ()}; //won't see the checkmark if we don't do this
			if defined (adrargs^.enclosureUrl) {
				local (enclosure);
				if sizeof (adrargs^.enclosureUrl) != sizeof (initialenclosureurl) {
					new (tabletype, @enclosure);
					xml.aggregator.getEnclosureData (adrargs^.enclosureUrl, @enclosure);
					if defined (enclosure.error) { //make sure they see the error
						flEnclosureError = true;
						if adrErrorString != nil {
							adrErrorString^ = enclosure.error}}};
				if enclosure != nil {
					adrpost^.enclosure = enclosure}};
			if defined (adrargs^.urlsToPing) { //add manually entered trackback ping urls to the outbound table for this post
				local (urls = string.trimWhiteSpace (adrargs^.urlsToPing));
				urls = string.replaceAll (urls, "\r\n", "\r");
				urls = string.replaceAll (urls, "\n", "\r");
				local (cturls = string.countFields (urls, "\r"));
				local (ixurl);
				for ixurl = 1 to cturls {
					local (url = string.nthField (urls, "\r", cturls));
					if url != "" {
						bundle { //reality checks
							if not (url contains "/") {
								url = url + "/"};
							if not (url beginswith "http://") {
								url = "http://" + url}};
						trackback.initOutboundUrl (adrpost, url)}}};
			if adrdata^.prefs.flCategoryCheckboxes { //set adrpost^.flNotOnHomePage
				if not defined (adrargs^.flPostToHomePage) {
					adrpost^.flNotOnHomePage = true}
				else {
					adrpost^.flNotOnHomePage = false}};
			addCatsTo (adrpost);
			bundle { //call callback scripts
				on callCallbacks (adrtable) {
					local (nomad);
					for nomad in adrtable {
						try {
							while typeOf (nomad^) == addressType {nomad = nomad^};
							nomad^ (adrpost)}}};
				callCallbacks (@radio.weblog.builtinCallbacks.beforeWeblogPostForm);
				callCallbacks (@radio.weblog.builtinCallbacks.afterWeblogPostForm);
				callCallbacks (adrBeforeFormCallbacks);
				callCallbacks (adrAfterFormCallbacks)};
			if defined (adrGetArgs^.referer) and adrGetArgs^.referer != "" { //redirect
				radio.webserver.redirect (adrGetArgs^.referer);
				flRedirect = true}
			else { //if there's a referer in the postArgs, redirect to that
				if defined (adrargs^.referer) {
					if adrargs^.referer != "" {
						local (actualReferer = "");
						if defined (pta^.requestHeaders.Referer) {
							actualReferer = pta^.requestHeaders.Referer};
						if adrargs^.referer != actualReferer { //only do a redirect if we came from somewhere else
							radio.webserver.redirect (adrargs^.referer);
							flRedirect = true}}}};
			if not flRedirect { //not redirecting to a referer -- redirect to this page, without the itemToEdit arg
				if defined (adrGetArgs^.itemToEdit) {
					delete (@adrGetArgs^.itemToEdit)};
				if defined (adrGetArgs^.uid) {
					delete (@adrGetArgs^.uid)};
				if defined (adrGetArgs^.idStory) {
					delete (@adrGetArgs^.idStory)};
				local (url = pta^.uri);
				if sizeOf (adrGetArgs^) > 0 {
					url = url + "?" + webserver.encodeArgs (adrGetArgs)};
				radio.webserver.redirect (url);
				flRedirect = true};
			return (adrpost)};
		local (flPost = false, flPublish = false);
		bundle { //set flPost and flPublish, based on which button was clicked
			if defined (adrargs^.postToWeblog) { //post and publish
				flPost = true;
				flPublish = true};
			if defined (adrargs^.postWithoutPublish) { //post
				flPost = true};
			if defined (adrargs^.publishWeblog) { //publish
				flPublish = true}};
		local (originalCatsList = {}, flWasOnHomePage = false);
		if adrpostToEdit != nil { //fill originalCatsList, set flWasOnHomePage
			local (adr);
			for adr in @adrPostToEdit^.categories {
				originalCatsList = originalCatsList + nameOf (adr^)};
			flWasOnHomePage = not adrPostToEdit^.flNotOnHomePage};
		if flPost {
			if isDuplicate () { //put an error message in the page -- don't post the text
				errorMessage = radio.string.getlocalizedstring ("weblogPostForm.duplicatePostError")};
			if string.trimWhiteSpace (adrargs^.itemtext) == "" {
				errorMessage = radio.string.getlocalizedstring ("weblogPostForm.emptyPostError")};
			if errorMessage == "" {
				postIt ()}};
		if flPublish {
			if errorMessage == "" {
				radio.weblog.publishAllUnpublishedPosts (adrdata)}};
		bundle { //publish category pages, from which the post has been removed
			if adrPostToEdit != nil {
				if errorMessage == "" {
					local (cat);
					for cat in originalCatsList {
						if not defined (adrPostToEdit^.categories.[cat]) {
							radio.weblog.publish (adrdata, cat);
							radio.weblog.publish (adrdata, cat, adrPostToEdit^.when);
							local (adrcat = @adrdata^.categories.[cat]);
							adrcat^.flDirty = true}};
					if flWasOnHomePage and adrPostToEdit^.flNotOnHomePage {
						radio.weblog.publish (adrdata);
						radio.weblog.publish (adrdata, d:adrPostToEdit^.when);
						radio.weblog.publishRss (adrdata)}}}}};
	if flRedirect { //don't bother rendering the html
		return ("")};
	local (initialtext = "", link = "http://");
	bundle { //look in and
		if defined ( {
			initialtext = string (;
			delete (};
		if defined ( {
			link = string (;
			delete (}};
	bundle { //start the form
		add (html.editor.formStart ("itemtext", name:"editPostForm", pta:pta)); indentlevel++};
	bundle { //add referer as a hidden item
		local (referer = "");
		<<if defined (pta^.requestHeaders.referer)
			<<referer = pta^.requestHeaders.referer
		if defined (pta^.radioResponder.getArgs) {
			if defined (pta^.radioResponder.getArgs.referer) {
				referer = pta^.radioResponder.getArgs.referer}};
		add ("<input name=\"referer\" type=\"hidden\" value=\"" + referer + "\">")};
	bundle { //editing form
		if adrPostToEdit != nil { //get initial text from the post, put it above the editing box
			initialtext = string (adrPostToEdit^.text)}
			<<add (html.processMacros (string.replaceAll (initialtext, "\r\n", "\r")) + "<br><br>")
		else {
			if defined (adrGetArgs^.idstory) {
				local (adraggregatordata = xml.aggregator.init ());
				local (adrstory = radio.aggregator.getStoryAddress (adrGetArgs^.idstory));
				if defined ([nameOf (adrstory^)] ) { //invalidate news-item cache
					delete ([nameOf (adrstory^)] )};
				local (adrsource = @adraggregatordata^.services.[adrstory^.url]);
				local (viatext = " [<a href=\"" + adrsource^.compilation.channellink + "\">" + adrstory^.channeltitle + "</a>]");
				local (globe, globeimg = radio.images.systemImageRef ("qbullet/remote"));
				initialtext = adrstory^.storytext + viatext;
				bundle { //link the globe to the HTML rendering of the channel
					with adrsource^.compilation {
						globe = "<a href=\"" + channellink + "\" title=\"" + radio.html.translateToEntities (channeldescription) + "\">" + globeimg + "</a>"}};
				add (globe + " <i>Source: " + adrstory^.channeltitle + "; " + adrstory^.time + ".</i><br><br>");
				add (adrstory^.storytext + "<br><br>");
				add ("<input name=\"sourceName\" type=\"hidden\" value=\"" + adrstory^.channeltitle + "\">");
				add ("<input name=\"sourceTime\" type=\"hidden\" value=\"" + adrstory^.time + "\">");
				add ("<input name=\"sourceUrl\" type=\"hidden\" value=\"" + adrstory^.url + "\">");
				if defined (adrGetArgs^.referer) {
					add ("<input name=\"referer\" type=\"hidden\" value=\"" + adrGetArgs^.referer + "\">")};
				add ("<input name=\"idSourceStory\" type=\"hidden\" value=\"" + adrGetArgs^.idstory + "\">")}
				<<edit (adrstory)
			else { //if there was an error, put the previously posted text in the box, so the user can see it
				if (errorMessage != "") and (pta^.method == "POST") {
					initialtext = pta^.radioResponder.postArgs.itemtext}}};
		bundle { //massage the text
			if system.environment.isMac { //convert to Latin for the browser
				initialtext = string.macToLatin (initialtext)};
			local (editingTool = html.editor.getEditingTool (pta));
			case editingTool {
				"wysiwygEditorMozilla" { //pre-process for Mozilla's rich text editor
					}}//do nothing
					<<initialtext = string.replaceAll (initialtext, "\r\n", "\r")
					<<if initialtext contains "\r\r"
						<<initialtext = string.replaceAll (initialtext, "\r\r", "<br><br>")
			else { //pre-process for all other editors
				initialtext = radio.html.translateToEntities (initialtext);
				initialtext = string.replaceAll (initialtext, "\r\n", "\r");
				initialtext = string.replaceAll (initialtext, "\r", "
			temp.t = initialtext};
		local (formtext = radio.userinterface.editorbox (initialtext));
		on callCallbacks (adrtable) {
			local (s = "");
			local (nomad);
			for nomad in adrtable {
				try {
					while typeOf (nomad^) == addressType {nomad = nomad^};
					s = s + nomad^ (adrPostToEdit)}};
			return (s)};
		formtext = callCallbacks (adrBeforeFormCallbacks) + formtext + callCallbacks (adrAfterFormCallbacks);
		add (formtext)};
	bundle { //add error message, if there was an error
		if errorMessage != "" {
			add ("<br><font color=\"red\" class=\"small\">" + errorMessage + "</font><br>")}};
	bundle { //add title and link
		if adrdata^.prefs.flTitleAndLinkOnPostForm {
			local (title = "");
			if defined (adrPostToEdit^.title) {
				title = adrPostToEdit^.title};
			if defined (adrPostToEdit^.link) {
				link = adrPostToEdit^.link};
			add ("<table cellspacing=\"10\" cellpadding=\"0\">"); indentlevel++;
			add ("<tr><td>Title: </td><td><input type=\"text\" name=\"postTitle\" size=\"55\" maxlength=\"512\" value=\"" + title + "\"></td></tr>"); // 8/22/04; 12:31:51 PM by SK --changed default size to 45 characters to allow for easier theme compatibility
			add ("<tr><td>Link: </td><td><input type=\"text\" name=\"postLink\" size=\"55\" maxlength=\"512\" value=\"" + link + "\"></td></tr>"); // 8/22/04; 12:31:51 PM by SK --changed default size to 45 characters to allow for easier theme compatibility
			add ("</table>"); indentlevel--}};
	bundle { //category checkboxes and help link
		if adrprefs^.flCategoryCheckboxes {
			<<add ("<br>" + radio.userinterface.categoryCheckboxes (adrdata, adrposttoedit, bgcolor))
			add (radio.userinterface.categoryCheckboxes (adrdata, adrposttoedit, bgcolor))}};
	bundle { //enclosure field
		if adrprefs^.flEnclosureField {
			add ("<p>" + radio.userinterface.enclosureField (adrdata, adrposttoedit) + "</p>")}};
	bundle { //trackback URLs to Ping box
		if adrdata^.prefs.trackback.flEnabled {
			add ("<p><div class=\"small\"><b>" + radio.string.getLocalizedString ("weblogPostForm.urlsToPing") + "</b></div><textarea name=\"urlsToPing\" rows=\"3\" cols=\"55\" wrap=\"soft\"></textarea>")}};
	bundle { //post button(s)
		local (buttons, flEdit);
		flEdit = ( (initialtext != "") and (errorMessage == "") and (not defined (adrGetArgs^.idstory)) );
		if adrprefs^.flPublishOnPost { //one-button version -- Post to Weblog or Post Changes
			local (buttonTitle);
			if flEdit { //Post Changes
				buttonTitle = radio.string.getlocalizedstring ("weblogPostForm.postChangesButton")}
			else { //Post to Weblog
				buttonTitle = radio.string.getlocalizedstring ("weblogPostForm.postToWeblogButton")};
			buttons = "<input type=\"submit\" name=\"postToWeblog\" value=\"" + buttonTitle + "\">"}
		else { //three-button version -- Post, Publish, Post & Publish
			bundle { //Post button
				local (buttonTitle);
				<<if flEdit //Post Changes
					<<buttonTitle = radio.string.getlocalizedstring ("weblogPostForm.postChangesButton")
				<<else //Post
				buttonTitle = radio.string.getlocalizedstring ("weblogPostForm.postButton");
				buttons = "<input type=\"submit\" name=\"postWithoutPublish\" value=\"" + buttonTitle + "\">"};
			bundle { //Publish button
				local (buttonTitle = radio.string.getlocalizedstring ("weblogPostForm.publishButton"));
				buttons = buttons + "  <input type=\"submit\" name=\"publishWeblog\" value=\"" + buttonTitle + "\">"};
			bundle { //Post & Publish button
				local (buttonTitle = radio.string.getlocalizedstring ("weblogPostForm.postAndPublishButton"));
				buttons = buttons + "  <input type=\"submit\" name=\"postToWeblog\" value=\"" + buttonTitle + "\">"}};
		bundle { //help link
			buttons = buttons + "  " + radio.userinterface.helplink ("Editing Box")};
		add ("<p>" + buttons + "</p>")};
	add ("</form>"); indentlevel--;
	return (htmltext)}
<<bundle //testing
	<<local (params = scratchpad.pagetable)
	<<html.setPageTableAddress (@params)
	<<radio.macros.weblogPostForm ()
	<<html.deletePageTableAddress ()

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.