Enabling RSS Site-wide in Orchard

Background

When publishing a blog with Orchard CMS, the blog module includes default RSS feeds for the items as well as for comments. One limitation of the default implementation is that the feeds only show up when you navigate to the main blog page, or to a post within the blog. Other pages in your site will not make the feed url(s) available.

In my case, I view my entire site as my “blog”, but only display a widget with recent posts on the home page, along with widgets for additional information. So I wanted to find a way to add my main RSS link to all pages in my site.

My initial thought was to simply hard-code the link in the layout file for my theme (or in document.cshtml in the Orchard.Core Shapes\Views), but that seemed like a very hacky solution, so I kept looking.

Current Solution

The current solution I’m using takes advantage of Orchard’s support for Shape Templates (additional info on Shape Templates). Shapes can be rendered via either templates or code. In the case of templates, these are implemented as views (i.e. – MyTemplate.cshtml). You can override an existing shape template by placing a file in your Themes<themename>\Views folder with the same name as the template you want to override. So if you wanted to override the rendering of the content area of the page, you would add Content.cshtml to the Themes<themename>\Views folder for the active theme, and modify it as desired. The best recommendation I can make beyond reading the Orchard documentation on this is to download a few themes and start digging through the Views folder to see what that particular theme may be overriding and how.

One file to take particular note of is Layout.cshtml, since this is where a lot of the action takes place. In my case, the section of most interest starts with the following comment:

   1: /* Inserting some ad hoc shapes

   2: ***************************************************************/

What follows, depending on your theme, are several calls to WorkContext.Layout. etc. These are calls allowing you to create shapes based on templates you’ve defined, and stick them in particular areas of the page. For example, The Theme Machine theme has the following calls:

   1: WorkContext.Layout.Header.Add(New.Branding(), "5"); // Site name and link to the home page

   2: WorkContext.Layout.Footer.Add(New.BadgeOfHonor(), "5"); // Powered by Orchard

   3: WorkContext.Layout.Footer.Add(New.User(), "10"); // Login and dashboard links

The comments are pretty informative here…basically we’re adding new Branding, BadgeOfHonor and User shapes to the Header and Footer zones of the page. Of interest here is that only Branding and BadgeOfHonor are being created from templates in the theme, while User is not being overriden.

So, after that slight tangent, back to my current solution for site-wide RSS. In order to support this, I created a file in my Themes<themename>\Views folder called RSSLink.cshtml, with the following content:

   1: <link rel="alternate" type="application/rss+xml"

   2:    title="Devhammer's Den" href="http://feeds.devhammer.net/devhammer" />

Then, to get the content to show up, I added the following to the Layout.cshtml file in my Themes<themename>\Views folder:

   1: WorkContext.Layout.Head.Add(New.RSSLink());

This creates a new shape based on my RSSLink template, and inserts it in the section of the document, which results in the RSS tag being rendered in the section of the site, regardless of which page is being viewed.

Advantages

The main advantage of this solution is that it’s relatively simple, and it works. Another advantage is that because it is using a template within the theme’s Views folder, and rendering that template from within Layout.cshtml, this solution does not require any modification to the Orchard Core files.

Downsides

There are a couple of downsides to my current solution. One is that the solution is code/markup-based, so if I needed to change my RSS link, I would have to go into the RSSLink.cshtml file and change the link there, and then redeploy that file to my Orchard site. Not the end of the world for a developer geek like myself, but not optimal for normal CMS users.

A second downside is that because the solution renders the RSS link regardless of what page is displayed, and neither my solution nor the built-in RSS support in the blog module are aware of one another, on the main blog page or any individual blog post, two RSS links will be rendered for the feed, as shown below (both the “Devhammer’s Den” and “Blog” feeds point to the same place):

feeds

This isn’t that big a deal, since both feeds point to the same place, but it does have the potential to be confusing.

Possible Future Solutions

I’m OK with the current solution for the time being, while I’m learning more about the internals of Orchard CMS. But moving forward, there are a couple of ideas I have for an improved solution.

One is to customize the blog module, adding a checkbox field in the blog settings for whether the RSS feed should be displayed site-wide. Given that Orchard is open-source, this would be fairly easy to do, but would not help the average user, unless the changes were contributed back and integrated into the Orchard project.

A second solution, which would be more accessible to end-users, would be to create a module that exposes fields for links and scripts that should go in the section of the page, and possibly also at the end of the page, just inside the tag (for performance reasons, most scripts should go at the end of the page, since downloading scripts can block rendering of the rest of the page). This could be implemented as a module that renders the desired links/scripts on all pages, or perhaps with a field to indicate the Layer (or layers) for which to render the links/scripts.

These future solutions are just my noodlings for now, so I would welcome comments or suggestions from other Orchard folks.

Code, Community, and Coffee
Built with Hugo
Theme Stack designed by Jimmy