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.