August 2009 Archives

Binding an ASP.NET Repeater to Delicious (RSS) and Twitter (Atom) Feeds

Bookmark and Share

I recently had a client who wanted to pull in and display some Twitter and Delicious feeds on their web site. While I'd never done this before, it turns out that it's relatively simple to do by binding an ASP.NET Repeater control to the actual XML feed itself. I thought I'd share the code in case anyone else needs to do the same thing.

We start by creating our repeater objects, one for Twitter and one for Delicious. Since the feeds are different, and because Twitter uses Atom while Delicious uses RSS, you'll notice that the syntax is slightly different. There are also two Literal controls which we'll use for error catching in case either of the feeds ever has a problem.

// Recent Tweets

<%# (Container.DataItem as System.Xml.XmlNode)["content"].InnerText%>

<%# DateFormat((Container.DataItem as System.Xml.XmlNode)["published"].InnerText)%> by <%# TwitterName((Container.DataItem as System.Xml.XmlNode)["author"].ChildNodes[0].InnerText) %>

// Recent Bookmarks

<%# (Container.DataItem as System.Xml.XmlNode)["title"].InnerText%>

<%# DateFormat((Container.DataItem as System.Xml.XmlNode)["pubDate"].InnerText) %> by <%# (Container.DataItem as System.Xml.XmlNode)["dc:creator"].InnerText %>

In our code-behind file, all we're doing is creating an XmlDocument object and binding our repeaters to it. The Delicious feed works by default but since the Twitter feed uses Atom we need to invoke the XMLNamespaceManager object and load the Atom definition. The Try/Catch blocks just ensure that the feeds are working and if not, display the error message instead.

    public string twitterUrl = "http://search.twitter.com/search.atom?q=asp.net";
    public string deliciousUrl = "http://feeds.delicious.com/v2/rss/tag/aspnet?count=15";

    public System.Xml.XmlDocument doc;

    protected void Page_Load(object sender, EventArgs e)
    {
        doc = new System.Xml.XmlDocument();

        try
        {
            doc.Load(twitterUrl);
            XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
            nsMgr.AddNamespace("def", "http://www.w3.org/2005/Atom");
            rptTwitter.DataSource = doc.SelectNodes("/def:feed/def:entry[position()<=5]", nsMgr);
            rptTwitter.DataBind();
        }
        catch
        {
            rptTwitter.Visible = false;
            ltlTwitter.Visible = true;
        }

        try
        {
            doc.Load(deliciousUrl);
            rptDelicious.DataSource = doc.SelectNodes("/rss/channel/item[position()<=5]");
            rptDelicious.DataBind();
        }
        catch
        {
            rptDelicious.Visible = false;
            ltlDelicious.Visible = true;
        }

    }

Lastly, since the client wanted the dates to display as "3 hours ago" instead of the actual date and time, the following function handles that. There's also a very simple function to pull the Twitter user name.

    protected string DateFormat(string rawDate)
    {
        DateTime currentDate = DateTime.Now;
        DateTime itemDate = DateTime.Parse(rawDate);

        TimeSpan difference = currentDate - itemDate;

        string dateValue;
        if (difference.TotalSeconds <= 60)
        {
            dateValue = difference.Seconds + " seconds ago";
        }
        else if (difference.TotalMinutes <= 60)
        {
            dateValue = difference.Minutes + " minutes ago";
        }
        else if (difference.TotalHours <= 24)
        {
            dateValue = difference.Hours + " hours ago";
        }
        else
        {
            dateValue = difference.Days + " days ago";
        }

        return dateValue;
    }

    protected string TwitterName(string rawName)
    {
        return rawName.Substring(0, rawName.IndexOf(" "));
    }

That's it. Simple, but it works. You can download a zip of these files to use if you like. It also contains some very basic CSS and an OutputCache declaration so that the page isn't hitting external URLs on every single page load.

Credit where credit is due... I hit up others sites, blogs, and forum posts to get ideas for how to do this and pulled together bits and pieces from various places. So thanks to the development community at large for always sharing information like this. I hope this post helps someone else as well.

Sitefinity - The only CMS I've ever loved

Bookmark and Share

I've blogged a couple of times about why I don't like content management systems and their hidden costs. While I may not like them, every client I've had in the last year or two has asked for one. It appears that the days of websites being maintained by web developers are drawing to a close. So if every project requires a CMS then the only option is to find the best one and after using dozens of others, Sitefinity by Telerik is the hands-down winner for me.

My main gripe with content management systems is that they're not intuitive at all for the end users who actually maintain the site. Drupal, for example, can be a very robust and powerful system... but God help you when Betty from accounting tries to use it. Let's be honest... the people that end up maintaining a site aren't always properly-trained, tech-savvy individuals. Often, it's a person with no web experience and minimal computer skills. When that's the case, as it often is, the CMS should be as user-friendly as possible.

In my opinion, the user interface is where Sitefinity excels. Sure, it's got built-in forums, blogging capabilities, an events calendar, etc., etc., but what really sets it apart from other systems is it's drag-and-drop, click-to-edit, so-easy-a-monkey-could-do-it, interface. Compare the screenshots below of Drupal's basic interface with Sitefinity's and it's easy to see which will be easier to use.

Drupal

Sitefinity

While Sitefinity has a ton of features built in, the other great thing about it is that it's built as a native ASP.NET application so the learning curve is drastically reduced for Microsoft developers like me. The ability to build your own user controls and tap into the robust API also make it easy to extend the CMS functionality to suit any client's needs.

Lastly, Sitefinity CMS also has one of the best support teams I've ever worked with.  I've posted various messages in the support forums and the responses are always incredibly helpful and friendly. 

Bottom line... Sitefinity has a price tag of $899 and a feature set that rivals systems costing 20-30 times as much making it one of the best values around.  If you've looked at other CMS products and been disappointed, I highly recommend you give Sitefinity a try.

Free the web - Boycott Internet Explorer 6