Add Additional Item Fields to RSS Feeds Generated by Sitecore
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”:
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:
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:
For testing, I added two Items — one with an image and another without an image:
After publishing everything, I loaded the RSS feed in my browser and saw the following:
If you know of other ways to add additional Item fields into Sitecore RSS feeds, please share in a comment.