Monday, November 08, 2010 at 12:00 AM.
scripting2Suite.server.buildStoryPage
on buildStoryPage (username, adrstory, flupload=true) { <<Changes <<8/4/10; 7:02:21 PM by DW <<Define urlNext and urlPrev. If it's the first, urlPrev is the emptystring, if it's the last, urlNext is the empty string. <<7/6/10; 4:46:56 AM by DW <<Go from 2-level hierarchy to N-level hierarchy. <<6/30/10; 2:48:51 PM by DW <<If a story has a flVisibleSubtext attribute and it's true, render the outline differently. <<6/14/10; 3:21:04 AM by DW <<In addition to <%pubDate%> add <%bylineDate%> specifically for display in the byline of the story. It uses the longstring date format. <<6/11/10; 7:54:02 AM by DW <<Now we allow paragraphs to have subtext that is hidden until you expand it. <<6/3/10; 9:23:48 AM by DW <<Created. local (adrsystemdata = scripting2suite.init (), now = clock.now (), fldebug = true, flVisibleSubtext); local (adrdata = scripting2suite.inituser (username)); local (storytext = "\r\r", indentlevel = 0, adr, ct=0); local (imgPermalink = string (scripting2Suite.data.html.sharpPermalinkImg)); <<edit (adrstory) scripting2Suite.server.initStory (adrstory); //6/14/10 by DW -- make absolutely sure it has all fields it's supposed to bundle { //set flVisibleSubtext if defined (adrstory^.flVisibleSubtext) { flVisibleSubtext = adrstory^.flVisibleSubtext} else { flVisibleSubtext = false}}; on add (s) { storytext = storytext + string.filledstring ("\t", indentlevel) + s + "\r\n"}; on decode (s) { return (xml.entitydecode (s, true))}; if not defined (adrstory^.xstruct) { xml.compile (adrstory^.opmltext, @adrstory^.xstruct)}; local (adropml = xml.getaddress (@adrstory^.xstruct, "opml")); local (adrbody = xml.getaddress (adropml, "body")); local (adrsummit = xml.getaddress (adrbody, "outline")); bundle { //add the outline structure on gettextatt (adrx) { return (decode (xml.getattributevalue (adrx, "text")))}; on hassubs (adrx) { //return true if the outline node has sub-outlines local (adr); for adr in adrx { if nameof (adr^) endswith "outline" { //contains at least one sub return (true)}}; return (false)}; on dolevel (adrlevel, textClass) { local (adr); for adr in adrlevel { if nameof (adr^) endswith "outline" { local (s = gettextatt (adr), idPgf = "p" + ++ct, idDiv = "div" + ct, icon=""); bundle { //change idPgf if it has a paragraph-level serial number, 6/23/10 by DW try { idPgf = "p" + xml.getattributevalue (adr, "pgfnum")}}; local (flhassubs = hassubs (adr)); if flhassubs { icon = scripting2Suite.server.getExpandCollapseIcon (idDiv, flVisibleSubtext)}; bundle { //add a blue arrow link, if it's a node of type link, 6/28/10 by DW s = s + scripting2Suite.server.getLinkHtml (adr)}; if adrdata^.prefs.flPgfPermalinks { s = "<a name=\"" + idPgf + "\"></a>" + icon + s + " <a href=\"#" + idPgf + "\">" + imgPermalink + "</a>"}; if flhassubs { local (adrsub, class="hide"); add ("<p class=\"" + textClass + "\">" + s); indentlevel++; if flVisibleSubtext { class = "show"}; add ("<div class=\"" + class + "\" id=\"" + idDiv + "\" name=\"" + idDiv + "\">"); indentlevel++; dolevel (adr, "storySubtext"); add ("</div>"); indentlevel--; add ("</p>"); indentlevel--} else { add ("<p class=\"" + textClass + "\">" + s + "</p>")}}}}; dolevel (adrsummit, "storyPageText")}; adrstory^.storytext = storytext; local (t = adrstory^); t.whenLastUpdate = date.longstring (t.whenLastSave) + "; " + date.timestring (t.whenLastSave); t.bodytext = storytext; t.pubDate = t.postdate; //I prefer to use RSS terminology in the story template t.localPubDate = scripting2Suite.server.getLocalTime (username, t.pubDate); //6/14/10 by DW t.bylineDate = date.longstring (t.localPubDate) + " at " + date.timestring (t.localPubDate, false); //6/14/10 by DW t.author = adrdata^.prefs.ownerName; //RSS terminology scripting2Suite.server.setupMacrosTable (username, @t); //add common elements t.crumbTrail = scripting2Suite.server.getCrumbTrail (t.baseurl, t.postdate); //6/8/10 by DW bundle { //set nextPrev local (nextlink = "Next", prevlink = "Previous"); if adrstory^.adrprev != "" { local (adrprev = address (adrstory^.adrprev)); //we store addresses as strings, and convert when we use them prevlink = "<a href=\"" + adrprev^.url + "\">" + prevlink + "</a>"}; if adrstory^.adrnext != "" { local (adrnext = address (adrstory^.adrnext)); //we store addresses as strings, and convert when we use them nextlink = "<a href=\"" + adrnext^.url + "\">" + nextlink + "</a>"}; t.nextPrev = prevlink + " / " + nextlink}; bundle { //set urlNext and urlPrev, 8/4/10 by DW if adrstory^.adrprev != "" { local (adrprev = address (adrstory^.adrprev)); t.urlPrev = adrprev^.url} else { t.urlPrev = ""}; if adrstory^.adrnext != "" { local (adrnext = address (adrstory^.adrnext)); t.urlNext = adrnext^.url} else { t.urlNext = ""}; t.urlParent = ""; t.urlChild = ""}; bundle { //set up calendar scripting2Suite.server.getCalendarText (username, adrstory^.postdate, t.baseurl, @t.calendar, @t.nextPrevMonths)}; bundle { //set editButton 7/3/10 by DW t.editButton = "<script type=\"text/javascript\" src=\"http://127.0.0.1:5337/scripting2/editor/controls?username=" + username + "&url=" + adrstory^.url + "\"></script>"}; bundle { //run it all through the template, ship the file to the server local (pagetext = string.multiplereplaceall (string (adrdata^.prefs.storytemplate), @t, false, "<%", "%>")); pagetext = scripting2Suite.server.glossarySubstitution (@adrdata^.prefs.glossary, pagetext); pagetext = scripting2Suite.server.glossarySubstitution (@scripting2Suite.data.systemGlossary, pagetext); if flupload { scripting2Suite.writeStaticFile (username, adrstory^.path, pagetext); if not defined (adrstory^.ctUploads) { adrstory^.ctUploads = 1}; adrstory^.ctUploads++; adrstory^.whenLastUpload = clock.now ()}}}; bundle { //test code local (adrstory = @scripting2Data.server.users.davewiner.calendar.["2010"].["06"].["11"].["00246"]); local (tc = clock.ticks ()); script.startProfile (true); buildStoryPage ("davewiner", adrstory, false); script.stopProfile (@scratchpad.storyProfile)} <<dialog.alert (clock.ticks () - tc) <<webbrowser.openurl (adrstory^.url)
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.