Home » Customization » Add Additional Item Fields to RSS Feeds Generated by Sitecore

Add Additional Item Fields to RSS Feeds Generated by Sitecore

Sitecore Technology MVP 2016
Sitecore MVP 2015
Sitecore MVP 2014

Enter your email address to follow this blog and receive notifications of new posts by email.

Tweets

Earlier today a colleague had asked me how to add additional Item fields into RSS feeds generated by Sitecore.

I could have sworn there was an easy way to do this, but when looking at the RSS Feed Design dialog in Sitecore, it appears you are limited to three fields on your Items “out of the box”:

rss-feed-design

After a lot of digging in Sitecore.Kernel.dll, I discovered that one can inject a subclass of Sitecore.Syndication.PublicFeed to override/augment RSS feed functionality:

feed-manager

As a proof-of-concept, I whipped up the following subclass of Sitecore.Syndication.PublicFeed:

using System.ServiceModel.Syndication; // Note: you must reference System.ServiceModel.dll to use this!

using Sitecore.Diagnostics;
using Sitecore.Configuration;
using Sitecore.Data.Items;
using Sitecore.Pipelines;
using Sitecore.Pipelines.RenderField;
using Sitecore.Syndication;

namespace Sitecore.Sandbox.Syndication
{
    public class ImageInContentPublicFeed : PublicFeed
    {
        private static string ImageFieldName { get; set; }

        private static string RenderFieldPipelineName { get; set; }

        static ImageInContentPublicFeed()
        {
            ImageFieldName = Settings.GetSetting("RSS.Fields.ImageFieldName");
            RenderFieldPipelineName = Settings.GetSetting("Pipelines.RenderField");
        }

        protected override SyndicationItem RenderItem(Item item)
        {
            SyndicationItem syndicationItem = base.RenderItem(item);
            AddImageHtmlToContent(syndicationItem, GetImageFieldHtml(item));
            return syndicationItem;
        }

        protected virtual string GetImageFieldHtml(Item item)
        {
            if (string.IsNullOrWhiteSpace(ImageFieldName))
            {
                return string.Empty;
            }

            return GetImageFieldHtml(item, ImageFieldName);
        }

        private static string GetImageFieldHtml(Item item, string imageFieldName)
        {
            Assert.ArgumentNotNull(item, "item");
            Assert.ArgumentNotNullOrEmpty(imageFieldName, "imageFieldName");
            Assert.ArgumentNotNullOrEmpty(RenderFieldPipelineName, "RenderFieldPipelineName");
            if (item == null || item.Fields[imageFieldName] == null)
            {
                return string.Empty;
            }

            RenderFieldArgs args = new RenderFieldArgs { Item = item, FieldName = imageFieldName };
            CorePipeline.Run(RenderFieldPipelineName, args);
            if (args.Result.IsEmpty)
            {
                return string.Empty;
            }

            return args.Result.ToString();
        }

        protected virtual void AddImageHtmlToContent(SyndicationItem syndicationItem, string imageHtml)
        {
            if (string.IsNullOrWhiteSpace(imageHtml) || !(syndicationItem.Content is TextSyndicationContent))
            {
                return;
            }

            TextSyndicationContent content = syndicationItem.Content as TextSyndicationContent;
            syndicationItem.Content = new TextSyndicationContent(string.Concat(imageHtml, content.Text), TextSyndicationContentKind.Html);
        }
    }
}

The class above ultimately overrides the RenderItem(Item item) method defined on Sitecore.Syndication.PublicFeed — it is declared virtual. The RenderItem(Item item) method above delegates to the RenderItem(Item item) method of Sitecore.Syndication.PublicFeed; grabs the System.ServiceModel.Syndication.SyndicationContent instance set in the Content property of the returned SyndicationItem object — this happens to be an instance of System.ServiceModel.Syndication.TextSyndicationContent; delegates to the <renderField> pipeline to generate HTML for the image set in the Image Field on the item; creates a new System.ServiceModel.Syndication.TextSyndicationContent instance with the HTML of the image combined with the HTML from the original TextSyndicationContent instance; sets the Content property with this new System.ServiceModel.Syndication.TextSyndicationContent instance; and returns the SyndicationItem instance to the caller.

Since I hate hard-coding things, I put the Image Field’s name and <renderField> pipeline’s name in a patch configuration file:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <settings>
      <setting name="RSS.Fields.ImageFieldName" value="Image" />
      <setting name="Pipelines.RenderField" value="renderField" />
    </settings>
  </sitecore>
</configuration>

I then mapped the above subclass of Sitecore.Syndication.PublicFeed to the RSS Feed Item I created:

RSS-Feed-Item

For testing, I added two Items — one with an image and another without an image:

item-with-image

item-no-image

After publishing everything, I loaded the RSS feed in my browser and saw the following:

RSS-Feed

If you know of other ways to add additional Item fields into Sitecore RSS feeds, please share in a comment.

Advertisements

1 Comment

  1. Susheela says:

    its good, but i want to know jow and where to set url redirection for blog title, i mean Title will be created as a link field but it will have its own redirection which is giving error as its not finding that aspx page.

Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: