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!