What is this post about?

If you have a blog, or a site with news articles, or even a podcast site, you will probably need to have an RSS feed set up.

And if you use Umbraco CMS then this is the post for you. In this post I give you a simple template to start using for your own feed. It's very simple and straight forward. It should be a simple case of copy > paste > edit > save > job done.

What do I need to do?

  • Just copy this code and paste it into a new template.
  • Edit the values at the top to be relevant to your site.
  • Create a doc type which uses the new template.
  • Allow this new doc type under the home page and create a page using it, called '/feed' or '/rss'
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = null;
    Response.AddHeader("Content-Type", "text/xml");

    const string DATE_FORMAT = "ddd, dd MMM yyyy hh:mm:ss zzz";
    const string FEED_TITLE = "codeshare.co.uk Blog";
    const string FEED_DESCRIPTION = "codeshare.co.uk Blog | Code examples and knowledge sharing";
    const string CREATOR_NAME = "Paul Seal";
    const string CATEGORY = "Web Development";
    const string UPDATE_PERIOD = "daily";
    const int UPDATE_FREQUENCY = 1;
    const string LANGUAGE = "en-US";
    const string HOME_PAGE_DOC_TYPE_ALIAS = "home";
    const string FEED_PARENT_DOC_TYPE_ALIAS = "blog";
    const string ARTICLE_DOC_TYPE_ALIAS = "blogPost";
    const string ARTICLE_TITLE_PROPERTY_ALIAS = "pageTitle";
    const string ARTICLE_DATE_PROPERTY_ALIAS = "blogPostDate";
    const int CONTENT_PREVIEW_LENGTH = 500;

    IPublishedContent homePage = Model.Content.AncestorOrSelf(1).DescendantsOrSelf().Where(x => x.DocumentTypeAlias == HOME_PAGE_DOC_TYPE_ALIAS).FirstOrDefault();
    IPublishedContent feedParentPage = homePage.Descendants().Where(x => x.DocumentTypeAlias == FEED_PARENT_DOC_TYPE_ALIAS).FirstOrDefault();
    IEnumerable<IPublishedContent> feedItems = feedParentPage.Descendants().Where(x => x.DocumentTypeAlias == ARTICLE_DOC_TYPE_ALIAS && x.IsVisible()).OrderByDescending(x => (DateTime)x.GetPropertyValue(ARTICLE_DATE_PROPERTY_ALIAS));
    DateTime lastBuildDate = feedItems.Max(x => x.UpdateDate);
    string siteUrl = homePage.UrlWithDomain();
    string feedUrl = ((IPublishedContent)CurrentPage).UrlWithDomain();
}

<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:slash="http://purl.org/rss/1.0/modules/slash/">

    <channel>
        <title>@FEED_TITLE</title>
        <atom:link href="@feedUrl" rel="self" type="application/rss+xml" />
        <link>@feedParentPage.UrlWithDomain()</link>
        <description>@FEED_DESCRIPTION</description>
        <lastBuildDate>@lastBuildDate.ToString(DATE_FORMAT)</lastBuildDate>
        <language>@LANGUAGE</language>
        <sy:updatePeriod>@UPDATE_PERIOD</sy:updatePeriod>
        <sy:updateFrequency>@UPDATE_FREQUENCY</sy:updateFrequency>
        @foreach (IPublishedContent item in feedItems.OrderBy(ARTICLE_DATE_PROPERTY_ALIAS + " desc"))
        {
            string articleDescription = Umbraco.Truncate(umbraco.library.StripHtml(item.GetGridHtml("contentGrid", "bootstrap3").ToString()), CONTENT_PREVIEW_LENGTH).ToString().Replace("&hellip;", "...");
            @:<item>
                <title>@(item.HasProperty(ARTICLE_TITLE_PROPERTY_ALIAS) ? item.GetPropertyValue<string>(ARTICLE_TITLE_PROPERTY_ALIAS) : item.Name)</title>
                @:<link>
                @umbraco.library.NiceUrlWithDomain(item.Id)
                @:</link>
                <pubDate>@(((DateTime)item.GetPropertyValue(ARTICLE_DATE_PROPERTY_ALIAS)).ToString(DATE_FORMAT))</pubDate>
                <dc:creator><![CDATA[@CREATOR_NAME]]></dc:creator>
                <category><![CDATA[@CATEGORY]]></category>
                <guid isPermaLink="false">@item.UrlWithDomain()</guid>
                <description><![CDATA[@articleDescription]]></description>
            @:</item>
        }
    </channel>
</rss>

Need a video to help you follow the instructions?

Have a look at this video where I try to implement the sample code on the default starter site you get with Umbraco.
If you want to be notified when I post new videos, click on subscribe in my author block below this post.

Watch on YouTube

Are you stuck?

If you are stuck, please don't hesitate to ask your question in the comments.

Paul Seal

Umbraco MVP and .NET Web Developer from Derby (UK) who specialises in building Content Management System (CMS) websites using MVC with Umbraco as a framework. Paul is passionate about web development and programming as a whole. Apart from when he's with his wife and son, if he's not writing code, he's thinking about it or listening to a podcast about it.

Proudly sponsored by

Moriyama

  • Moriyama build, support and deploy Umbraco, Azure and ASP.NET websites and applications.
AppVeyor

  • CI/CD service for Windows, Linux and macOS
  • Build, test, deploy your apps faster, on any platform.
elmah.io

  • elmah.io is the easy error logging and uptime monitoring service for .NET.
  • Take back control of your errors with support for all .NET web and logging frameworks.
uSync Complete

  • uSync.Complete gives you all the uSync packages, allowing you to completely control how your Umbraco settings, content and media is stored, transferred and managed across all your Umbraco Installations.
uSkinned

  • More than a theme for Umbraco CMS, take full control of your content and design with a feature-rich, award-nominated & content editor focused website platform.
UmbHost

  • Affordable, Geo-Redundant, Umbraco hosting which gives back to the community by sponsoring an Umbraco Open Source Developer with each hosting package sold.