I got to thinking about this automagic changing background and logo
business, and figured the next step would be to add text to the "latest 
news" section of the front page that would appear and leave with the 
changing background. 

I decided the way to implement this was to:

1) modify the special events XML file to include the summary text 
   I wanted, 
2) have the code generate a separate XML doc, using the standard 
   schema, which contains the new text
3) read this doc into the dataset after the dataset has been loaded
   with everything else. 

Now that the dataset has been "doped" with the new text, that new text
will display just like all of the other eligible content.

4) destroy the XML doc that contained the new text after the content
   is displayed

That way the "doped" content appears on demand only, and is 
not retained outside of the special event context.

I'm careful here to differentiate between "doc" and "file".
I initially instantiated an actual XML file via IO, and found that
had a considerable impact on the speed of the page load. A few days
later I modified the code to create the XML in a memory stream object.
The result: far faster code. I left the original, IO-based code in
place and simply overloaded it with the stream-based code. Even though
I don't need to, I pass the memory stream into the latter simply to be
able to visually differentiate between the two versions. The example
code below is of the stream-based version.

~~~~~

Before these changes are made, here's a high-level overview of how
the "worker code" that builds the "latest news" feature looks.

--	Gets a count of the "latest news" content summaries for display

--	Creates a dataview and filters it for "active" content

	-	if the count is 0, it grabs the latest pubdate and adds 
		that date to the filter, so the latest content (even 
		though it's old), will be displayed

--	Loops to build the HTML surrounding the content

--	Updates the RSS content to match

These mods are going to change this somewhat, by prepending and appending
new steps.

~~~~~

1) Modify the Special Events XML File

All I really did here was change the schema a bit to support the inclusion
of text. Simply, in each <event> node, there's a new node called 
<latestNewsText>. Naturally, I had to place this node in every <event>.

~~~~~

2) Have the Code Generate a Separate XML File

Instantiating the new XML as a memory stream required creating a few
module-level variables: 

 	Public blnHasStream As Boolean = False
	Public stmXML As New IO.MemoryStream
 	Public stmWriter As New IO.StreamWriter(stmXML, Text.Encoding.UTF8)

Back in my AssembleSpecialEventStyle() sub, I created a pair of new
variables:

  	'2009-09-12
        Dim strCurrentText As String = String.Empty
        Dim blnHasText As Boolean = False

and added this If-Then statement to set the value for the Boolean,
grouped with the others:

	If Len(strCurrentText) > 0 Then blnHasText = True

Later, down in the decision logic, a call to a sub if that Boolean 
is true:

  	If blnHasText = True Then
        	Call addSpecialEventText(strCurrentText, stmXML)
        End If

.... and the sub it calls:

	Private Sub AddSpecialEventText(ByVal strCurrentText As String, ByVal stmXML As IO.MemoryStream)
		Dim sb As New StringBuilder()
		Dim strXML As String = String.Empty
	        Dim strDate As String = String.Empty
	        Dim strAuthor As String = "gk@halfgk.com"
	        Dim strPubDate As String = String.Empty
	
	        'format date and pubDate Strings
	        strDate = common.displayDate(Now.Year, Now.Month, Now.Day, common.DateFormat.ForwardSlashDelimitedMMDDYYYY)
	        strPubDate = common.displayDate(Now.Year, Now.Month, Now.Day, common.DateFormat.YYYYMMDD)
	
		With sb
			.Append("<?xml version=""1.0"" encoding=""utf-8"" ?>")
			.Append("<specialevent>")
			.Append("<item>")
			
			'date node.
			.Append("<date>" & strDate & "</date>")
			
 			'summary node.
            		.Append("<summary><![CDATA[" & strCurrentLatestNewsText & "]]></summary>")

... continue on with the other nodes to match the schema of the other 
content xml docs...

			'close
			.Append("</item>")
			.Append("</specialevent>")
			
			strXML = .ToString()

		End With        'With sb
		
		With stmWriter
		    .WriteLine(strXML)
		    .Flush()
		End With

		'start the memory stream at 0 so it can be read from the beginning
		stmXML.Position = 0
		
		
		'set boolean
		blnHasStream = True
	
	End Sub

~~~~~

3) Read This File into the DataSet

I need a way to read the new file into the dataset. This sub accomplishes that.

	Private Sub ReadSpecialEventTextXML(ByVal stmXML As IO.MemoryStream)
        	'2009-09-14 reads in the special event XML as a memory stream object.

        	Dim rdrSpecialEventText As New XmlTextReader(stmXML)

	        Try
	            'import the reader's data into the dataset
	            dsDataSet.ReadXml(rdrSpecialEventText)
	
	        Catch ex As Exception
	            . . .
	
	        Finally
	            'close the reader
	            If Not rdrSpecialEventText.ReadState = ReadState.Closed Then
	                rdrSpecialEventText.Close()
	            End If
	        End Try
	
	        rdrSpecialEventText = Nothing
	
	    End Sub

~~~~~
4) Destroy the XML File

	 Private Sub DeleteSpecialEventTextXML(ByVal stmXML As IO.MemoryStream)
		'2009-09-14 for memory stream
		
		With _stmWriter
		    .Close()
		    .Dispose()
		End With
		
		With _stmXML
		    .Close()
		    .Dispose()
		End With

For steps 3) and 4), we simply add calls to these subs in the code that
does the work of building the display. 

The call to read the XML file is placed before the dataview is created
and filtered:

		'Latest News

		'if there's text associated with the special event, grab it and append it to the dataset
		If _blnHasStream = True Then
	    		Call ReadSpecialEventTextXML(stmXML)
		End If

		'2009-07-21 Get the count first. This will allow us to know whether there are any posts within the time limit (15 days) to display. Measures are taken below if the count is zero.
            	intLatestNewsCount = GetLatestNewsCount()

		If Not dsDataSet Is Nothing AndAlso dsDataSet.Tables.Count > 0 Then
		
			'create a dataview from the dataset
			Dim dvDataView As New DataView(dsDataSet.Tables(0))
			
			With dvDataView
			    'filter out the inactive items
			    .RowFilter = "active = 'True' "
		
		. . .

The call to delete happens at the end of the sub, when other tidying is done:

	  'tidy up
        '   - this whacks the XML doc created to inject the special events text into "latest news."
	If blnHasStream = True Then
        	Call DeleteSpecialEventTextXML(stmXML)
	End If

        sb = Nothing

So, at a higher level, the flow of the worker code now looks like this:

--	If the special events text XML doc exists, it is read

--	Gets a count of the "latest news" content summaries for display

--	Creates a dataview and filters it for "active" content

	-	if the count is 0, it grabs the latest pubdate and adds 
		that date to the filter, so the latest content (even 
		though it's old), will be displayed

--	Loops to build the HTML surrounding the content

--	Updates the RSS content to match

--	If the special events text XML doc exists, it is deleted

~~~~~

There is one other thing, though. I made some modifications to my
dateformat subroutines to support this. I actually copied and
overloaded the original, and added a means to specify which format
to use. I also added a new format ("YYYYMMDD") that I use as a 
standard in my XML for sequencing. I should update
http://www.halfgk.com/howto_dateformat.txt to reflect that.


~~~~~

That should be it for now! Contact me using the site's contact form if 
you have questions. Feel free to use the code in your projects. A shout
out in your project would be thoughtful. Also, drop me a line and let me
know how you might have tweaked things to better suit your needs. 
Finally, I wouldn't profess to be THE expert on matters represented in
my code -- so drop me a line if you have constructive suggestions, too. 
I'd like to hear from you!
  

Best,

halfgk


copyright 2009 halfgk.com