RSS or ATOM Feed from Composite C1

Topics: Feature requests, General, Standard packages, XSLT
Jun 30, 2011 at 9:40 PM
Edited Jun 30, 2011 at 9:48 PM

Hi,

I want to add an RSS feed to my Composite C1 site, and would like suggestions for how to go about it.

I'm OK in xslt,html,css, and C#, but asp.net is not my strong area. In umbraco I created a special page template, and had some xslt to create a feed. But, in C1, the nearest I can find is the sitemap package, which works differently. 

Is there a recommended way to add feeds to a C1 site? If not, can I provide a document like an rss feed via the template and function system of C1, or is an http handler or other control advisable?

For the sake of discussion and the exposure, I want to implement the feed at UncloggingDrains101.com . I can get much of this going once I know how to approach the basic implementation, but ideally the feed would have options to check both a setting on published pages for inclusion, but also filtered by page type. Updates to pages should be given due indication in the feed. There are no instances on the site at the moment, but there is also a blog-entry analogous datatype. A feed or feeds from the site should be able to include such datatypes (which will have canonical urls).

I welcome all suggestions and pointers!

 

EDIT: Oh hey, I see I overlooked the Blog package has RSS, whhich I'll take a closer look at

Jun 30, 2011 at 9:44 PM
Edited Jun 30, 2011 at 9:44 PM

This is a simple example of creating a feed based on a datatype in C1. Its a basic IHttpHandler that outputs xml/rss.

http://c1packages.codeplex.com/SourceControl/changeset/view/8053#129098

Jun 30, 2011 at 9:57 PM

If you want to, you can also build up the feed using an XSLT Function and then expose it using this http://docs.composite.net/C1/HTML/FrontendFAQ.aspx?q=Can+I+call+C1+Functions+AJAX+style+from+JavaScript+or+Flash%3f - if you need any pointers on how to get at the data, just fire away.

Jun 30, 2011 at 10:16 PM

@mawtex i have a suggestion for that handler... semantically language is not a property of the data being queried but referers to "which context/scope" to execute the function in, so therefor its more correct to use the url

http://mysite/nl-NL/ajax/MY.XSLT.FUNCTION.ashx?PageNum=2&PageSize=25

instead of

http://mysite/Ajax/MY.XSLT.FUNCTION.ashx?cultureScope=nl-NL&PageNum=2&PageSize=25

 

You can easily do rewrite so the culture is passed as querystring, but the more correct way is to set the CurrentCultureInfo on the current thread and let that be authorative for what culturescope should be used when executing the function. Inspiration for such a module can be seen here http://compositec1contrib.codeplex.com/SourceControl/changeset/view/68173#1133177 and is what makes it possible to access http://www.katuaq.gl/da-DK/sitemap.axd or http://www.katuaq.gl/kl-GL/sitemap.axd without using ugly querystrings.

Jul 3, 2011 at 1:35 AM
Edited Jul 3, 2011 at 1:51 AM

Thanks for the feedback! I decided to go with the function call because it was very similar to what I had to work with already. 

I didn't implement any features, and in fact hardcoded some bits and found others, but did get it to validate. I kept checking it via Google Reader, and I don't know if it was coincidental, but it appeared Reader would not let me subscibe until the feed validated completely, although it would see the feed when browsed to.

I confess I did not concern myself too much with culture info. The feed lang is set to 'en' by the xslt. I'll paste the xslt for anyone interested--if it could be easily improved for accessibility, let me know. You'll see I mixed sources of info a bit, but the function calls are standard except one that is for GetPageSettingsXml and it is specific to my site, among a couple other areas.

Thanks for the quick and useful pointers! I really enjoy making C1 work.

 

 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" 
xmlns:f="http://www.composite.net/ns/function/1.0" xmlns:date="#dateExtensions" exclude-result-prefixes="xsl in lang f date">
  <xsl:variable name="PublishDate">
    <!--  //    This date has not eliminated pages marked for exclusion from feeds. 
          //    The Publish Date may be newer than the newest item in the feed. 
          //	The destination page type is a 'Pad' -->
   <xsl:for-each select="/in:inputs/in:result[@name='GetIPageXml']/IPage[contains(@PageTypeId.Name, 'Pad') and @PublicationStatus='published']">
      <xsl:sort select="@ChangeDate" data-type="text" order="descending" />
      <xsl:if test="position() = 1">
        <xsl:value-of select="@ChangeDate" />
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>
  <xsl:template match="/">
    <rss version="2.0">
      <channel>
        <atom:link href="{concat('http://', /in:inputs/in:result[@name='ServerVariableHTTPHOST'], '/Frontend/Feeds/LandingSite.PagesRSS.ashx')}" rel="self" type="application/rss+xml" />
        <title>
          <xsl:text>UncloggingDrains101.com - Learn the Latest About Clearing and Cleaning Drains [Your Drain Service Information Resource]</xsl:text>
        </title>
        <link>
          <xsl:value-of select="concat('http://', /in:inputs/in:result[@name='ServerVariableHTTPHOST'])" />
        </link>
        <pubDate>
          <xsl:value-of select="date:Format($PublishDate, 'r')" />
        </pubDate>
        <generator>UncloggingDrains101.com via Composite C1 CMS</generator>
        <description>
          <xsl:text>Teaching You All About Unclogging Drains. Etc.</xsl:text>
        </description>
        <language>en</language>
        <xsl:for-each select="/in:inputs/in:result[@name='GetIPageXml']/IPage[contains(@PageTypeId.Name, 'Pad') and @PublicationStatus='published']">
          <xsl:sort select="@ChangeDate" data-type="text" order="descending" />
          <xsl:if test="/in:inputs/in:result[@name='GetPageSettingsXml']/PageSettings[@PageId=current()/@Id]/@HideFromSyndication='false'">
            <xsl:apply-templates select="." />
          </xsl:if>
        </xsl:for-each>
      </channel>
    </rss>
  </xsl:template>
  <xsl:template match="IPage">
    <xsl:if test="position() &lt;= 125">
      <item>
        <title>
          <xsl:value-of select="@Title" />
        </title>
        <link>
          <xsl:value-of select="concat('http://', /in:inputs/in:result[@name='ServerVariableHTTPHOST'], /in:inputs/in:result[@name='SitemapXml']//Page[@Id=current()/@Id]/@URL)" />
        </link>
        <pubDate>
          <xsl:value-of select="date:Format(@ChangeDate,'r')" />
        </pubDate>
        <guid>
          <xsl:value-of select="concat('http://', /in:inputs/in:result[@name='ServerVariableHTTPHOST'], /in:inputs/in:result[@name='SitemapXml']//Page[@Id=current()/@Id]/@URL)" />
        </guid>
        <description>
          <xsl:value-of select="@Description" />
        </description>
      </item>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>