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 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