Extending SubText to report Future Posts
Since I am making so much use of future posts recently, I decided that it would be interesting to have a sidebar that shows the future posts. The problem is that I really don’t want to mess around with SubText.
This is not a slight against SubText, it has served me well for a long time. It is simply that for what I wanted, the number of steps that I would have to go through is way too long:
- Get the relevant source
- Compile it on my machine
- Figure out SubText’s architecture and where I should make my changes
- Upload a new version of the blog engine
It is possible, but it just take too long. Moreover, it would most certainly break the next time that I would update SubText, because I would forget all about it.
But it is not the only way to get stuff done, however. Here is my solution:
Update: I actually had a bug here related to time zone handling, fixed now.
Update 2: I used the 3.5 TimeZone semantics for this, but my server is running 2.0, use an okay hack instead. And fixed potential issue with < & > in the titles.
<%@ Page Language="C#" %> <%@ OutputCache Duration="60" VaryByParam="None" %> <%@ Import Namespace="System.Data.SqlClient" %> <%@ Import Namespace="System.Configuration" %> <ul> <% string connectionString = ConfigurationManager.ConnectionStrings["subtextData"].ConnectionString; using(SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using(SqlCommand cmd = connection.CreateCommand()) { cmd.CommandText = @" select top 15 Id, DateSyndicated, Title from subtext_Content where DateSyndicated > @nowIsrael order by DateSyndicated "; DateTime nowIsrael = DateTime.UtcNow.AddHours(3); cmd.Parameters.AddWithValue("nowIsrael",nowIsrael); using(SqlDataReader reader = cmd.ExecuteReader()) { if(reader.HasRows == false) { %><li>Queue is empty</li><% } while(reader.Read()) { DateTime dateSyndicated = (DateTime)reader["DateSyndicated"]; string title = (string) reader["Title"]; string formattedSyndication; TimeSpan timeLeft = dateSyndicated - DateTime.Now; if (timeLeft.Days > 7) formattedSyndication = timeLeft.Days / 7 + " weeks " + timeLeft.Days % 7 + " days"; else if (timeLeft.Days > 0) formattedSyndication = timeLeft.Days + " days"; else if (timeLeft.Hours > 0) formattedSyndication = timeLeft.Hours + " hours"; else if (timeLeft.Minutes > 0) formattedSyndication = timeLeft.Minutes + " minutes"; else formattedSyndication = "In a moment"; %> <li><%= formattedSyndication %> <br /> <%= Server.HtmlEncode(title) %></li> <% } } } } %> </ul>
And then it was just a matter of changing the template to include the following JavaScript:
$('#futurePosts').load('http://ayende.com/Blog/FuturePosts.aspx');
And that is it. It works, it is safe, it can’t really break anything, and it will probably survive blog upgrades.
Comments
...until you put < in a title like "Using List <t correctly" ;-)
[)amien
Line 20: TimeZoneInfo israelTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Israel Standard Time");
Line 21: DateTime nowIsrael = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, israelTimeZone);
bwahaha
nice that we can take a peek at the future post titles too :)
Damien,
Fixed
But I had only 2 of those out of 4K+
Hmm, currently two posts are showing as appearing "In A Moment", and have been for several minutes.
Thanks, fixed.
Comment preview