March Madness swept over the nation a few weeks ago, and I am lucky enough to live in the hometown of one of the competitors for the NCAA champion- ship. Naturally, I wanted to support the home team, so I whipped up some images to replace my standard "welcome page" fare... including a slightly revised logo. Of course, doing so was a bit of a PITA. I'd considered creating some seasonal variations in image content and logo - maybe featuring art or photography that celebrates each of the seasons or something; logo changes for big football games and the holidays and the like. But doing all this "manually" currently requires the content be exchanged and the site be recompiled. Not so enticing, actually. Then along came the idea to let the site do the work of managing special event content automatically. All I'd need to do is create and upload the content, plus devise a mechanism to make it all appear automagically.... of course!! I'm going to assume that creation of the content -- that is, the idea that the content I'm going to display must first be created -- is obvious. So this is really all about the code and the XML that create the magical mechanism. In the broad strokes, the mechanism works by reading in the data, comparing the current date with the start and end dates of each event, and, if applicable, building a CSS file responsible for swapping the left side images, and modifying attributes of certain HTML controls to make them point to the new CSS and/or the special logo image. The XML ======== My schema takes this shape: For each event, we need a filename, a date range, and as many as three paths: one for a logo change and two for the images used currently along the left side -- one for the main image (goes on top), and one for the repeated part below. The Code ======== The code does four things each time a session is created: o Read the XML into a dataset object (and filter it into a dataview) o Compare the and data of each record from the dataview with the current date to determine whether a special event is currently underway o If an event is underway, build fresh CSS file containing the path information of any applicable images o Point a placeholder HtmlLink object to the path for the new CSS and modify the src attribute of the tag to point to the revised logo Because I'm having the code do this ONLY on the first web form a visitor sees, all of the code to run this located in the local class. First things first: We assign a dataset to hold our data, then create an XmlTextReader object is instantiated to read the data into the ds. I've probably described this several times in different how-to articles. So I'll skip it for this one. I can always step you through it. Next, call the AssembleSpecialEventStyle() subroutine from the Page_Load event. The sub does exactly what it says: If Not dsSpecialEvents Is Nothing AndAlso dsSpecialEvents.Tables.Count > 0 Then Try strToday = Date.Today 'create a dataview from the dataset Dim dvDataView As New DataView(dsSpecialEvents.Tables(0)) from here, a rowfilter is created and the data is sorted. At least, that's what should be happening. In truth, I'm having some trouble getting it to work filtering dates. Seems that the RowFilter is better suited to doing string comparisons. So I'll have to figure something else out there.... but the data is being sorted: 'sort on date (most recent at top) .Sort = "dateEnd DESC" Next up: Looping. If dvDataView.Count > 0 Then intUpperBound = dvDataView.Count - 1 For intCount = 0 To intUpperBound 'assign dataview columns to local variables . . . 'perform date comparisons. '- the end date must be AFTER the current date '- the beginning date must be ON or BEFORE the current date If (DateDiff(DateInterval.Day, CDate(strCurrentDateStart), CDate(strToday)) >= 0) And (DateDiff(DateInterval.Day, CDate(strToday), CDate(strCurrentDateEnd)) > 0) Then 'detect what's present in the dataset. If Len(strCurrentPathImageLogo) > 5 Then blnHasLogoImage = True If (Len(strCurrentPathImageTopBackground) > 5) And (Len(strCurrentPathImageBottomBackground) > 5) Then blnHasTopAndBottom = True Okay. Here's where I use a filestream object to build the .css file. 'we're in the zone for a special event. Build the CSS. If Len(strCurrentFilename) > 0 Then Dim objSW As StreamWriter Dim objFS As FileStream Dim linkCSS As HtmlControls.HtmlLink This HtmlLink points to a I planted on the master page. Dim imgHeader As HtmlControls.HtmlImage This image is my logo image, also planted on the master page. Dim strCssFilePath As String = String.Empty This will be the full .MapPath strCurrentFilename = Trim(strCurrentFilename) & ".css" strCssFilePath = Server.MapPath(strCssPath & strCurrentFilename) Now, I want to make sure I have the latest data for this event. I'll do that by deleting whatever .css is already present with this event name and create a new one. So, out with the old... If blnHasTopAndBottom Then 'if this .css file already exists, delete it If IO.File.Exists(strCssFilePath) Then File.Delete(strCssFilePath) End If ... and in with the new: objFS = New FileStream(strCssFilePath, FileMode.Create, FileAccess.ReadWrite) objSW = New StreamWriter(objFS) With the streamwriter object open, it's just like Response.Write in VBSCript. You just... write stuff. Just remember to FLUSH the object BEFORE closing it. With objSW .Write(Chr(13)) .Write("#divImageInner {" & Chr(13)) .Write(" background-image:url(" & strCurrentPathImageTopBackground & ");" & Chr(13)) .Write("}" & Chr(13)) .Write(Chr(13)) .Write("#divImageOuter {" & Chr(13)) .Write(" background-image:url(" & strCurrentPathImageBottomBackground & ");" & Chr(13)) .Write("}" & Chr(13)) .Write(Chr(13)) .Write("/*Generated " & Now.ToShortDateString() & ". Valid from " & strCurrentDateStart & " until " & strCurrentDateEnd & " */" & Chr(13)) .Flush() .Close() End With objFS.Close() And that's it. Your new .css is written! Next, we need to send the path of the new .css to the : 'point the special link to the path of the new file linkCSS = Me.Master.FindControl("linkStyleSpecialEvent") With linkCSS .Href = strCssPath & strCurrentFilename .Visible = True End With 'tidy up objSW = Nothing objFS = Nothing End If 'blnHasTopAndBottom = True If blnHasLogoImage Then 'now point the header image to the path of the new file imgHeader = Me.Master.FindControl("imgLogoHeader") imgHeader.Src = strCurrentPathImageLogo End If 'blnHasLogoImage End If 'Len(strCurrentFilename) > 0 'bail Exit For That's the majority of the substance. Below this point, we have the companion Else condition to the If in which a date comparison is formed. We're going to use the opportunity to whack any special event .css files to keep things tidy. Else 'erase any files in the special event subdirectory strOldFile = IO.Directory.GetFiles(Server.MapPath(strCssPath)) Dim intCnt As Int32 For intCnt = 0 To strOldFile.Length IO.File.Delete(strOldFile(intCount)) Next Erase strOldFile End If '(intToday <= intCurrentDateStart) And (intToday >= intCurrentDateEnd) Next 'For intCount = 0 To intUpperBound And I'll do the same thing here -- under the Else to the original If. Else 'dvDataView.Count > 0 'erase any files in the specialevent subdirectory . . . (same code as above) End If 'dvDataView.Count > 0 Catch ex As Exception End Try '(Try) End If 'Not dsSpecialEvents Is Nothing AndAlso dsSpecialEvents.Tables.Count > 0 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