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

system.verbs.builtins.mainResponder.discuss.listThreads

on listThreads (d, bgColor="ivory", otherColor="beige", tableWidth=425, pta=nil, headerColor="black", headerTextColor=nil, cssPrefix="", threadAliveDays=5, threadActiveDays=1, adrTemplate=nil, adrItemTemplate=nil, adrTemplateHeader=nil, adrTemplateFooter=nil, activeThreadIcon=nil, inactiveThreadIcon=nil, userIcon=nil, adrInDgCallback=nil, flUseMappedMemberKeys=false) {
	<<List current discussion threads
		<<10/09/00; 7:59:29 PM by JES
	<<Changes:
		<<4/18/03; 5:26:51 PM by JES
			<<New optional parameter, flUseMappedMemberKeys -- if true, we use the newer style numeric member keys instead of the older email address style member keys.
		<<10/3/02; 2:33:49 AM by JES
			<<Added preliminary support for the {fullSubject} psuedo-macro.
		<<4/4/02; 12:55:24 AM by JES
			<<New optional paramter, adrInDgCallback. Passed to mainResponder.discuss.getThreadData.
		<<1/25/02; 6:04:26 PM by PBS
			<<Performance enhancement in the local "add" routine -- add a trailing semicolon; use parentheses to get the expression in x = x + y form (which is optimized by the kernel).
		<<10/17/01; 10:43:48 AM by PBS
			<<Don't use IP address when constructing the URL to a built-in icon. This fixes a bug with servers that have multiple IP addresses.
		<<9/26/01; 6:32:45 PM by PBS
			<<Pass adrMembers to mainResponder.members routines for performance enhancement.
		<<??? by JES
			<<Added template support.
	
	if pta == nil {
		pta = html.getPageTableAddress ()};
	
	local (adrData = mainResponder.discuss.openRoot (pta));
	local (adrCal = @adrData^.calendar);
	local (adrMsgs = @adrData^.messages);
	local (htmlText = "");
	local (i, j);
	local (membershipGroup = pta^.responderAttributes.defaultMembershipGroup);
	local (msgReaderUrl = pta^.responderAttributes.urls^.discussMsgReader);
	if not (msgReaderUrl endsWith "$") {
		msgReaderUrl = msgReaderUrl + "$"};
	local (flCss = (cssPrefix != "")); //if true, emit CSS classes, otherwise don't
	local (yr = date.year (d), mo = date.month (d), day = date.day (d)); // the year, month and day which save state for the thread-reader
	local (template, itemTemplate, templateHeader, templateFooter);
	local (adrMembers = mainResponder.members.getMembershipTable (membershipGroup)); //PBS 09/26/01: get adrMembers, address of membership group
	
	local (nameTable);
	new (tableType, @nameTable);
	
	on add (s) {
		htmlText = htmlText + (s + "\r");};
	
	on td (s, align="", class="", height="", bgcolor="", fontColor="") {
		local (fontClass = "");
		if (flCss) and (class != "") {
			class = cssPrefix + class;
			fontClass = " class=\"" + class + "Font\"";
			class = " class=\"" + class + "\""};
		if height != "" {
			height = " height=\"" + height + "\""};
		if align != "" {
			align = " " + align};
		if bgcolor != "" {
			bgcolor = " " + bgcolor};
		add ("<td nowrap" + align + " valign=\"middle\"" + class + height + bgcolor + "><font size=\"-1\"" + fontClass + fontColor + ">  " + s + "  </font></td>")};
	
	on shortenString (s, maxLen=35) {
		if defined (string.ellipsize) {
			return (string.ellipsize (s, maxLen))};
		if sizeOf (s) > maxLen {
			return (string.mid (s, 1, maxLen - 3) + "...")};
		return (s)};
	
	local (activeThreadImgUrl, inactiveThreadImgUrl, threadStatusIconWidth = 17, threadStatusIconHeight = 14);
	local (userIconUrl, userIconHeight = 16, userIconWidth = 16);
	bundle { // build image data for topic status icons and dailyLink icon
		<<local (myDottedId = tcp.myDottedId ())
		<<local (myDottedId = tcp.dns.getMyDottedId ()) //PBS 09/26/01: 
		<<local (myPort = user.inetd.config.http.port)
		<<local (portString = "")
		<<if myPort != 80
			<<portString = ":" + myPort
		<<local (resourcesUrl = "http://" + myDottedId + portString + "/mainResponderResources/")
		local (resourcesUrl = "/mainResponderResources/"); //PBS 10/16/01: don't use IP address
		activeThreadImgUrl = resourcesUrl + "icons/folder.open2";
		inactiveThreadImgUrl = resourcesUrl + "icons/folder2";
		userIconUrl = resourcesUrl + "icons/user";
		
		if inactiveThreadIcon == nil {
			inactiveThreadIcon = "<img src=\"" + inactiveThreadImgUrl + "\" height=\"" + threadStatusIconHeight + "\" width=\"" + threadStatusIconWidth + "\" border=\"0\" alt=\"inactiveThread\">"};
		if activeThreadIcon == nil {
			activeThreadIcon = "<img src=\"" + activeThreadImgUrl + "\" height=\"" + threadStatusIconHeight + "\" width=\"" + threadStatusIconWidth + "\" border=\"0\" alt=\"activeThread\">"};
		if userIcon == nil {
			userIcon = "<img src=\"" + userIconUrl + "\" height=\"" + userIconHeight + "\" width=\"" + userIconWidth + "\" border=\"0\" alt=\"user\">"}};
	
	bundle { // get templates
		bundle { // get the header
			if typeOf (adrTemplateHeader) == addressType and defined (adrTemplateHeader^) {
				templateHeader = string (adrTemplateHeader^)}
			else {
				if flCss {
					templateHeader = "<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\" class=\"" + cssPrefix + "Table\">"}
				else {
					templateHeader = "<table cellpadding=\"0\" cellspacing=\"1\" border=\"0\">"}};
			templateHeader = string.trimWhiteSpace (templateHeader)};
		bundle { // get the template
			if typeOf (adrTemplate) == addressType and defined (adrTemplate^) {
				template = string (adrTemplate^)}
			else {
				on addToTemplate (s) {
					template = template + s + "\r"};
				if flCss {
					addToTemplate ("<tr bgcolor=\"{headerColor}\" class=\"" + cssPrefix + "SeparatorRow\">");
					addToTemplate ("<td colspan=\"6\" height=\"28\" width=\"100%\">");
					addToTemplate ("<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr>");
					addToTemplate ("<td>  <font color=\"{headerTextColor}\" class=\"" + cssPrefix + "SeparatorFont\"><b>Recent Topics</b></font></td>");
					addToTemplate ("<td align=\"right\"><a href=\"{dayListUrl}\" style=\"color: {headerTextColor};\"><font size=\"-1\" color=\"{headerTextColor}\" class=\"" + cssPrefix + "DayLinkFont\">Chronological View</font></a>  </td>");
					addToTemplate ("</tr></table>");
					addToTemplate ("</td>");
					addToTemplate ("</tr>");
					
					addToTemplate ("<tr bgcolor=\"{bgcolor}\" class=\"" + cssPrefix + "TitleRow\">");
					addToTemplate ("<td nowrap align=\"center\" height=\"28\" class=\"" + cssPrefix + "StatusIconTitle\"> </td>");
					addToTemplate ("<td nowrap class=\"" + cssPrefix + "MessageLinkTitle\">  <b>Topic</b>  </td>");
					addToTemplate ("<td nowrap class=\"" + cssPrefix + "AuthorTitle\">  <b>Originator</b>  </td>");
					addToTemplate ("<td nowrap align=\"right\" class=\"" + cssPrefix + "CountMessagesTitle\">  <b>Msgs</b>  </td>");
					addToTemplate ("<td nowrap align=\"right\" class=\"" + cssPrefix + "CountReadsTitle\">  <b>Reads</b>  </td>");
					addToTemplate ("<td nowrap align=\"right\" class=\"" + cssPrefix + "PostedTitle\">  <b>Last Post</b>  </td>")}
				else {
					addToTemplate ("<tr bgcolor=\"{headerColor}\">");
					addToTemplate ("<td colspan=\"6\" height=\"28\" width=\"100%\">");
					addToTemplate ("<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr>");
					addToTemplate ("<td>  <font color=\"{headerTextColor}\"><b>Recent Topics</b></font></td>");
					addToTemplate ("<td align=\"right\"><a href=\"{dayListUrl}\" style=\"color: {headerTextColor};\"><font size=\"-1\" color=\"{headerTextColor}\">Chronological View</font></a>  </td>");
					addToTemplate ("</tr></table>");
					addToTemplate ("</td>");
					addToTemplate ("</tr>");
					addToTemplate ("<tr bgcolor=\"{bgcolor}\">");
					addToTemplate ("<td nowrap align=\"center\" height=\"28\"> </td>");
					addToTemplate ("<td nowrap>  <b>Topic</b>  </td>");
					addToTemplate ("<td nowrap>  <b>Originator</b>  </td>");
					addToTemplate ("<td nowrap align=\"right\">  <b>Msgs</b>  </td>");
					addToTemplate ("<td nowrap align=\"right\">  <b>Reads</b>  </td>");
					addToTemplate ("<td nowrap align=\"right\">  <b>Last Post</b>  </td>")};
				addToTemplate ("</tr>");
				addToTemplate ("{messageList}")};
			template = string.trimWhiteSpace (template)};
		bundle { // get the item template
			if typeOf (adrItemTemplate) == addressType and defined (adrItemTemplate^) {
				itemTemplate = string (adrItemTemplate^)}
			else {
				on addToItemTemplate (s) {
					itemTemplate = itemTemplate + s + "\r"};
				if flCss {
					addToItemTemplate ("<tr bgcolor=\"{bgcolor}\" class=\"" + cssPrefix + "MessageRow\">");
					addToItemTemplate ("<td nowrap align=\"center\" height=\"28\" class=\"" + cssPrefix + "StatusIcon\">  <a href=\"{messageUrl}\">{statusIcon}</a>  </td>");
					addToItemTemplate ("<td nowrap class=\"" + cssPrefix + "MessageLink\">  <a href=\"{messageUrl}\">{subject}</a>  </td>");
					addToItemTemplate ("<td nowrap class=\"" + cssPrefix + "Author\">  {author}  </td>");
					addToItemTemplate ("<td nowrap align=\"right\" class=\"" + cssPrefix + "CountMessages\">  {messageCount}  </td>");
					addToItemTemplate ("<td nowrap align=\"right\" class=\"" + cssPrefix + "CountReads\">  {readCount}  </td>");
					addToItemTemplate ("<td nowrap align=\"right\" class=\"" + cssPrefix + "Posted\">  {lastPostTime}  </td>")}
				else {
					addToItemTemplate ("<tr bgcolor=\"{bgcolor}\">");
					addToItemTemplate ("<td nowrap align=\"center\" height=\"28\">  <a href=\"{messageUrl}\">{statusIcon}</a>  </td>");
					addToItemTemplate ("<td nowrap>  <a href=\"{messageUrl}\">{subject}</a>  </td>");
					addToItemTemplate ("<td nowrap>  {author}  </td>");
					addToItemTemplate ("<td nowrap align=\"right\">  {messageCount}  </td>");
					addToItemTemplate ("<td nowrap align=\"right\">  {readCount}  </td>");
					addToItemTemplate ("<td nowrap align=\"right\">  {lastPostTime}  </td>")};
				addToItemTemplate ("</tr>")};
			itemTemplate = string.trimWhiteSpace (itemTemplate)};
		bundle { // get the footer
			if typeOf (adrTemplateFooter) == addressType and defined (adrTemplateFooter^) {
				templateFooter = string (adrTemplateFooter^)}
			else {
				templateFooter = "</table>"};
			templateFooter = string.trimWhiteSpace (templateFooter)}};
	
	bundle { // replace color macros in the templates
		template = string.replaceAll (template, "{bgColor}", otherColor, false);
		template = string.replaceAll (template, "{headerColor}", headerColor, false);
		template = string.replaceAll (template, "{headerTextColor}", headerTextColor, false);
		
		itemTemplate = string.replaceAll (itemTemplate, "{bgColor}", otherColor, false);
		itemTemplate = string.replaceAll (itemTemplate, "{headerColor}", headerColor, false);
		itemTemplate = string.replaceAll (itemTemplate, "{headerTextColor}", headerTextColor, false);
		
		templateHeader = string.replaceAll (templateHeader, "{bgColor}", otherColor, false);
		templateHeader = string.replaceAll (templateHeader, "{headerColor}", headerColor, false);
		templateHeader = string.replaceAll (templateHeader, "{headerTextColor}", headerTextColor, false);
		
		templateFooter = string.replaceAll (templateFooter, "{bgColor}", otherColor, false);
		templateFooter = string.replaceAll (templateFooter, "{headerColor}", headerColor, false);
		templateFooter = string.replaceAll (templateFooter, "{headerTextColor}", headerTextColor, false)};
	
	add (templateHeader);
	
	local (msgData); // a temporary table for storing thread-message data
	mainResponder.discuss.getThreadData (@msgData, d, threadAliveDays, pta, adrInDgCallback);
	
	local (ct = sizeOf (msgData), oldestActiveThreadDate);
	oldestActiveThreadDate = date (clock.now () - (3600 * 24 * threadActiveDays));
	
	local (listHtml);
	for i = ct downTo 1 {
		local (s = itemTemplate, adrMsgData = @msgData[i]);
		
		bundle { // replace messageUrl
			local (messageUrl = msgReaderUrl + adrMsgData^.adrThread^.msgNum + "?mode=topic&y=" + yr + "&m=" + mo + "&d=" + day);
			s = string.replaceAll (s, "{messageUrl}", messageUrl, false)};
		bundle { // replace statusIcon
			if adrMsgData^.lastPost < oldestActiveThreadDate { // inactive thread
				s = string.replaceAll (s, "{statusIcon}", inactiveThreadIcon, false)}
			else { // active thread
				s = string.replaceAll (s, "{statusIcon}", activeThreadIcon, false)}};
		bundle { // replace authorIcon
			s = string.replaceAll (s, "{authorIcon}", userIcon, false)};
		bundle { // replace subject
			s = string.replaceAll (s, "{subject}", shortenString (adrMsgData^.adrThread^.subject), false)};
		bundle { // replace fullSubject
			s = string.replaceAll (s, "{fullSubject}", string.replaceAll (adrMsgData^.adrThread^.subject, "\"", """))};
		bundle { // replace author
			local (author = mainResponder.members.linkToMember (membershipGroup, adrMsgData^.adrThread^.member, hideEmail: true, adrMembers:adrMembers, useMap:flUseMappedMemberKeys));
			s = string.replaceAll (s, "{author}", author, false)};
		bundle { // add msg count
			s = string.replaceAll (s, "{messageCount}", adrMsgData^.msgCount, false)};
		bundle { // add read count
			s = string.replaceAll (s, "{readCount}", adrMsgData^.adrThread^.ctReads, false)};
		bundle { // add last post date
			s = string.replaceAll (s, "{lastPostTime}", adrMsgData^.lastPost, false)};
		bundle { // add post date
			s = string.replaceAll (s, "{postTime}", adrMsgData^.adrThread^.postTime, false)};
		
		listHtml = listHtml + s};
	
	bundle { // process the main template
		htmlText = templateHeader + template + templateFooter;
		bundle { // replace dayListUrl
			local (linkToDay = false, isLastDay = false);
			local (dateLinkUrl = pta^.urls^.discussHomePage);
			linkToDay = defined (adrCal^.[date.year (d)].[string.padWithZeros (date.month (d), 2)].[string.padWithZeros (date.day (d), 2)]);
			bundle { // is this the last day in the calendar?
				local (lastDate = mainResponder.calendar.getLastDay (adrCal));
				isLastDay = (lastDate == date.set (date.day (d), date.month (d), date.year (d), 0, 0, 0))};
			if linkToDay and (not isLastDay) {
				dateLinkUrl = dateLinkUrl + "$" + date.year (d) + "/" + string.padWithZeros (date.month (d), 2) + "/" + string.padWithZeros (date.day (d), 2)};
			dateLinkUrl = dateLinkUrl + "?mode=day&y=" + yr + "&m=" + mo + "&d=" + day;
			htmlText = string.replaceAll (htmlText, "{dayListUrl}", dateLinkUrl, false)};
		bundle { // replace date
			htmlText = string.replaceAll (htmlText, "{date}", mainResponder.localization.longDateString (d, pta), false)};
		bundle { // replace messageList
			htmlText = string.replaceAll (htmlText, "{messageList}", listHtml, false)}};
	
	<<add (templateFooter)
	
	return (htmlText)}



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.