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

system.verbs.builtins.xml.rss.renderWithTemplate

on renderWithTemplate (adrService, template, itemTemplate, serviceTitle=nil, maxItems=infinity, timeZone="PST") {
	<<Changes:
		<<12/23/01; 10:18:39 PM by JES
			<<Add itemText as a synonym for item.
		<<6/28/01; 2:58:23 PM by JES
			<<Restore the page table address, before exiting, when called in the context of the website framework.
		<<1/8/01; 11:54:00 AM by JES
			<<Render a service, given the address of the service, and two templates as strings.
				<<The templates are:
					<<template
						<<Macros:
						<<{title ()} -- The name of the channel.
						<<{updateTime ()} -- The time the channel was last updated.
						<<{items ()} -- The items as rendered through #rssItemTemplate.
						<<{channelLink (linetext, title=nil)} -- Generate a link to the URL specified by channelLink.
						<<{channelDescription ()} -- The description of the channel.
						<<{image (imageUrl=nil)} -- The channel's image if defined, or the empty string.
					<<itemTemplate
						<<Macros:
						<<{itemText ()} -- The text of a single item.
						<<{sourceTitle ()} -- The name of the source channel if defined, or this channel if not defined.
						<<{sourceLink (linetext, title=nil)} -- The URL of the source channel if defined, or this channel if not defined.
	local (adrTable = @adrService^.compilation);
	local (htmltext, adrItem);
	local (pageTable);
	
	on neuter (s) {
		s = string.replaceAll (s, "{", "{"); //neuter macros
		s = string.replaceAll (s, "'", "'");
		return (s)};
	
	bundle { //add a comment with the date/time
		htmltext = "<!-- RSS-to-HTML rendering done by UserLand on " + date.netstandardstring (clock.now ()) + " -->\r\n"};
	
	on channelTitle () {
		if serviceTitle == nil {
			return (neuter (adrtable^.channelTitle))};
		return (neuter (serviceTitle))};
	on updateTime () {
		local (timeString);
		local (day, month, year, hour, minute, second, nowday, nowmonth, nowyear);
		date.get (clock.now (), @nowday, @nowmonth, @nowyear, @hour, @minute, @second);
		date.get (adrService^.timeLastChange, @day, @month, @year, @hour, @minute, @second);
		
		if (nowday == day) and (nowmonth == month) and (nowyear == year) { //only show time
			minute = string.padwithzeros (minute, 2);
			if hour == 0 {
				timeString = "12:" + minute + "AM"}
			else {
				if hour < 12 {
					timeString = hour + ":" + minute + "AM"}
				else {
					if hour == 12 {
						timeString = hour + ":" + minute + "PM"}
					else {
						timeString = (hour - 12) + ":" + minute + "PM"}}};
			timestring = timeString + " " + timeZone}
		else {
			timeString = month + "/" + day + "/" + year};
		template = string.replaceAll (template, "{updateTime}", timeString, false);
		return (timeString)};
	on image (imageUrl = nil) {
		local (imageHtml = "");
		if imageUrl == nil {
			if defined (adrTable^.imageLink) { //the image is optional
				imageUrl = adrTable^.imageLink}};
		if imageUrl != nil {
			imageHtml = "<a href=\"" + imageUrl + "\"><img src=\"" + adrTable^.imageUrl + "\" border=\"0\" align=\"right\" vspace=\"3\"></a>"};
		return (imageHtml)};
	on sourceTitle () {
		if defined (adritem^.sourceChannelTitle) {
			return (neuter (adritem^.sourceChannelTitle))};
		return (neuter (adrtable^.channelTitle))};
	on channelLink (linetext = serviceTitle, title = nil) {
		if defined (adrtable^.channelLink) {
			local (titleText = "");
			if title != nil {
				titleText = " title=\"" + title + "\""};
			return ("<a href=\"" + neuter (adrtable^.channelLink) + "\"" + titleText + ">" + linetext + "</a>")};
		return (linetext)};
	on channelDescription () {
		if defined (adrtable^.channelDescription) {
			return (adrtable^.channelDescription)};
		return ("")};
	on sourceLink (linetext, title = nil) {
		if defined (adritem^.sourceChannelUrl) {
			local (titleText = "");
			if title != nil {
				titleText = " title=\"" + title + "\""};
			return ("<a href=\"" + neuter (adritem^.sourceChannelUrl) + "\"" + titleText + ">" + linetext + "</a>")};
		return (linetext)};
	on item () {
		return (neuter (adritem^.title))};
	on itemText () {
		return (item ())};
	on items () {
		local (itemsHtml);
		for i = sizeof (adrtable^.items) downto 1 {
			adrItem = @adrtable^.items[i];
			itemsHtml = itemsHtml + html.processMacros (itemTemplate, adrPageTable: @pageTable);
			maxItems--;
			if maxItems == 0 {
				break}};
		return (itemsHtml)};
	
	bundle { //render the channel
		new (tableType, @pageTable);
		pageTable.adrObject = adrService; // don't mask macro errors; pass them through to HTML
		local (oldPta);
		try {
			oldPta = html.getPageTableAddress ()};
		html.setPageTableAddress (@pageTable);
		htmltext = htmltext + html.processMacros (template, adrPageTable: @pageTable);
		html.deletePageTableAddress ();
		if oldPta != nil {
			html.setPageTableAddress (oldPta)}};
	
	return (htmltext)}
<<bundle //test code
	<<local (adrService = @myUserLandData.services.["http://www.ourfavoritesongs.com/users/dave@userland.com/rss/mindBombs.xml"])
	<<local (template = string (myUserLandData.prefs.templates.serviceTemplate))
	<<local (itemTemplate = string (myUserLandData.prefs.templates.serviceItemTemplate))
	<<webbrowser.displaytext (renderWithTemplate (adrService, template, itemTemplate))



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.