I wanted to display my Twitter status on the side of this blog. To do this, I created a small custom Sitefinity ASP.NET user control. I'm making it available to everyone below. To add this control to your Sitefinity web site, simply follow the instructions below. (Click here for basic information about extending Sitefinity with ASP.NET user controls.)
Create & Install the Twitter Status ASP.NET User Control
1. Create ~/UserControls/TwitterStatus.aspx:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TwitterStatus.ascx.cs" Inherits="UserControls_TwitterStatus" EnableViewState="false" %>
<div class="TwitterStatus">
<h2>Twitter - <a id="Link" href="http://twitter.com/sitefinitywatch" runat="server">more</a></h2>
<p><asp:Literal ID="Status" runat="server" /></p>
</div>
2. Create ~/UserControls/TwitterStatus.aspx.cs:
using System;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
[DefaultProperty("TwitterRssUrl")]
public partial class UserControls_TwitterStatus : System.Web.UI.UserControl
{
private string _twitterrssurl;
private double MinutesCached = 30;
private string TwitterUrl;
private string TwitterStatus;
/// <summary>
/// Gets & sets the Twitter RSS URL
/// </summary>
[Category("Main")]
[Description("The URL to the Twitter RSS")]
public string TwitterRssUrl
{
get { return _twitterrssurl; }
set { _twitterrssurl = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (TwitterRssUrl != "" && TwitterRssUrl != null)
{
GetTwitterStatus();
Link.HRef = TwitterUrl;
Status.Text = TwitterStatus;
}
}
/// <summary>
/// Get the Twitter status from the cache file or the Twitter RSS feed.
/// </summary>
private void GetTwitterStatus()
{
// If our Twitter Status cache isn't expired, use it. Otherwise fetch the status from the RSS feed.
// Make an exception for the Sitefinity page editor. If we're using the editor NEVER use the cache.
if (Cache["TwitterUrl"] == null || Cache["TwitterStatus"] == null || Request.QueryString["cmspagemode"] == "edit")
{
GetTwitterRss();
}
else
{
GetCachedTwitterStatus();
}
}
/// <summary>
/// Get the Twitter status from the RSS feed.
/// </summary>
private void GetTwitterRss()
{
WebRequest _request = HttpWebRequest.Create(TwitterRssUrl);
_request.Timeout = 5000;
_request.Method = "GET";
try
{
// Get the Twitter RSS via a HttpWebRequest and read the ouput as a string
StreamReader reader = new StreamReader(_request.GetResponse().GetResponseStream());
string rss = reader.ReadToEnd();
// Full XML parsing was overkill (in my opinion); we only need two strings and
// RegEx will get it done quicker.
// Get the Twitter URL from the RSS Feed (Used for the More link)
Match match = Regex.Match(rss, @"<link>(.+?)</link>");
TwitterUrl = match.Groups[1].Value;
// Get the first Tweet from the RSS
match = Regex.Match(rss, @"<item>\s*?<title>(.+?)</title>");
TwitterStatus = FormatTweet(match.Groups[1].Value);
// Cache the Twitter Status
CacheTwitterStatus();
}
catch (Exception e)
{
// Twitter is probably down or the Twitter RSS URL is bad.
TwitterStatus = "Cannot connect to Twitter.";
}
}
/// <summary>
/// Saves the Twitter status to the cache text file.
/// </summary>
private void CacheTwitterStatus()
{
Cache.Insert("TwitterUrl", TwitterUrl, null, DateTime.Now.AddMinutes(MinutesCached), TimeSpan.Zero);
Cache.Insert("TwitterStatus", TwitterStatus, null, DateTime.Now.AddMinutes(MinutesCached), TimeSpan.Zero);
}
/// <summary>
/// Loads the cached Twitter status from the cache text file.
/// </summary>
private void GetCachedTwitterStatus()
{
TwitterUrl = Cache["TwitterUrl"].ToString();
TwitterStatus = Cache["TwitterStatus"].ToString();
}
/// <summary>
/// Removes the Twitter username from the beginning of the Tweet. Also finds any links in
/// the tweet and puts an anchor tag around the URL.
/// </summary>
/// <param name="TweetObject">The Tweet</param>
/// <returns></returns>
private string FormatTweet(object TweetObject)
{
string tweet = TweetObject.ToString();
// Remove Twitter username from the beginning of the tweet.
tweet = Regex.Replace(tweet, @"^.+?: ", "");
// Make URLs found in the tweet into Hyperlinks
string urlpattern = @"((?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~/|/)?(?#Username:Password)(?:\w+:\w+@)?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?)";
tweet = Regex.Replace(tweet, urlpattern, "<a href=\"$1\">$1</a>");
return tweet;
}
}
3. Add a mapping to this control in the <toolboxControls> of your ~/web.config file:
<add name="Twitter Status" section="My Controls" url="~/UserControls/TwitterStatus.ascx" />
4. Add some stylesheets to visually style the Twitter Status box. Here is the style I'm using:
.TwitterStatus
{
padding: 10px;
background: #DAECF4;
margin-bottom: 20px;
}
I would recommend adding your styles to the ~/App_Themes theme your web site is using.
Place the Twitter Status control on your Sitefinity Page (or Template)
You can now login to Sitefinity and edit your Sitefinity pages (or templates). The Twitter Status control will be in your Controls Toolbox in the My Controls category. Drag & drop an instance of this control onto your Sitefinity page and click Edit.
Type the URL to your Twitter RSS; this is different than your Twitter URL. Click I'm Done and save your changes. If the Twitter RSS URL is correct, the current status should be displayed.
Feedback is welcome!