2
Aug
2006
Breaking Down the CS Post Date
While I don't think there's anything terribly fancy about the particular skin I've put together, there is one part of it that required some research, and I've had a couple of questions about it already: the post dates. I've seen this particular style of date (the big one, to the left of this paragraph) on a few other blogs, and wanted it for myself. The problem is that Community Server doesn't give you a particularly handy way to get at this information, so you have to do a bit of extra work to get it.
If you open up Skin-EntryView.ascx in the default skin, you will see the following:
<asp:Literal id="EntryDesc" Text="Perma Link" Runat="server" />
This is the control into which CS embeds the post date, and it is the easiest place from which to extract that information. For this skin, I’ve created the following markup to hold the date information:
<span class="entry-date">
<asp:Label ID="entryDay" CssClass="entry-day" runat="server" />
<asp:Label ID="entryMonth" CssClass="entry-month" runat="server" />
<asp:Label ID="entryYear" CssClass="entry-year" runat="server" />
</span>
The Label entryDay will hold the day, entryMonth the month, and entryYear the year. To populate these controls, I handle the PreRender event on the page. In this method, I parse the date into its constituent parts and use that information to fill the Labels. Once done, you can hide the EntryDesc Literal if you no longer need it.
<script runat="server">
protected void Page_PreRender( object sender, EventArgs e )
{
DateTime entryDate = DateTime.Parse( EntryDesc.Text );
entryDay.Text = entryDate.Day.ToString();
entryMonth.Text = entryDate.ToString( "MMM" );
entryYear.Text = entryDate.Year.ToString();
}
</script>
Note: To be safe, you’d probably want to wrap the DateTime.Parse() in a try-catch block, or use DateTime.TryParse() if you are on ASP.NET 2.0. I was on ASP.NET 1.1 when I wrote this code and I have a fair amount of faith that CS will actually provide me with a valid date.
This works quite well for Skin-EntryView.ascx. Unfortunately, It’s not quite as simple for Skin-EntryList.ascx. Because you’re handling multiple date controls now, sorting out all of the dates in PreRender isn’t really a viable option. In this case, the simplest and most straightforward approach is to handle the ItemDataBound event of the Repeater control that generates the entries. We use the same markup as before, but this C# code instead:
<script runat="server">
protected void entryItems_MyItemDataBound( object sender, RepeaterItemEventArgs e )
{
WeblogPost entry = e.Item.DataItem as WeblogPost;
if ( entry != null )
{
Label entryDay = e.Item.FindControl( "entryDay" ) as Label;
if ( entryDay != null )
entryDay.Text = entry.UserTime.Day.ToString();
Label entryMonth = e.Item.FindControl( "entryMonth" ) as Label;
if ( entryMonth != null )
entryMonth.Text = entry.UserTime.ToString( "MMM" );
Label entryYear = e.Item.FindControl( "entryYear" ) as Label;
if ( entryYear != null )
entryYear.Text = entry.UserTime.Year.ToString();
}
}
</script>
The line to note here is WeblogPost entry = e.Item.DataItem as WeblogPost. This gets you the WeblogPost instance that corresponds to the entry currently being rendered. WeblogPost represents a single blog post and contains all of the relevant information that belongs to it. You can learn more about this class by perusing the CS SDK. The WeblogPost’s UserTime property contains the date and time at which the entry was posted, and we parse this DateTime in the same way that we did on Skin-EntryView.ascx. Also note that, because we are assigning values to controls inside of a Repeater, we must use the FindControl() method to get references to them instead of referencing them directly by ID.