Monday, November 08, 2010 at 12:05 AM.
system.verbs.builtins.radio.macros.weblogPostForm
on weblogPostForm (adrdata=radio.weblog.init (), bgcolor=radio.data.htmlColors.cellBgColor) { <<Changes <<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 user.radio.callbacks.beforeWeblogPostForm and user.radio.callbacks.afterWeblogPostForm. Docs are here: http://radio.userland.com/weblogPostFormCallbacks <<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 system.temp.radio.misc.initialPostLink 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 system.temp.radio.misc.initialPostText 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 = @user.radio.callbacks.beforeWeblogPostForm); local (adrAfterFormCallbacks = @user.radio.callbacks.afterWeblogPostForm); 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" { <<workspace.pt = pta^; edit (@workspace.pt) //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 <<system.temp.radio.flPublishCategoryRss = 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 = radio.weblog.post (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 system.temp.radio.misc.initialPostText and system.temp.radio.misc.initialPostLink if defined (system.temp.radio.misc.initialPostText) { initialtext = string (system.temp.radio.misc.initialPostText); delete (@system.temp.radio.misc.initialPostText)}; if defined (system.temp.radio.misc.initialPostLink) { link = string (system.temp.radio.misc.initialPostLink); delete (@system.temp.radio.misc.initialPostLink)}}; 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 (system.temp.radio.newsItemCache.[nameOf (adrstory^)] ) { //invalidate news-item cache delete (@system.temp.radio.newsItemCache.[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.