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:
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')))"/>
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" />
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>
<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>
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.
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>
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 …
Hi Tim, That looks like a great addition to your new and improved blog package! Cheers, Chris
Can't wait to this thing finished! =)
Awesome! Really liking this blog series and can't wait for the end product. Great Idea!
You comment is being submitted... please wait...
Your comment has been posted on umbraco in reply to: Blog 4 umbraco 2.0.4 – Rss-feeds
Something horrible happened. and your comment could not be posted. Please ensure that all fields have correct values, and that yourEmail address is valid.