Stefan Goßner

Senior Escalation Engineer for SharePoint (WSS, SPS, MOSS, SP2010) and MCMS

Blogs

Creating a RSS Feed for your MCMS Web site

  • Comments 19
  • Likes

Yesterday I received the question to add an RSS feed to one of our internal MCMS Web sites.

At that moment I did not know more about RSS as that this blog has an RSS feed to be able to keep updated with my writings. ;-)

So I searched for a document explaining what RSS is and how it works. I found this very easy to read document which is a very good starter when trying to write an RSS feed: http://www.feedvalidator.org/docs/rss2.html

To sum up, an RSS feed is very similar to a MCMS summary page. Major differences: the content is served as XML rather than html. but Html can be embedded if propertly encoded.

As the RSS feed should give information about recent changes to the MCMS site I used the NewPosting method of the searches object and returned a summary of the content.

To integrate the RSS feed nicely into the site I created an RSS channel below the root of the Web site and bound the ASP.NET Web form that generates the Feed as Channel Rendering Script to this channel.

Here is the actual implementation:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.ContentManagement.Publishing;
using Microsoft.ContentManagement.Publishing.Extensions.Placeholders;

namespace MyCMSproject
{
   
/// <summary>
    /// Summary description for RSS.
    /// </summary>

   
public class RSS : System.Web.UI.Page
    {

        private
string GetPostingSummary(Posting p)
        {
            if (p.Placeholders["Summary"] != null)
            {
                HtmlPlaceholder phSummary = (HtmlPlaceholder)p.Placeholders["Summary"];
                return phSummary.Html;

            }
            else
            {
                return p.Description;
            }
        }

        private string GenerateRssXml()
        {
            MemoryStream mem = new MemoryStream();
            XmlTextWriter Xmlwriter = new XmlTextWriter(mem, Encoding.UTF8);

            Xmlwriter.WriteStartElement("rss");
            Xmlwriter.WriteAttributeString("version","2.0");
            Xmlwriter.WriteStartElement("channel");

            Xmlwriter.WriteElementString("title","Title of your Web site");
            Xmlwriter.WriteElementString("link","http://www.yourWebsite.com";
            Xmlwriter.WriteElementString("copyright","© Your Corporation. All rights reserved.");
            Xmlwriter.WriteElementString("description","Description of your Web site");
            Xmlwriter.WriteElementString("managingEditor","email of your responsible Editor");
            Xmlwriter.WriteElementString("webMaster","email of your responsible Webmaster");
            Xmlwriter.WriteElementString("generator","Stefan's RSS feeder 1.0.0.0");

            PostingCollection pc = CmsHttpContext.Current.Searches.NewPostings(20);
            pc.SortByLastModifiedDate();

            
foreach (Posting p in pc)
            {
                
if (p.Path.ToLower().StartsWith("/channels/publicchannel"))     // I don't want include all channels here
                {
                    Xmlwriter.WriteStartElement("item");
                    Xmlwriter.WriteElementString("title",p.DisplayName);
                    Xmlwriter.WriteElementString("link","http://www.yourWebsite.com"+p.Url);

                    // date needs to be in this format!

                    Xmlwriter.WriteElementString("pubDate",p.LastModifiedDate.ToString("r"));  

                    // guid needs to have the isPermaLink=false attribute for some rss readers

                    Xmlwriter.WriteStartElement("guid");  
                    Xmlwriter.WriteAttributeString("isPermaLink","false");
                    Xmlwriter.WriteRaw(p.Guid);
                    Xmlwriter.WriteEndElement();

                    Xmlwriter.WriteElementString("description",GetPostingSummary(p));
                    Xmlwriter.WriteElementString("author",p.CreatedBy.ClientAccountName);
                    Xmlwriter.WriteEndElement();
                }
            }

            Xmlwriter.WriteEndElement();
            Xmlwriter.WriteEndElement();

            Xmlwriter.Flush();
            mem.Position = 0;
            StreamReader reader = new StreamReader(mem);
            return reader.ReadToEnd();
        }

        private void Page_Load(object sender, System.EventArgs e)
        {
            Response.ContentType = "text/xml; charset=utf-8";    // its Xml, not Html
        }

        protected override void Render( HtmlTextWriter writer)
        {
            writer.Write(GenerateRssXml());
       
}

        
#region Web Form Designer generated code
        
override protected void OnInit(EventArgs e)
        {
            
//
            
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
            
//
            
InitializeComponent();

            
base.OnInit(e);
        }

        
/// <summary>
        
/// Required method for Designer support - do not modify
        
/// the contents of this method with the code editor.
        
/// </summary>
        
private void InitializeComponent()
        { 
            
this.Load += new System.EventHandler(this.Page_Load);
        }
        
#endregion

    }
}

I decided to use the last modified date as published date as this was our business requirement. If you like you can also choose the creation date instead.

The code above is pretty simple. You might have to adjust it to meet your requirements if different placeholders on different templates should be returned.

As you can see MCMS makes it easy for you to create an RSS feed for content syndication or for whatever reason your would like to have this nice feature.

 

Comments
  • Using string concatenation to create XML files is a sure fire way to create invalid XML. For example, I don't see any code that handles escaping special characters in XML [such as the ampersand] if they appear in title or link elements of the RSS feed.

  • Thanks for this useful hint! I corrected the bug. I know there are better methods to do the Xml coding.

  • Actually, apart from the ampersand, you have a lot of other mucky-muck to deal with (such as greater than signs, etc). I suggest you something like the XmlWriter

  • Ok, now using XmlTextWriter.

  • Take Outs for 4 April 2004

  • Nice to see the code - but if you dont want to get your hands dirty there is a free CMS RSS component at http://www.cmsrss.com

  • There is also a very nice generic library for creating RSS Xml

  • http://www.rssdotnet.com/

    or click on my name above

  • Nice code.

  • Great example, but I found a minor bug.

    if (p.Path.ToLower().StartsWith("/channels/publicChannel")) will never be true as your ToLower() != "publicChannel".

    Just a heads up, thanks for all your work with CMS and the community.

  • Hi Scott,

    you are right, that's a bug. :-)
    I just corrected it.

    Cheers,
    Stefan.

  • Please, Any one can help me?
    Any one can translate this example to VB.Net?
    Thaxns and sorry for my question, but i don know the C#.
    Thanxs again.

  • Hi Jesus,

    please use the hints in the following article to translate to VB.NET:
    http://blogs.msdn.com/stefan_gossner/archive/2004/04/06/108512.aspx

    Cheers,
    Stefan.

Raw Html Fix