Content Query Web Part (CQWP) and events / calendars lists usinginconsistent internal column names

The Content Query Web Part is by far one of the most versatile out-of-the-box web parts that SharePoint 2010 provides for allowing the user to aggregate data from a single list or multiple lists within a site and subsites or even site collection wide.

When aggregating data though from an Calendar list type and using a custom XSL ItemStyle, you may have found some oddities with the list columns “Start Time” and “Description” if you desired to display either of these two columns in your web part.


If you would like to skip directly to the solution, you can do so here:

DISCOVERY

If you analyze the column architecture of the list, you will notice that the list uses the Event Content Type and if you were to look the internal names for “Start Time” and “Description” columns, you would find:

Internal Field Name in List Settings

Table 1 List Level Content Type Column Names:

Column Name Display Name Internal Name
Start Time Start Time EventDate
Description Description Description

Internal Field Name for List Content Type

When you further analyze the column names for the actual List Content Type, you would find the same thing. Although, if you look at the column names for the Site Content Type for “Event”, you find something completely different for the internal:
Table 2 Site Level Content Type Column Names:
Column Name Display Name Internal Name
Start Time Start Time StartDate
Description Description Comments

Internal Field Name for Site Content Type

The beauty of the CQWP is that the user can decide what scope the web part should use when aggregating data. As mentioned above, they can choose to set the scope to a single list or multiple lists. This setting though is where the problem occurs when aggregating Calendar list data.
When you scope your CQWP directly on a list, it will return the “Start Time” and “Description” fields via XML using the internal names of the columns as defined at the list level “Event” content Type (Table 1 above).
ALTHOUGH, if you scope your CQWP to the Site Collection or a specific Site and Subsites, it will return the “Start Time” and “Description” fields using the internal names of the columns as defined at the site level “Event” Site Content Type (Table 2 above).
So this raises a question of, “How can I display the Start Time and/or Description accurately in a single ItemStyle in my XSL and still allow the user to change the scope of the CQWP when the Start Time and/or Description column name can change based on that scope????”.

1. The first step is to ensure your custom .webpart file includes a reference in the “CommonViewFields” property to both of the internal column names for each of the “Start Time” and “Description” columns. For the example in this solution, we will focus on the “Start Time” column, but the same actions can be applied on the “Description” column as well.

CommonViewFields Property in .webpart fille.
At this point, depending on the scope of your CQWP, for the “Start Time” value, only one of it’s internal names will be returned with populated with a value in the XML and the other will be blank.

For example, if you set the scope of your CQWP to aggregate all of the events from the entire site collection, the CQWP will return your “Start Time” value in a column named “StartDate” (Table 2 above) and therefore the “EventDate” column name will be blank.

If the scope is set directly on a list instead, then the “Start Time” value will be returned in a column named “EventDate” and the “StartDate” column will be blank.

2. Armed with the knowledge in step 1 above, we can create a custom XSL variable that will look to see which column name is being used and then provide the accurate “Start Time” value.

    
<xsl:variable name="CalendarStartDate">
<xsl:choose>
<xsl:when test="@StartDate != ''">
<xsl:value-of select="@StartDate"/>
</xsl:when>
<xsl:when test="@EventDate != ''">
<xsl:value-of select="@EventDate"/>
</xsl:when>
</xsl:choose>
</xsl:variable>

The XSL variable starts with the Site Content Type Event column name “StartDate” (Table 2 above) and checks to see if it has any value. If there is a value in this column, that value is returned.

The same test is then applied checking for a value in the List Level Content Type Event column name “EventDate”. If there is a value in this column, then value is returned.

Because we know that dependent on the scope of the CQWP, only one of these column names are used at a time.

NOTE: If you are concerned that both “<xsl:when>” statements will return true, you could replace one of the “<xsl:when>” statements with an “<xsl:otherwise>” statement and know for sure only one will ever be returned. Based on my tests though, I felt this was not necessary. Feel free to let me know if you encounter a scenario that would warrant the use of the “<xsl:otherwise>” instead of using the two “<xsl:when>” statements.

    UPDATE:


    You may have experienced that when you implement the solution in this blog post, you begin experiencing errors when you try to edit your web part and modify the web part properties on a page.

    There is a solution and I have documented it in a separate blog post entitled “Error when editing the (CQWP) Content Query web part properties that is scoped on an Events / Calendar list in SharePoint 2010“.



    Share:

    Author: David Warner II

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.