Adding an Image to a Community Server RSS Feed
I realised through the week that my RSS feed didn't include an image within the channel definition - and so I decided that I needed to do something about it :) After researching what was needed to get an image into a feed (this is at the top of the feed, not within a blog post) it was pretty straight forward to add it to not only my own feed, but tor make it configurable for anyone on the CrankyGoblin blogs site.
First, I needed to make the URL for the image a property of a blog. So in Weblog.cs (CommunityServer.Blogs.Components) I added this property:
public string RssImageUrl
{
get { return GetString("RssImageUrl", null); }
set { SetExtendedAttribute("RssImageUrl", value); }
}
Then I needed a way to set the value within the control panel. So to DescOptions.aspx (Web/ControlPanel/Blogs):
<DIV class="CommonFormFieldName">
<CP:helpicon id="Helpicon5" runat="server" Text="Enter the URL for the image you want embedded within your RSS feed."></cp:helpicon>
<CP:FormLabel id="FormLabel5" runat="server" Text="RSS Image URL" ControlToLabel="RssImageUrl"></CP:FormLabel>
</DIV>
<DIV class="CommonFormField">
<asp:TextBox id="RssImageUrl" Runat="Server" CssClass="ControlPanelTextInput" ></asp:TextBox>
</DIV>
And in the code behind for that page (DescOptions.aspx.cs) we have to get a handle on the new textbox, set the current value on the textbox, and update the value on the Weblog object on save.
Up near the top of the file, add a field and update the Page_Load event:
protected TextBox RssImageUrl;
private void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
TitleValidator.Text = ResourceManager.GetString("CP_Blogs_DescOptions_BlogTitle_Required");
Title.Text = this.CurrentWeblog.Name;
Description.Text = this.CurrentWeblog.Description;
News.Text = this.CurrentWeblog.News;
FavIcon.Text = this.CurrentWeblog.FavIcon;
RssImageUrl.Text = this.CurrentWeblog.RssImageUrl;
}
}
And in the SaveButton click event:
private void SaveButton_Click(object sender, EventArgs e)
{
if(Page.IsValid)
{
CurrentWeblog.Name = Title.Text;
CurrentWeblog.Description = Description.Text;
CurrentWeblog.News = News.Text;
CurrentWeblog.FavIcon = FavIcon.Text;
CurrentWeblog.RssImageUrl = RssImageUrl.Text;
Weblogs.Update(CurrentWeblog);
This takes care of saving and editing what image we'd like included in our Rss feed.
Now we need to update the actual RSS XML. To do it nice, I only wanted to modify the channel stuff when it was a blog, not anything else - the logical place is to do it in the WeblogRssWriter (CommunityServer.Blogs.Components, in the Syndication folder) - but to override that BuildChannel() method, first we need to make the base class's BuildChannel() method overridable. So first in BaseRssWriter (CommunityServer.Components, in the Syndication folder) I made the to overloads virtual:
protected virtual void BuildChannel(string link, string description)
{
BuildChannel(link,description,"en-US");
}
protected virtual void BuildChannel(string link, string description, string lang)
{
this.WriteElementString("title", Title);
this.WriteElementString("link", FormatUrl(link));
this.WriteElementString("description", description);
this.WriteElementString("dc:language", lang);
this.WriteElementString("generator", SiteStatistics.CommunityServerVersionVersionInfo);
}
And then back in WeblogRssWriter.cs I was able to add these two methods:
protected override void BuildChannel(string link, string description)
{
BuildChannel(link, description, "en-US");
}
protected override void BuildChannel(string link, string description, string lang)
{
base.BuildChannel(link, description, lang);
if (CurrentWeblog.RssImageUrl != null && CurrentWeblog.RssImageUrl != string.Empty && CurrentWeblog.RssImageUrl.Trim().Length > 0)
{
this.WriteStartElement("image");
this.WriteElementString("link", FormatUrl(link));
this.WriteElementString("title", Title);
this.WriteElementString("url", CurrentWeblog.RssImageUrl);
this.WriteEndElement();
}
}
Ok, so I know that one nasty if statement. But hey, I'm a VB guy, and I'm use to just testing If CurrentWeblog.RssImageUrl <> Nothing :)
And that's all there is to it! We now have the option to set a URL in for the feed:

And once it's set and your aggregator updates itself, the image comes up too:

A nice way to waste a Friday afternoon at work, if I do say so myself :)