Content Query Web Part example

I recently got deeper into using the Content Query Web Part (CQWP) than I had in a while and learned a few things. The first thing you should do to learn about the CQWP is read this article from Heather Solomon’s blog: Customizing the Content Query Web Part and Custom Item Styles. I follow the process she describes when using the CQWP.

The Solution

We built a Site Collection that included a top-level site with highlighted and summary content and a large number of sub-sites that included wikis and blogs. Each sub-site had a different group of content contributors. The owner of the top-level site wants to be able to highlight and promote sub-site content to the top landing page. I built this with a custom list and a CQWP.

The custom list contains enough columns to reference content by URL and add summary info that can be display at the top-level landing page:

Columns

Then I placed a CQWP on the landing page to display that custom list with a specific layout:

CQWP

CQWP Details

Here is what I learned in the process. All of this applies to the XSL you write in ItemStyle.xsl.

Debugging

When working with custom fields in the XSL, it was helpful to use this to display all the column names and their values:

<xsl:for-each select="@*">
F:<xsl:value-of select="name()"/>--<xsl:value-of select="."/><br/>
</xsl:for-each>

URL Columns

Using the script above on a URL column, you’ll notice that URL values are stored as “https://msdn.microsoft.com, https://msdn.microsoft.com”. This is to support this style of rendering:

<a href="{substring-before(@URLColumn, ', ')}">
<xsl:value-of select="substring-after(@URLColumn, ', ')"/>
</a>

Therefore, if you just want the URL, use substring-before(@URLColumn, ‘, ‘).

Pictures and Rich Text

Both Picture and Rich Text column types are stored with embedded HTML markup. By default, when you use XSL to render these column values, the HTML is escaped and the viewer sees the actual markup rather than just the formatted content. To render these column values, use the disable-output-escaping attribute:

<div class="image-area-left">
<xsl:value-of select="@Icon" disable-output-escaping="yes"/>
</div>

Rating Web Part

Finally, I used the Rating web part from Codeplex to allow viewers to rate the content. Now I needed to display the rating value or a link to rate the item in the CQWP. Here’s how I did that:

<xsl:variable name="ListGuid">
<xsl:value-of select="@ListId"/>
</xsl:variable>

<xsl:variable name="ItemId">
<xsl:value-of select="@ID"/>
</xsl:variable>

 <div>
<xsl:choose>
<xsl:when test="contains($Rating, '(5)')">
<img src="/_layouts/images/sptoolbasket/rating_5.gif" alt="{$Rating}"/>
</xsl:when>
<xsl:when test="contains($Rating, '(4)')">
<img src="/_layouts/images/sptoolbasket/rating_4.gif" alt="{$Rating}"/>
</xsl:when>
<xsl:when test="contains($Rating, '(3)')">
<img src="/_layouts/images/sptoolbasket/rating_3.gif" alt="{$Rating}"/>
</xsl:when>
<xsl:when test="contains($Rating, '(2)')">
<img src="/_layouts/images/sptoolbasket/rating_2.gif" alt="{$Rating}"/>
</xsl:when>
<xsl:when test="contains($Rating, '(1)')">
<img src="/_layouts/images/sptoolbasket/rating_1.gif" alt="{$Rating}"/>
</xsl:when>
<xsl:otherwise>
<a href="/_layouts/sptoolbasket/ItemRating.aspx?Id={$ItemId}&amp;List={$ListGuid}">Rate</a>
</xsl:otherwise>
</xsl:choose>
</div>

The CQWP is powerful both for formatting the display as well as query content. In this particular case, I used the former more than the latter since I was only querying a single list.