This past weekend I decided to upgrade my Subtext blog to VS 2010 so I could finally rid my machine of VS 2008. After some small hiccups it was ready to rock, and thankfully the deployment to my server was entirely painless with WebDeploy.
So being in VS 2010 and having fully tested my deployment process it seemed like a good time to make a tweak to my Skin that Iâve been wanting to try for a while: showing âHero Shotsâ next to each post.
Iâm not really sure what they should be called, I just know Iâve heard the term hero shot a lot this year and it seemed to fit, but call it whatever you want
The idea is pretty simple: when viewing a list of posts (the home page, a specific tag, the archives) I want to show an image that helps illustrate the topic and allow for easier scanning with the eye.
As for implementation I wanted to allow some basic configuration of the hero shot from within Live Writer (or whatever you use to author posts). It goes something like this:
First I used NuGet to get HtmlAgilityPack â the absolute best way to work with an HTML string.
With that installed the change to Subtext was actually really simple. Within EntryList.cs I found where it was binding the Post Text and added the BindHeroShot() method seen below. BindHeroShot encapsulates that logic described above. The code below will respect Skins which do not use the PostImage, so this change should not affect any themes without a PostImage control declared.
private void BindPostText(RepeaterItemEventArgs e, Entry entry)
{
BindHeroShot(e, entry);
var postText = (Literal)e.Item.FindControl("PostText");
if(DescriptionOnly)
{
postText.Text = entry.HasDescription
? string.Format(CultureInfo.InvariantCulture, "<p>{0}</p>", entry.Description)
: ShowTruncatedBody(entry, 150);
}
else
{
postText.Text = entry.HasDescription ? entry.Description : entry.Body;
}
}
/// <summary>
/// Get the first image in a post to use as the "Hero Shot" on the list of entries
/// </summary>
private static void BindHeroShot(RepeaterItemEventArgs e, Entry entry)
{
var postImage = e.Item.FindControl("PostImage") as System.Web.UI.WebControls.Image;
if (postImage != null)
{
postImage.Visible = false;
var html = new HtmlDocument();
html.LoadHtml(entry.Body);
var noHero = html.DocumentNode.SelectSingleNode("//div[@id='no-hero']");
if (noHero != null)
return;
var img = html.DocumentNode.SelectSingleNode("//img[@id='hero']")
?? html.DocumentNode.SelectSingleNode("//img");
if (img != null)
{
postImage.Visible = true;
postImage.ImageUrl = HttpUtility.HtmlDecode(img.Attributes["src"].Value);
}
}
}
Thatâs actually all that had to be changed in Subtext. The rest of the changes take place in your current Skin.
Â
Below is the Repeater which shows each Post, the only thing I added to it was an <asp:Image ID=âPostImageâ/>
<asp:Repeater runat="server" ID="Entries" OnItemCreated="PostCreated">
<ItemTemplate>
<div class="post">
<div class="title">
<asp:HyperLink runat="server" ID="TitleUrl" />
<asp:HyperLink runat="server" ID="editLink" />
</div>
<div class="body">
<asp:Image runat="server" ID="PostImage" CssClass="post-hero-image" />
<asp:Literal runat="server" ID="PostText" />
<div class="clear">
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
Naturally I gave the PostImage a CSS Class so I could style it. I chose to float it right and give it max height and widths so it doesnât take up the entire post. You can of course tweak this any way you like â this part is entirely in your skin. Put the image wherever and style it how you like.
.post-hero-image
{
float: right;
margin: 0 0 6px 10px;
max-height: 200px;
max-width: 400px;
}
All in all pretty small tweaks and I actually like how it turned out. I think images next to the posts make it a lot easier to scan topics as Iâm scrolling down the page. If you agree and are using Subtext then hopefully this post will make it easy to add to your blog!
Â
Leave a Comment