Wednesday, March 24, 2010

Content Query Webpart Header Footer issue

Scenario:
I have used Content Query Webpart and everytime I learn something but this time I think I found a BUG as OOTB xslt files available with Content Query does not support Header and Footer in fully controlled manner.

Solution:
I have re-adjusted few templates to make it easier for any one to edit.Even though I am dumping here all the changed templates , you can skip all these steps by simple downloading the updated file

ContentQueryMain.xsl for 2007 <- DOWNLOAD (free)

ContentQueryMain.xsl for 2010 <- DOWNLOAD (free, please rename file to ContentQueryMain before Use)

This updated version of ContentQueryMain.xsl supports Header , GroupHeader , GroupFooter and Footer templates.

Output will be something like this :
cqwp

Code:

    <xsl:template name="OuterTemplate.Body">
<xsl:param name="Rows" />
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<xsl:variable name="BeginColumn1" select="string('&lt;td id=&quot;column&quot; width=&quot;')" />
<xsl:variable name="BeginColumn2" select="string('%&quot; valign=&quot;top&quot;&gt;')" />
<xsl:variable name="BeginColumn" select="concat($BeginColumn1, $cbq_columnwidth, $BeginColumn2)" />
<xsl:variable name="EndColumn" select="string('&lt;/td &gt;')" />
<xsl:for-each select="$Rows">
<xsl:variable name="CurPosition" select="position()" />
<xsl:if test="($CurPosition &gt;= $FirstRow and $CurPosition &lt;= $LastRow)">
<xsl:variable name="StartNewGroup" select="@__begingroup = 'True'" />
<xsl:variable name="StartNewColumn" select="@__begincolumn = 'True'" />

<xsl:choose>
<xsl:when test="$cbq_isgrouping != 'True'">
<xsl:if test="$CurPosition = $FirstRow">
<xsl:value-of disable-output-escaping="yes" select="$BeginColumn" />
<!-- New call to the Header template-->
<xsl:call-template name="OuterTemplate.CallHeaderTemplate"/>
</xsl:if>
</xsl:when>
<xsl:when test="$StartNewGroup and $StartNewColumn">
<xsl:choose>
<xsl:when test="$CurPosition = $FirstRow">
<xsl:value-of disable-output-escaping="yes" select="$BeginColumn" />
<!-- New call to the Header template-->
<xsl:call-template name="OuterTemplate.CallHeaderTemplate"/>
<!-- Renamed the existing Header template to group header template -->
<xsl:call-template name="OuterTemplate.CallGroupHeaderTemplate"/>
</xsl:when>
<xsl:otherwise>
<!-- Renamed the existing Footer template to group footer template -->
<xsl:call-template name="OuterTemplate.CallGroupFooterTemplate"/>
<!-- New call to the Footer template-->
<xsl:call-template name="OuterTemplate.CallFooterTemplate"/>
<xsl:value-of disable-output-escaping="yes" select="concat($EndColumn, $BeginColumn)" />
<xsl:call-template name="OuterTemplate.CallHeaderTemplate"/>
<!-- Renamed the existing Header template to group header template -->
<xsl:call-template name="OuterTemplate.CallGroupHeaderTemplate"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$StartNewGroup">
<!-- Renamed the existing Footer template to group footer template -->
<xsl:call-template name="OuterTemplate.CallGroupFooterTemplate"/>
<!-- Renamed the existing Header template to group header template -->
<xsl:call-template name="OuterTemplate.CallGroupHeaderTemplate"/>
</xsl:when>
<xsl:when test="$StartNewColumn">
<xsl:choose>
<xsl:when test="$CurPosition = $FirstRow">
<xsl:value-of disable-output-escaping="yes" select="$BeginColumn" />
<!-- New call to the Header template-->
<xsl:call-template name="OuterTemplate.CallHeaderTemplate"/>
</xsl:when>
<xsl:otherwise>
<!-- New call to the Footer template-->
<xsl:call-template name="OuterTemplate.CallFooterTemplate"/>
<xsl:value-of disable-output-escaping="yes" select="concat($EndColumn, $BeginColumn)" />
<xsl:call-template name="OuterTemplate.CallHeaderTemplate"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>

<xsl:call-template name="OuterTemplate.CallItemTemplate">
<xsl:with-param name="CurPosition" select="$CurPosition" />
</xsl:call-template>

<xsl:if test="$CurPosition = $LastRow">
<!-- Added an additional check to render the group footer only if grouping is enabled : start -->
<xsl:if test ="$cbq_isgrouping = 'True'" >
<!-- Renamed the existing Footer template to group footer template -->
<xsl:call-template name="OuterTemplate.CallGroupFooterTemplate"/>
</xsl:if>
<!-- Added an additional check to render the group footer only if grouping is enabled : end -->

<!-- New call to the Footer template-->
<xsl:call-template name="OuterTemplate.CallFooterTemplate"/>
<xsl:value-of disable-output-escaping="yes" select="$EndColumn" />
</xsl:if>

</xsl:if>
</xsl:for-each>
</xsl:template>

<!-- Added a new template for Header -->
<xsl:template name="OuterTemplate.CallHeaderTemplate">
<!-- Wrapper div : start ( See CallFooterTemplate for closing node tag )-->
<xsl:variable name="test" select="string('&lt;div id=&quot;test&quot;&gt;')" />
<xsl:value-of disable-output-escaping="yes" select="$test" />
<div id="mainHeader">Main Header ( Locate me in ContentQueryMain.xsl file to change me )</div>
</xsl:template>


<!-- Renamed template , was originally names as CallHeaderTemplate -->
<xsl:template name="OuterTemplate.CallGroupHeaderTemplate">
<div id="header">Group Header ( Locate me in ContentQueryMain.xsl file to change me )</div>
<xsl:apply-templates select="." mode="header">
</xsl:apply-templates>
</xsl:template>


<!-- Renamed template , was originally names as CallFooterTemplate -->
<xsl:template name="OuterTemplate.CallGroupFooterTemplate">
<div id="footer">Group Footer ( Locate me in ContentQueryMain.xsl file to change me )</div>
</xsl:template>

<!-- Added a new template for Footer -->
<xsl:template name="OuterTemplate.CallFooterTemplate">
<div id="mainFooter">Main Footer ( Locate me in ContentQueryMain.xsl file to change me )</div>

<!-- Wrapper div : end ( See CallHeaderTemplate for starting node tag)-->
<xsl:variable name="test" select="string('&lt;/div&gt; ')" />
<xsl:value-of disable-output-escaping="yes" select="$test" />

</xsl:template>

8 comments:

Anonymous,  March 30, 2010 at 5:15 AM  

GREAT POST! :-)

Ilkka October 20, 2011 at 12:37 AM  
This comment has been removed by the author.
westerdaled February 23, 2012 at 12:06 PM  

Hi


Good post. I had mixed results with this. added it to my existing
ContentQueryMain.xls. I noticed that although the place holders are there, I still need to a bit of work to get them populated with actual header I am using. In my case I used the default banded header style but added extra code to create tabular list view for start of each group. I can send you the final xslt for your comments if you like.

Sandeep K Nahta February 23, 2012 at 12:17 PM  

sure , it will help some else save some time :)

Anonymous,  March 2, 2012 at 5:00 AM  

Nice!! Thanks