Blog 4 umbraco 2.0.4 – Rss-feeds

Friday, December 04, 2009 by Administrator

Today we'll look at improving the blog rss-feed(s), the magic words are xslt, alternative templates and some url rewriting .Currently the blog4umbraco package comes with a single rss-feed that just lists the xth latest blog posts. We'll be improving that so as an end result we'll have:

  • Latest posts rss feed
  • Latest posts rss feed for each tag
  • Comments rss feed
  • Comments rss feed for each post

Basicly the rss feed is an alternative template that's applied to the blog homepage(by adding the template alias 'rss' to the url) . And that template contains a single xslt macro that outputs the rss-feed in the correct format (the rss feed is one of the templates you can start your xslt with).

image

A small update that I'll tackle first it to update the SiteURL variable from a static value to a dynamic one by fetching the current host from the HTTP_HOST server variable.

<xsl:variable name="SiteURL" select="concat(' http://',string(umbraco.library:RequestServerVariables('HTTP_HOST')))"/>

Latest posts rss feed for each tag

In order to have an rss feed for each tag, we'll just have to update the code that selects the blogposts and only show the blogposts that contain the supplied tag. If there isn't a tag supplied (we'll use the request param tag, so /rss.aspx?tag=xmas) we still display all blogposts. So we'll first check if the request param tag is available, if it isn't we select all blogposts (like it should allready do) and if there is a tag supplied we'll filter the blog posts to only select the ones containing that tag.

<xsl:choose>
        <xsl:when test="string-length(umbraco.library:Request('tag')) &gt; 0">
            <xsl:apply-templates select="$currentPage//node [@nodeTypeAlias = 'BlogPost' and contains(Exslt.ExsltStrings:lowercase(./data [@alias='tags']), Exslt.ExsltStrings:lowercase(umbraco.library:Request('tag')))]">
                      <xsl:sort select="@createDate" order="descending" />
                    </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="$currentPage//node [@nodeTypeAlias = 'BlogPost']">
                      <xsl:sort select="@createDate" order="descending" />
                    </xsl:apply-templates>
        </xsl:otherwise>
    </xsl:choose>

We'll make this have a nicer url by adding a url rewriting rule to the /config/UrlRewriting.config file. So we'll go from /rss?tag=xmas to /rss/tags/xmas.

<add name="rsstagrewrite"
    virtualUrl="^~/blog/rss/tags/(.*).aspx"
    rewriteUrlParameter="ExcludeFromClientQueryString"
    destinationUrl="~/blog/rss.aspx?tag=$1"
    ignoreCase="true" />

Comments rss feed

For the comments rss feed we'll also be able to re-use most of the main xslt we'll just need to know if we need to output a comments feed instead of a blog post feed (since we have to select different documents and these have a different structure). So I'll add a parameter to the blog rss macro called 'iscommentfeed'.

image

And I'll also create a new template called 'CommentRss'. This will be used in the same way as the Rss template (as an alternative template). The only difference between the 2 will be the value of the iscommentfeed parameter.

So I'll first update the blog rss macro to include the iscommentfeed variable

<xsl:variable name="iscommentfeed" select="//macro/iscommentfeed" />

And then prior to selecting the BlogPosts I'll check the value of the iscommentfeed variable. In case the value is 1 we'll need to select the comments instead of the posts.

<xsl:when test="$iscommentfeed = '1'">

            <xsl:apply-templates select="$currentPage//node [@nodeTypeAlias = 'BlogPostComment']">
                      <xsl:sort select="@createDate" order="descending" />
                    </xsl:apply-templates>

        </xsl:when>

I'll also have to update the xslt code that outputs the rss items. Since the post and comments will have a different url and a differen structure (content of a post is stored in the bodyText property, content of a comment in the comment property).

<xsl:variable name="link">
        <xsl:choose>
            <xsl:when test="@nodeTypeAlias = 'BlogPostComment'">
                <xsl:value-of select="concat(umbraco.library:NiceUrl(./../@id),'#comment-',@id)"/>
            </xsl:when>
            <xsl:otherwise>
                 <xsl:value-of select="umbraco.library:NiceUrl(@id)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="content">
        <xsl:choose>
            <xsl:when test="@nodeTypeAlias = 'BlogPostComment'">
                 <xsl:value-of select="umbraco.library:ReplaceLineBreaks(data [@alias = 'comment'])"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="./data [@alias='bodyText']"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

Comments rss feed for each post

For making a comments rss feed for each post I won't have to change anything to the xslt. Since I select all the comments found below the currentPage ($currentPage//node [@nodeTypeAlias = 'BlogPostComment']).

So when calling the commentsrss template on the main blog page (blog/commentrss.aspx), we'll list all comments but when calling the template on a specific post ( blog/2009/12/3/xmaspost/commentrss.aspx) we'll only get the comments for that post.

Final touches

The last thing we'll do is update the xslt file that's responsible for outputting the rss feed link.

In case we are viewing the posts of a certain tag we'll need to add a link to the rss feed for that tag (/rss/tags/xmas.aspx).

<xsl:if test="string-length(umbraco.library:Request('filterby')) &gt; 0">
    <link href="{umbraco.library:Replace(umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = 'Blog']/@id),'.aspx',concat('/rss/tags/',umbraco.library:Request('filterby'),'.aspx'))}" rel="alternate" type="application/rss+xml" title="RSS Feed for tag {umbraco.library:Request('filterby')}" />
</xsl:if>

And we'll also need to show a link to the comments rss feed (wich is an alternative template of the blog called commentrss)

<link href="{umbraco.library:Replace(umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = 'Blog']/@id),'.aspx','/commentrss.aspx')}" rel="alternate" type="application/rss+xml" title="Comments RSS Feed" />

And if we are on a blog post  (we can check that with the nodetypealias) we'll also add a link to the comments feed for that specific blog post.

<xsl:if test="$currentPage/@nodeTypeAlias = 'BlogPost'">
    <link href="{umbraco.library:Replace(umbraco.library:NiceUrl($currentPage/@id),'.aspx','/commentrss.aspx')}" rel="alternate" type="application/rss+xml" title="Comments RSS Feed for {$currentPage/@nodeName}" />
</xsl:if>

The result

When on the main blog page, we'll have the main rss feed and the comments rss feed

image

On a post we'll also have the comments feed for that post

image

And when viewing the posts for a certain tag …

image

3 comment(s) for “Blog 4 umbraco 2.0.4 – Rss-feeds”

  1. Gravatar ImageChris Houston Says:

    Hi Tim,

    That looks like a great addition to your new and improved blog package!

    Cheers,

    Chris

  2. Gravatar ImageLee Says:

    Can't wait to this thing finished! =)

  3. Gravatar ImageZac Says:

    Awesome! Really liking this blog series and can't wait for the end product. Great Idea!

Leave a comment