Monday, November 08, 2010 at 12:05 AM.
system.verbs.builtins.radio.macros.weblogRecentPosts
on weblogRecentPosts (adrdata=radio.weblog.init (), bgColor=radio.data.htmlColors.cellBgColor, hilightBgColor=radio.data.htmlColors.highlightColor, catname=nil) { <<Changes: <<11/5/02; 1:23:20 AM by JES <<Reversed the last change. <<10/28/02; 7:38:13 PM by JES <<Call html.processMacros with plainprocessing as true to prevent extra paragraph tags. <<10/12/02; 2:48:51 AM by JES <<Localized the header and delete button text. <<3/11/02; 8:57:40 AM by DW <<When displaying a recent post, use the title and link info, if it's available. <<2/13/02; 3:42:48 PM by JES <<Update relevant category RSS files, when post(s) are deleted. Don't update the main weblog archive pages when a post's flNotOnHomePage is true. <<2/10/02; 11:09:58 PM by JES <<Fixed a bug where when deleting a post from an archive page, the post would be deleted, but the public site would not be updated, and a macro error would appear when the browser reloads the page in the desktop website. <<2/10/02; 10:39:17 PM by JES <<Fixed a bug where archive pages would limit the number of posts displayed to the same number displayed on the home page, which could prevent editing of some items. <<2/5/02; 5:04:08 PM by JES <<Fixed a bug where navigating to previous posts using the calendar on the desktop website home page, would not display previous posts. <<2/4/02; 2:54:47 PM by JES <<Added an optional parameter, catname. If specified, only posts in the specified category will be listed. <<1/25/02; 1:26:05 PM by JES <<Applied the same optimization to add() that was applied to radio.html.viewNewsItems. Before, this script took 84 ticks. After this change, it takes 29 ticks -- more than twice as fast. <<1/19/02; 9:11:26 PM by JES <<Make sure that adrpost^.when is defined. If not, set it to when for a surrounding post if possible, or to clock.now if there are no other posts. <<1/15/02; 2:08:58 PM by DW <<Call callbacks in user.radio.callbacks.deleteItem. <<http://radio.userland.com/stories/storyReader$7740#userradiocallbacksdeleteitem <<1/9/02; 12:18:21 AM by JES <<Add a searchArg, uid, whose value is number (clock.now ()) -- to act as a browser cache confuser. This prevents the browser from loading up an old, cached version of a previously edited post, when clicking the Edit button a second time. <<1/6/02; 4:30:49 AM by JES <<Added table css classes. <<11/30/01; 12:32:04 PM by JES <<Convert line-endings in htmltext to \r, before returning. <<11/29/01; 5:50:39 PM by JES <<When a post is deleted, remove it from the storyList in all categories which include it. <<11/23/01; 9:53:05 PM by DW <<It's help support was archaic. Modernized. <<11/23/01; 9:47:05 PM by JES <<Call html.processMacros on the returned htmltext. <<11/14/01; 11:08:52 PM by JES <<Rewrote the post-handling code, which deletes posts and updates the relevant pages. Return the empty string for dynamic pages, which aren't the home page. <<10/29/01; 4:47:17 PM by JES <<Added optional parameters: bgColor and hilightBgColor. <<10/27/01; 9:08:01 AM by DW <<If static rendering, return the empty string. <<8/31/01; 8:38:06 PM by JES <<Factored from radio.weblog.main. <<Preserve the menu and d getArgs so that we stay on the same archive page, and menu mode when clicking an EDIT button. local (pta = html.getPageTableAddress ()); <<scratchpad.pagetable = pta^; edit (@scratchpad.pagetable) //debugging code bundle { //if static rendering, return the empty string if pta^.radioResponder.flStaticRendering { return ("")}}; bundle { //if not the weblog editor page, return the empty string if not pta^.radioResponder.flStaticRendering { if pta^.path != radio.data.systemUrls.weblogEditor { if not (string.lower (pta^.path) beginsWith string.lower (radio.data.systemUrls.newCategory)) { return ("")}}}}; local (htmltext, indentlevel=0); on add (s) { htmltext = htmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n");}; local (d = clock.now (), flArchivePage = false, dateArg); //PBS 02/22/01: archive page support local (editbuttonimg = radio.images.systemImageRef ("icons/editbutton")); local (globeimg = radio.images.systemImageRef ("qbullet/remote")); local (xmlimg = radio.images.systemImageRef ("icons/xml")); local (mediaimg = radio.images.systemImageRef ("qbullet/sound")); local (checkmarkimg = radio.images.systemImageRef ("icons/checkmark")); local (helpurl = radio.userinterface.helpurl ("Previous Posts")); if pta^.method == "POST" { local (adrargs = @pta^.radioResponder.postArgs); if defined (adrargs^) { if defined (adrargs^.deletePosts) { delete (@adrargs^.deletePosts); local (postsToDelete); new (tableType, @postsToDelete); local (adr, adrpost); for adr in adrargs { //build a table containing addresses of posts to delete on isPostId (s) { try { local (id = number (s)); return (defined (adrdata^.posts.[string.padWithZeros (id, 8)]))}; return (false)}; if isPostId (nameOf (adr^)) { local (adritem = table.uniqueName ("post", @postsToDelete, 8)); adritem^ = @adrdata^.posts.[string.padwithzeros (nameof (adr^), 8)]}}; local (flUpdateHomePage = false, datesToUpdate = {}); local (catsToUpdate); new (tableType, @catsToUpdate); for adr in @postsToDelete { //go through all the posts, figure out which pages to update, deleting posts as we go adrpost = adr^; local (theDate); bundle { //get theDate local (day, month, year, hour, minute, second); date.get (adrpost^.when, @day, @month, @year, @hour, @minute, @second); theDate = date.set (day, month, year, 0, 0, 0)}; if not flUpdateHomePage { //if flUpdateHome page is true, we already know we need to update if radio.weblog.isPostOnHomePage (adrpost) { flUpdateHomePage = true}}; if not (datesToUpdate contains theDate) { //keep a list of archive dates to re-render if not adrpost^.flNotOnHomePage { datesToUpdate = datesToUpdate + theDate}}; if defined (adrpost^.categories) { //go through categories and figure out what needs updating local (ixcat, sizecats = sizeOf (adrpost^.categories)); for ixcat = 1 to sizecats { if adrpost^.categories[ixcat] { //a hit local (catname = nameOf (adrpost^.categories[ixcat])); local (adrcat = @adrdata^.categories.[catname]); if defined (adrcat^) { adrcat^.storyList = adrcat^.storyList - {number (nameOf (adrpost^))}}; if not defined (catsToUpdate.[catname]) { //init our temp data new (tableType, @catsToUpdate.[catname]); catsToUpdate.[catname].flUpdateIndexPage = false; catsToUpdate.[catname].datesToUpdate = {}}; if not catsToUpdate.[catname].flUpdateIndexPage { //is this post in the cat's index page? if radio.weblog.isPostOnHomePage (adrpost, catname) { catsToUpdate.[catname].flUpdateIndexPage = true}}; if not (catsToUpdate.[catname].datesToUpdate contains theDate) { //the cat's archive page catsToUpdate.[catname].datesToUpdate = catsToUpdate.[catname].datesToUpdate + theDate}}}}; bundle { //call the callbacks -- 1/15/02; 2:08:29 PM by DW try { if not defined (user.radio.callbacks.deleteItem) { new (tabletype, @user.radio.callbacks.deleteItem)}; local (adrcallback); for adrcallback in @user.radio.callbacks.deleteItem { try { while typeOf (adrcallback^) == addressType { adrcallback = adrcallback^}; adrcallback^ (adrpost)}}}}; delete (adrpost)}; bundle { //update all the pages local (dateToUpdate, adrCatToUpdate); if flUpdateHomePage { //update the weblog home page radio.weblog.publish (adrdata); thread.callScript (@radio.weblog.publishRss, {adrdata})}; for dateToUpdate in datesToUpdate { //update weblog archive pages radio.weblog.publish (adrdata, d:dateToUpdate)}; for adrCatToUpdate in @catsToUpdate { //update all the category pages local (catname = nameOf (adrCatToUpdate^), flUpdateRss = false); if adrCatToUpdate^.flUpdateIndexPage { radio.weblog.publish (adrdata, catname); flUpdateRss = true}; for dateToUpdate in adrCatToUpdate^.datesToUpdate { radio.weblog.publish (adrdata, catname, dateToUpdate); flUpdateRss = true}; if flUpdateRss { local (adrcat = @adrdata^.categories.[catname]); adrcat^.flDirty = true}}}}}}; <<bundle //old code <<local (adr, adrpost, deletedPostDates = {}, deletedPostDate) <<for adr in adrargs <<adrpost = @adrdata^.posts.[string.padwithzeros (nameof (adr^), 8)] <<if defined (adrpost^) <<local (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 <<delete (adrcats) <<bundle //add the date for this post to the deletedPostDates list <<local (day, month, year, hour, minute, second) <<date.get (adrpost^.when, @day, @month, @year, @hour, @minute, @second) <<deletedPostDate = date.set (day, month, year, 0, 0, 0) <<if not (deletedPostDates contains deletedPostDate) <<deletedPostDates = deletedPostDates + deletedPostDate <<delete (adrpost) <<bundle //publish home page and archive pages in their own threads <<local (flPublishHomePage = false) <<for deletedPostDate in deletedPostDates <<if radio.weblog.isDateOnHomePage (deletedPostDate) <<flPublishHomePage = true <<if flPublishHomePage <<radio.weblog.publish (adrdata) <<for deletedPostDate in deletedPostDates <<local (day, month, year, hour, minute, second) <<date.get (deletedPostDate, @day, @month, @year, @hour, @minute, @second) <<local (maxDate = date.set (day, month, year, 23, 59, 59)) <<thread.callScript (@radio.weblog.publishStaticPage, {adrdata, nil, 1, maxDate, deletedPostDate, false}) local (adrPostToEdit); bundle { //process GET args local (adrargs = @pta^.radioResponder.getArgs); if defined (adrargs^) { if defined (adrargs^.d) { //PBS 02/22/01: archive page, possibly flArchivePage = true; local (year = string.nthField (adrargs^.d, '/', 1)); local (month = string.nthField (adrargs^.d, '/', 2)); local (day = string.nthField (adrargs^.d, '/', 3)); d = date.set (day, month, year, 0, 0, 0); dateArg = year + "/" + string.padWithZeros (month, 2) + "/" + string.padWithZeros (day, 2); bundle { //check d against midnight of the day with the last post local (midnightMostRecentDay); local (adrLastPost = @adrdata^.posts [sizeOf (adrdata^.posts)]); local (day, month, year, hour, minute, second); date.get (adrLastPost^.when, @day, @month, @year, @hour, @minute, @second); midnightMostRecentDay = date.set (day, month, year, 0, 0, 0); if d >= midnightMostRecentDay { flArchivePage = false}}}; if defined (adrargs^.itemToEdit) { adrPostToEdit = @adrdata^.posts.[string.padWithZeros (adrargs^.itemToEdit, 8)]}}}; bundle { //add the posts local (ctposts = sizeof (adrdata^.posts)); if ctposts > 0 { add ("<br>"); add ("<form method=\"POST\" action=\"" + radio.data.systemUrls.weblogEditor + "\">"); indentlevel++; if flArchivePage { add ("<input type=\"hidden\" name=\"d\" value=\"" + dateArg + "\">")}; add ("<table class=\"dwsFrameTable\" cellspacing=\"0\" cellpadding=\"0\"><tr bgcolor=\"" + radio.data.htmlColors.framecolor + "\"><td>"); indentlevel++; add ("<table class=\"dwsTable\" border=\"0\" cellspacing=\"1\" cellpadding=\"5\">"); indentlevel++; if flArchivePage { local (t); new (tabletype, @t); t.day = date.shortString (d); add (radio.html.prefsElement.separator (radio.string.getLocalizedString ("homePage.postsForDate", @t), false, 4, helpUrl))} <<"Posts for " + date.shortString (d) + "..." else { local (t); new (tabletype, @t); t.numposts = adrdata^.prefs.viewing.ctPosts; add (radio.html.prefsElement.separator (radio.string.getLocalizedString ("homePage.previousNPosts", @t), false, 4, helpUrl))}; <<"Previous " + adrdata^.prefs.viewing.ctPosts + " posts..." local (ctlisted = 0); case adrdata^.prefs.viewing.mode { "byPosts" { local (adrpost, editurl, cellBgColor); <<local (lastitemnum = ctposts - adrdata^.prefs.viewing.ctPosts + 1) <<if lastitemnum < 1 <<lastitemnum = 1 <<local (start = ctposts, end = lastitemnum) local (i = ctposts); if flArchivePage { local (day, month, year, hour, minute, second); date.get (d, @day, @month, @year, @hour, @minute, @second); <<bundle //obsolete code <<local (adrFirstPost) <<local (firstOfDay = date.set (day, month, year, 0, 0, 0)) <<radio.weblog.getNextPostAfterDate (adrdata, firstOfDay, @adrFirstPost) <<end = indexOf (adrFirstPost^) //reverse chronological order local (adrLastPost); local (lastOfDay = date.set (day, month, year, 23, 59, 59)); radio.weblog.getLastPostBeforeDate (adrdata, lastOfDay, @adrLastPost, catname); i = indexOf (adrLastPost^)}; loop { if i < 1 { break}; if not flArchivePage { if ctlisted >= adrdata^.prefs.viewing.ctPosts { break}}; adrpost = @adrdata^.posts [i]; if flArchivePage { //the home page -- end is a post table index, if an archive page if adrpost^.when < d { break}}; if catname != nil { if not radio.weblog.isPostInCategory (adrpost, catname) { i--; continue}}; if adrpost == adrPostToEdit { cellBgColor = hilightBgColor} else { cellBgColor = bgcolor}; add ("<tr class=\"dwsTableCell\" bgcolor=\"" + cellBgColor + "\">"); indentlevel++; bundle { //add checkbox local (name = number (nameof (adrpost^))); local (checkboxval = "xxx "); if false { checkboxval = checkboxval + "checked"}; add ("<td class=\"dwsTableCell\" valign=\"top\"><input type=\"checkbox\" name=\"" + name + "\" value=" + checkboxval + "></td>")}; bundle { //add the post text local (posttext = string (adrpost^.text)); if defined (adrpost^.title) { local (titletext = adrpost^.title); if defined (adrpost^.link) { titletext = "<a href=\"" + adrpost^.link + "\" class=\"weblogItemTitle\">" + titletext + "</a>"}; posttext = titletext + ". " + posttext}; add ("<td class=\"dwsTableCell\" valign=\"top\">" + posttext + "</td>")}; bundle { //make sure that adrpost^.when is defined if not defined (adrpost^.when) { local (ix = indexOf (adrpost^)); if ix > 1 { adrpost^.when = date (adrdata^.posts[ix - 1].when + 1)} else { if sizeOf (adrdata^.posts) > 1 { adrpost^.when = date (adrdata^.posts[ix + 1].when - 1)} else { adrpost^.when = clock.now ()}}}}; add ("<td class=\"dwsTableCell\" valign=\"top\" nowrap><font size=\"-1\">" + radio.string.getDateString (adrpost^.when) + "</font></td>"); bundle { //add little icons add ("<td class=\"dwsTableCell\" valign=\"top\" nowrap>"); indentlevel++; bundle { //EDIT button, checkmark, enclosure icons local (args); new (tabletype, @args); args.itemToEdit = number (nameof (adrpost^)); args.uid = number (clock.now ()); <<if defined (pta^.radioResponder.getArgs.menu) <<args.menu = pta^.radioResponder.getArgs.menu if flArchivePage { args.d = dateArg}; <<editurl = pta^.uri + "?" + webserver.encodeargs (@args) editurl = radio.data.systemUrls.weblogEditor + "?" + webserver.encodeargs (@args); editurl = string.replaceAll (editurl, "%2F", "/"); local (checkmark = ""); bundle { //an item has a checkmark if it's in at least one category if defined (adrpost^.categories) { if sizeOf (adrpost^.categories) > 0 { local (adr); for adr in @adrpost^.categories { if adr^ { checkmark = " <a title=\"" + radio.data.strings.checkmarktooltip + "\">" + checkmarkimg + "</a>"; break}}}}}; local (encl = ""); bundle { //if it has an enclosure add a media link if defined (adrpost^.enclosure) { if not defined (adrpost^.enclosure.error) { encl = "<br><a href=\"" + adrpost^.enclosure.url + "\">" + mediaimg + "</a>"}}}; add ("<a href=\"" + editurl + "\">" + editbuttonimg + "</a>" + checkmark + encl)}; add ("</td>"); indentlevel--}; add ("</tr>"); indentlevel--; i--; ctlisted++}}}; if ctlisted == 0 { return ("")}; add ("</table>"); indentlevel--; add ("</td></tr></table>"); indentlevel--; local (deleteButtonText = radio.string.getLocalizedString ("buttons.delete")); add ("<p><input type=\"submit\" name=\"deletePosts\" value=\"" + deleteButtonText + "\"></p>"); add ("</form>"); indentlevel--}}; bundle { //start the form local (actionString = ""); if defined (pta^.radioResponder.getArgs) { if sizeOf (pta^.radioResponder.getArgs) > 0 { actionString = " action=\"" + pta^.uri + "?" + webserver.encodeArgs (@pta^.radioResponder.getArgs) + "\""}}; add ("<form method=\"POST\"" + actionString + ">"); indentlevel++}; if flArchivePage { add ("<input type=\"hidden\" name=\"d\" value=\"" + dateArg + "\">")}; add ("</form>"); indentlevel--; <<return (htmltext) htmltext = string.replaceAll (htmltext, "\r\n", "\r"); return (html.processMacros (htmltext, false, adrPageTable:pta))} <<bundle //testing <<local (params = scratchpad.pagetable) <<html.setPageTableAddress (@params) <<radio.macros.weblogRecentPosts () <<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.