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).

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')) >
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'.

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')) >
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

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

And when viewing the posts for a certain tag …
