Wednesday, February 03, 2010

SharePoint Custom User Field Rollup

Today I made a custom "Person or Group" site column to store the Publisher of an article, and then tried to show a link to the selected user in the content query web-part (CQWP). This is quite easy for the Author (created by) field and the Editor (modified by) fields that CQWP provide by default, but not intuitive for a custom user field type.

<Field ID="{r-g-u-i-d}" Name="ContosoPublisher" Type="User" DisplayName="Article Publisher" List="UserInfo" Required="FALSE" ShowField="ImnName" UserSelectionMode="0" UserSelectionScope="0" Group="Contoso Publishing Columns" SourceID="http://schemas.microsoft.com/sharepoint/v3" />

I added "ContosoPublisher,User;" to the CQWP <CommonViewFields> property and then displayed @ContosoPublisher in the XSL. To my surprise, the returned value lacked the ID;#VALUE lookup encoding of the name, i.e. there was no "1;#KjellSJ" only "KjellSJ".

Then, I tried to use both Lookup and Text as the type, getting only the name and nothing. As it turns out, using the URL field type like this "ContosoPublisher,Url;" will result in the returned data having the expected format. Use this XSL to display the user name as a link to the public user profile page:

<xsl:variable name="PublisherID">
<xsl:value-of select="substring-before(string(@ContosoPublisher) ,';#')" />
</xsl:variable>
<xsl:variable name="PublisherName">
<xsl:value-of select="substring-after(string(@ContosoPublisher) ,';#')" />
</xsl:variable>
. . .

<span class="publishedby">
<a href="/_layouts/userdisp.aspx?ID={$PublisherID}">
<xsl:value-of select="$PublisherName" />
</a>
</span>

Note the use of the relative /_layouts/ link, as this virtual page is available in all SharePoint subsites. Also remember that the user ID number is only valid within the site-collection's UserInfo list. You cannot pass this ID between site-collections as the same user account typically has different IDs in different site-collections.