Wednesday, April 16, 2008

Displaying listname and sitename when querying data with CQWP

A colleague of mine who works with our MOSS Intranet asked me if I could help him tweak the Content Query Webpart to aggregate all announcements from all sites in our Intranet.

He had already started to tune the content, following Heather Solomons excellent article:
http://www.heathersolomon.com/blog/articles/customitemstyle.aspx and an Microsoft article: http://blogs.msdn.com/ecm/archive/2006/10/25/configuring-and-customizing-the-content-query-web-part.aspx

However, there seemed to be no way of getting the listname and sitename where the item was coming from to the XSL transformation. After some digging deep with the reflector and some testing with the SPSiteDataQuery I found a solution that seems to do the trick.

First (as described in step 3 in the Microsoft article) you need to export the .webpart file from the CQWP-webpart that you have configured.

In the .webpart file there is a property called ViewFieldsOverride. This property overrides the fields that are loaded by the CQWP. This gives us an opportunity to add the Listname when querying the data.

Since we are overriding it, we first need to add the default fields (Title, Created etc) manually. After that, we add the listname and sitename using the <ListProperty Name="Title" />and <ProjectProperty Name="Title" />

<property name="ViewFieldsOverride" type="string"><![CDATA[<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Nullable="True" Type="Text" /><FieldRef ID="{94f89715-e097-4e8b-ba79-ea02aa8b7adb}" Nullable="True" Type="Lookup" /><FieldRef ID="{1d22ea11-1e32-424e-89ab-9fedbadb6ce1}" Nullable="True" Type="Counter" /><FieldRef ID="{28cf69c5-fa48-462a-b5cd-27b6f9d2bd5f}" Nullable="True" Type="DateTime" /><FieldRef ID="{1df5e554-ec7e-46a6-901d-d85a3881cb18}" Nullable="True" Type="User" /><FieldRef ID="{d31655d1-1d5b-4511-95a1-7a09e9b75bf2}" Nullable="True" Type="User" /><FieldRef ID="{8c06beca-0777-48f7-91c7-6da68bc07b69}" Nullable="True" Type="DateTime" /><FieldRef Name="PublishingRollupImage" Nullable="True" Type="Image" /><FieldRef Name="_Level" Nullable="True" Type="Number" /><FieldRef Name="Comments" Nullable="True" Type="Note" /><ListProperty Name="Title" /><ProjectProperty Name="Title" />]]></property>

(Note: I found the GUID:s of the default fields using the reflector)


After importing the webpart file, the listname and sitename are now available in the xsl-file as ListProperty.Title and ProjectProperty.Title

Insert the following xsl code in ItemStyle.xsl (for more details, see the Heather Solomon or Microsoft guides above):

<xsl:value-of select="@ListProperty.Title" />
<xsl:value-of select="@ProjectProperty.Title" />

There is still one problem I'm trying to solve. The Author is for some reason presented as ID#Name (where ID is a number, specifying the user) when using it in the XSL-file. This can be fixed with the variable below, but I would rather find why the override causes Author to be changed.

<xsl:variable name="Author">
 <xsl:choose>
  <xsl:when test="contains(@Author, '#')">
   <xsl:value-of select="substring-after(@Author, '#')" />
  </xsl:when>
  <xsl:otherwise>
   <xsl:value-of select="@Author" />
  </xsl:otherwise>
 </xsl:choose>
</xsl:variable>

Use it with the following xsl code:
<xsl:value-of select="$Author" />



Update: To enable Audience targeting, we first need to add another field into ViewFieldsOverride. Otherwise, the settings in the webpart won't work:
<FieldRef ID="{61cbb965-1e04-4273-b658-eedaa662f48d}" Nullable="True" Type="TargetTo" />