It is a common scenario to have the need to render the last row item of the Content Query Web Part (CQWP) a bit different from other row items. You might be positioning div's and containers with margins and you may want the last row item to have different styles, exclude the last delimiter or include an extra link. Here is how I implemented this requirement by just using the CQWP with some XSL changes:
Solution Structure
The CWQP uses a few default XSL stylesheets to render its output: ItemStyle.xsl, ContentQueryMain.xsl and Header.xsl located in “/Style Library/XSL Style Sheets”. These items get deployed by the MOSS Publishing Feature. For this exercise I had to modify ItemStyle.xsl and ContentQueryMain.xsl, but instead of modifying the default files I created copies of them and included them in a feature that also deploys my instance of the CQWP.
My feature deploys the required XSL files to a custom folder under “XSL Style Sheets”, and the following properties of my CQWP are modified to reference those XSL files rather than the default ones.
<property name="HeaderXslLink" type="string">/Style Library/XSL Style Sheets/MOSSIGWebPart/MOSSIGWebPartHeaderStyle.xslt</property><property name="MainXslLink" type="string">/Style Library/XSL Style Sheets/MOSSIGWebPart/MOSSIGWebPartMainStyle.xslt</property><property name="ItemXslLink" type="string">/Style Library/XSL Style Sheets/MOSSIGWebPart/MOSSIGWebPartItemStyle.xslt</property>
XSL modifications
Inside the ContentQueryMain.xsl file there is a section that renders the body of the web part. The template is called “OuterTemplate.Body”. The template instantiates a convenient variable $CurPosition, and it passes it onto the item template “OuterTemplate.CallItemTemplate”.
<xsl:call-template name="OuterTemplate.CallItemTemplate"> <xsl:with-param name="CurPosition" select="$CurPosition" /></xsl:call-template>
The inconvenience is that inside "OuterTemplate.CallItemTemplate" the parameter is not actually passed to the custom template inside the ItemStyle.xslt file:
<xsl:otherwise> <xsl:apply-templates select="." mode="itemstyle"> </xsl:apply-templates></xsl:otherwise>
To pass it through to the ItemStyle.xslt template I included the CurPosition parameter:
<xsl:otherwise> <xsl:apply-templates select="." mode="itemstyle"> <xsl:with-param name="CurPosition" select="$CurPosition" /> </xsl:apply-templates></xsl:otherwise>
I made a matching declaration in my customised ItemStyle.xsl file to accept the parameter:
<xsl:template name="MOSSIGStyle" match="Row[@Style='MOSSIGStyle']" mode="itemstyle"> <xsl:param name="CurPosition" />
I can then use this variable throughout my item template. A simple check can determine if the current row is the last row:
<div id="linkitem" class="m-item"> <xsl:attribute name="style"> <xsl:if test="not($CurPosition = 3)">margin-top:10px;</xsl:if> <xsl:if test="$CurPosition = 3">margin-top:0;</xsl:if> </xsl:attribute>
I always had 5 items returned from query. Similar to the above approach you can bring the total row count if you have a situation where the amount of returned rows changes. OuterTemplate.Body privides the $LastRow parameter.
<xsl:with-param name="LastRow" select="$LastRow" />
Has anyone approached this in any other way?