Instantly share code, notes, and snippets.
Last active
October 27, 2021 14:54
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save AaronSadlerUK/4169ab6207557fdf13a4b3c8d701f654 to your computer and use it in GitHub Desktop.
How to create an RSS & Atom feed in Umbraco V9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.ServiceModel.Syndication; | |
| public interface ISyndicationXmlService | |
| { | |
| Atom10FeedFormatter GenerateAtomXml(string feedTitle, string feedDescription); | |
| Rss20FeedFormatter GenerateRssXml(string feedTitle, string feedDescription); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Microsoft.Extensions.DependencyInjection; | |
| using Umbraco.Cms.Core.Composing; | |
| using Umbraco.Cms.Core.DependencyInjection; | |
| public class RegisterServicesComposer : IComposer | |
| { | |
| public void Compose(IUmbracoBuilder builder) | |
| { | |
| builder.Services.AddTransient<ISyndicationXmlService, SyndicationXmlService>(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.IO; | |
| using System.Text; | |
| using System.Xml; | |
| using Microsoft.AspNetCore.Mvc; | |
| using Umbraco.Cms.Core.Cache; | |
| using Umbraco.Cms.Core.Logging; | |
| using Umbraco.Cms.Core.Routing; | |
| using Umbraco.Cms.Core.Services; | |
| using Umbraco.Cms.Core.Web; | |
| using Umbraco.Cms.Infrastructure.Persistence; | |
| using Umbraco.Cms.Web.Website.Controllers; | |
| public class SyndicationSurfaceController : SurfaceController | |
| { | |
| private readonly ISyndicationXmlService _syndicationXmlService; | |
| private readonly XmlWriterSettings _xmlWriterSettings = new() | |
| { | |
| Encoding = Encoding.UTF8, | |
| NewLineHandling = NewLineHandling.Entitize, | |
| NewLineOnAttributes = true, | |
| Indent = true | |
| }; | |
| [Route("blog/feed.rss")] | |
| [ResponseCache(Duration = 900)] | |
| public FileContentResult Rss() | |
| { | |
| using var stream = new MemoryStream(); | |
| using (var xmlWriter = XmlWriter.Create(stream, _xmlWriterSettings)) | |
| { | |
| var feed = _syndicationXmlService.GenerateRssXml("My RSS Feed Title", "My RSS Feed Description"); | |
| feed.WriteTo(xmlWriter); | |
| xmlWriter.Flush(); | |
| } | |
| return File(stream.ToArray(), "application/rss+xml; charset=utf-8"); | |
| } | |
| [Route("blog/feed.atom")] | |
| [ResponseCache(Duration = 900)] | |
| public FileContentResult Atom() | |
| { | |
| using var stream = new MemoryStream(); | |
| using (var xmlWriter = XmlWriter.Create(stream, _xmlWriterSettings)) | |
| { | |
| var feed = _syndicationXmlService.GenerateAtomXml("My Atom Feed Title", "My Atom Feed Description"); | |
| feed.WriteTo(xmlWriter); | |
| xmlWriter.Flush(); | |
| } | |
| return File(stream.ToArray(), "application/atom+xml; charset=utf-8"); | |
| } | |
| public SyndicationSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, ISyndicationXmlService syndicationXmlService) | |
| : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) | |
| { | |
| _syndicationXmlService = syndicationXmlService; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.ServiceModel.Syndication; | |
| using Umbraco.Cms.Core.Models.PublishedContent; | |
| using Umbraco.Cms.Core.Web; | |
| using Umbraco.Extensions; | |
| public class SyndicationXmlService : ISyndicationXmlService | |
| { | |
| private readonly IUmbracoContextFactory _umbracoContextFactory; | |
| public SyndicationXmlService(IUmbracoContextFactory umbracoContextFactory) | |
| { | |
| _umbracoContextFactory = umbracoContextFactory; | |
| } | |
| public Rss20FeedFormatter GenerateRssXml(string feedTitle, string feedDescription) | |
| { | |
| return new Rss20FeedFormatter(GenerateSyndicationFeed(feedTitle, feedDescription)); | |
| } | |
| public Atom10FeedFormatter GenerateAtomXml(string feedTitle, string feedDescription) | |
| { | |
| return new Atom10FeedFormatter(GenerateSyndicationFeed(feedTitle, feedDescription)); | |
| } | |
| private SyndicationFeed GenerateSyndicationFeed(string feedTitle, string feedDescription) | |
| { | |
| using var context = _umbracoContextFactory.EnsureUmbracoContext().UmbracoContext; | |
| var feed = new SyndicationFeed(feedTitle, feedDescription, | |
| new Uri(context.CleanedUmbracoUrl.GetLeftPart(UriPartial.Authority)), | |
| context.OriginalRequestUrl.AbsoluteUri,, | |
| DateTime.Now) | |
| { | |
| Copyright = new TextSyndicationContent($"{DateTime.Now.Year} Copyright Name") | |
| }; | |
| var rootNode = context.Content.GetByXPath("//home").First().FirstChild<Blog>(); | |
| var nodes = rootNode | |
| .Descendants<BlogPost>() | |
| .Where(x => x.HasTemplate()) | |
| .Where(x => x.IsVisible()) | |
| .Where(x => x.Value<bool>("hideFromXmlSyndication") == false); | |
| var items = new List<SyndicationItem>(); | |
| foreach (var node in nodes) | |
| { | |
| var title = !string.IsNullOrEmpty(node.Heading) ? node.Heading : node.Name; | |
| var description = new TextSyndicationContent(node.Introduction); | |
| items.Add( | |
| new SyndicationItem( | |
| title, | |
| description, | |
| new Uri(node.Url(null, UrlMode.Absolute)), | |
| node.UrlSegment(), | |
| node.CreateDate)); | |
| } | |
| feed.Items = items; | |
| return feed; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment