How to customize the Content Query Web Part XSL to aggregate blog posts
Ever wondered how to have the Content Query Web Part (CQWP) aggregate SharePoint blog posts from the SharePoint Blog site templates? Oh wait, that’s already possible. How about aggregating blog posts, customizing the XSL styling and being able to display the first 200 characters of the post as a preview?

Believe it or not, I couldn’t seem to find a single definitive blog post on how to do this so I’ve decided to write one up myself.
Step 1
Assuming you already have your Blog sites setup, add a Content Query Web Part to the page in which you’d like to have the posts aggregated onto. Configure the Web Part to your liking. It would look something like this:

Step 2
Using SharePoint Designer, check-out and open the ItemStyle.xsl Style Sheet from http://yourserver/Style Library/XSL Style Sheets/
Step 3
Follow all the steps in this blog post. It will give you a good overview on how to customize the Content Query Web Part to aggregate and display News Article items along with the quick summary display and some other item properties.
The result of my customized XSL Template looks like this:
<xsl:template name="LargeTitleWithDescription" match="Row[@Style='LargeTitleWithDescription']" mode="itemstyle"> <xsl:variable name="SafeLinkUrl"> <xsl:call-template name="OuterTemplate.GetSafeLink"> <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="SafeImageUrl"> <xsl:call-template name="OuterTemplate.GetSafeStaticUrl"> <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="DisplayTitle"> <xsl:call-template name="OuterTemplate.GetTitle"> <xsl:with-param name="Title" select="@Title"/> <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="LinkTarget"> <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if> </xsl:variable> <xsl:variable name="Created"> <xsl:value-of select="ddwrt:FormatDateTime(string(@Created) ,1033 ,'MM-dd-yyyy')" /> </xsl:variable> <xsl:variable name="Author"> <xsl:call-template name="OuterTemplate.GetGroupName"> <xsl:with-param name="GroupName" select="@Author"/> <xsl:with-param name="GroupType" select="'User'"/> </xsl:call-template> </xsl:variable>
<div id="linkitem" class="item">
<xsl:if test="string-length($SafeImageUrl) != 0">
<div class="image-area-left">
<a href="{$SafeLinkUrl}" target="{$LinkTarget}">
<img class="image" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}" />
</a>
</div>
</xsl:if>
<div class="link-item-large">
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
<font size="2"><xsl:value-of select="$Created"/></font><br/>
<a href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}" style="color:black">
<xsl:value-of select="$DisplayTitle"/>
</a>
<div class="description">
<span style="padding-left: 5px; font-size: smaller; text-decoration: none;">
Posted by <xsl:value-of select="$Author" /><br/><br/>
</span>
</div>
<div class="description" style="padding-left:5px; color:#333333;">
<xsl:value-of select="substring(@Description, 0, 200)" disable-output-escaping="yes"/>
<a href="{$SafeLinkUrl}" target="{$LinkTarget}" title="Read More">...</a>
</div>
</div>
</div>
</xsl:template>
Unfortunately, if you check this in, publish it and look at your CQWP, it won’t display the summary text of the blog post. It will look something like this:

So after much head scratching and googling, I came across this blog post and this blog post that gave me some hints as to why this doesn’t work with the Body field of SharePoint blog posts. Apparently the Blog Site template and the Posts Document Library contain more than one Content Types (one for posts, one for comments?). But wait! He says we can override the Content Query Web Part. Unfortunately… there doesn’t seem to be an available BaseType for blogs.
After some more sleuthing I finally see something interesting on the 2nd page of my google search. A PowerPoint Slidedeck from SharePoint Conference 2008 being stored on a Chinese SharePointer’s SharePoint Site! Good thing he didn’t have all the slides translated already :p And thank you Sean Squires from the ECM Team for including some really awesome slide notes. Slide 15 did it for me. So onwards with our cuztomizations…
Step 4
Export the configured CQWP and open it with a text editor. There will be 3 lines that will need editing. The first one is this one:
<property name="ListsOverride" type="string"/>
You’ll want to change it to reflect this:
<property name="ListsOverride" type="string"> <![CDATA[<Lists><List ID="81B49BFB-E218-46D4-A697-683FE7F286ED"/> <List ID="0CC1695B-1E54-45C5-9825-67DE219A2B4C"/></Lists>]]> </property>
Heather Soloman has a nice post that explains how to retrieve a list’s GUID. The second line you’ll need to change is this one:
<property name="DataColumnRenames" type="string" />
Update that property to reflect this:
<property name="DataColumnRenames" type="string">Body,Description;</property>
The 3rd line that needs to change is
<property name="CommonViewFields" type="string" />
It should now look like this:
<property name="CommonViewFields" type="string"> ExternalUrl,URL;PublishingPageImage,Image; Body,Description;</property>
Save your Web Part file as something other than the default file name.
Step 5
Upload your customized Web Part into your Site Collection’s Web Part Gallery. It would probably be helpful to give it a unique name and group.

Step 6
Add the new web part to your page and voila!



Nice writeup and much needed as well.
Thanks.
Martin
15 Jun 08 at 8:38 pm
this is god send..I was looking for this to post blogs on my MOSS 2007 front page dynamically for the portal from the SharePoint blogs. I just have to look into a way to put one and only the latest post on the content query webpart. i should be able to maniupalate this…
thanks again.
Z
24 Jun 08 at 6:14 pm
I get this error when I check in the itemstyle.xsl with your template.
Unable to display this Web Part. To troubleshoot the problem, open this Web page in a Windows SharePoint Services-compatible HTML editor suc
Z
24 Jun 08 at 9:00 pm
Re: Z:
You need to replace any punctuation from the copy-paste with real ‘”‘, ”’, and ‘…’ chars…
Caught me out too…
My problem is, if I do step 4 with the ListOverride, the Web Part does not display *anything* (I will check to see if the GUID shown here is a sample…), but if I take it out, I still get no body synopsis…
Mark Fendley
26 Jun 08 at 7:05 am
Hey Mark, the copy paste should work as is, but if it doesn’t let me know which parts need to be updated. The GUIDs will be unique to your environment.
Henry
26 Jun 08 at 7:45 am
Thanks Mark and Henry
I replaced the ‘”‘, ”’, and ‘…’ quotations and that didresolved some issues for me.
I have other issues where this line gives out an error :
This stuf i very tough to trooubleshoot also.
Also , when I add a specific GUID ( I got the guid from the URL of the posts) , I cannot really get that webpart ot disply also.
Also , why do you have two seperate guids for the same blog ?
It would be awesome if I can get this to work correctly…but I am seeing too many errors…
Z
26 Jun 08 at 9:24 am
Hey man …the override with the list ID’s just doesnt work. I cannot even import the webpart with the list id. I realize you have tow list ID’s beause one is for the posts and other for the comments (How did you even get this list id). any help is appreciated.
Z
26 Jun 08 at 11:29 am
Hey Z, in my example each GUID is for a different blog site’s document library that contains the posts. I haven’t tried using the CQWP for comments.
Henry
26 Jun 08 at 1:42 pm
aah makes sense…thanks a lot !
I still am struggling with even adding this one line and not getting an error when I import the webpart. I wonder what I am doing wrong…..
:
<![CDATA[
]]>
Z
27 Jun 08 at 7:46 am
I finally got it to work !!! thanks this is really helpful.
Z
27 Jun 08 at 12:07 pm
The user groupType is not defined as referenced below:
The corrected Template is below:
Chris Wood
3 Jul 08 at 7:51 pm
The user groupType is not defined as referenced below:<xsl:call-template name=”OuterTemplate.GetGroupName”><xsl:with-param name=”GroupName” select=”@Author”/><xsl:with-param name=”GroupType” select=”‘User’”/></xsl:call-template>
The corrected Template is below:
<xsl:template name=”OuterTemplate.GetGroupName”> <xsl:param name=”GroupName”/> <xsl:param name=”GroupType”/> <xsl:choose> <xsl:when test=”string-length(normalize-space($GroupName)) = 0″> <xsl:value-of select=”$BlankGroup”/> </xsl:when> <xsl:otherwise> <xsl:choose> <xsl:when test=”$GroupType=’URL’”> <xsl:variable name=”Url”> <xsl:call-template name=”OuterTemplate.FormatValueIntoUrl”> <xsl:with-param name=”Value” select=”$GroupName”/> </xsl:call-template> </xsl:variable> <xsl:call-template name=”OuterTemplate.GetPageNameFromUrlRecursive”> <xsl:with-param name=”Url” select=”$Url”/> </xsl:call-template> </xsl:when> <xsl:when test=”$GroupType=’User’”> <xsl:value-of select=”substring-after($GroupName,’#')”/> </xsl:when>
<xsl:otherwise> <xsl:value-of select=”$GroupName” /> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template>
Chris Wood
3 Jul 08 at 7:54 pm
Works great… BUT… the truncating of the Blog body field does not unfortunately leave “valid HTML”… with the result that if your blog posts contain any html formatting this will then “leak” out into the rest of the page.
I wish there were a way to access the functionality for the “summary view” for the list view web part. That somehow magically truncates any rich text - without any “leaking” problems.
Liam Kennedy
11 Jul 08 at 12:43 am
I get this error:
List does not exist
The page you selected contains a list that does not exist. It may have been deleted by another user.
Troubleshoot issues with Windows SharePoint Services.
Matt
6 Aug 08 at 12:13 pm
Hi Henry thanks for this post. But I still need a little of light over me
I’m getting the blog like it shows in the Step 3.
I’ve edited the 3 lines that you mention above but still not working
My itemstyle portion code looks like this:
_blank
-
…
And the .webpart file was edited like follows:
Body, Description;
<![CDATA[ ]]>
ExternalUrl,URL;PublishingPageImage,Image;Body,Description;
Did you see anything wrong in my code?
I’m using Community Kit for SharePoint Blogs http://www.codeplex.com/CKS
Thanks in advance!!!
Ariel
10 Aug 08 at 8:16 am
Ok, I make it works!!
I change a few things to try.
1st: I use @Body as internal name for the “Body” of the blog post in the .sxl file
2nd: I don’t rename the field on the “DataColumnRenames” property of my .wepbart file.
3rd: I use Body, RichHTML on the “CommonViewFields” property of my .webpart file.
The rest is the same as you use here.
I hope this helps.
Thanks… !!!
Ariel
10 Aug 08 at 8:52 am
Hi, I’m triyng to show the name of the blog for every blog post but I can’t find the way…
Does anybody know how to get the blog name??
Thanks
Ariel
27 Aug 08 at 5:40 am
I was wondering if it capable of seekingout all blogs on the server, or maybe the latest 20 posts from 20 different blogs automaticlly with out having to add the blogs to the web part..
What we are trying to do is have a blog aggregator that dynamiclly finds blogs created by staff and displays their posts in the aggregator rather than the sharepoint admins having to add a new blog everytime a new one is created.
Dan
25 Sep 08 at 4:26 pm
xlws utqlwba hmkuvone zcivsp atdyqb geqpd fozvlawxi
dwlx exgqtp
13 Nov 08 at 7:31 pm