In your Office Sharepoint Server 2007 site you can display a dynamic view of content on a page by using the Content Query Web Part. This post from Tyler Butler and this one from Heather Solomon helped me on my way.
With the help of these blogs it is not very hard to create a single column presentation of your content. Every single item gets processed by the ItemStyle.xsl found in the Style library / XSL Style sheets section. But if you would like to order your content dynamically in 2 columns you will need to build some extra coding in the ItemStyle.xsl and in the ContentQueryMain.xsl, which is also found in the XSL Style sheets section.
The default templates present our data in a single column:
But for some sites we might want to show our data inside 2 columns:
I will not make use of the header.xsl file in this example because it makes it harder to read and in my opinion it is better to keep all rendering code of a style accessible in one spot for future editing.
If we want to be able to render 2 columns, the ItemStyle.xsl must know the item number which is currently being processed. To generate valid html we must also know when we are processing the last item, otherwise we might finish our table with an incorrect number of <td> tags. To provide our style in the ItemStyle.xsl with the 2 required parameters open up the ContentQueryMain.xsl file in your favorite text editor. Search for the tag “<xsl:call-template name=”OuterTemplate.CallItemTemplate”>” and modify it in the following way:
<xsl:with-param name=”CurPosition” select=”$CurPosition” />
<xsl:with-param name=”LastRow” select=”$LastRow” />
</xsl:call-template>
This will pass the CurPosition and LastRow parameter to the OuterTemplate.CallItemTemplate which we must alter to accept the LastRow parameter. Search for the “<xsl:template name=”OuterTemplate.CallItemTemplate”>” template section and make sure you have the CurPostion and LastRow parameters in the top section of the template:
<xsl:param name=”CurPosition” />
<xsl:param name=”LastRow” />
<xsl:choose>
<xsl:when test=”@Style=’Multicolumn_example'”>
<xsl:apply-templates select=”.” mode=”itemstyle”>
<xsl:with-param name=”CurPos” select=”$CurPosition” />
<xsl:with-param name=”Last” select=”$LastRow” />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select=”.” mode=”itemstyle”>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Inside the same template section add a <xsl:when> node for every template that should access the new parameters. Take a look at the <xsl:when test=”@Style=’Multicolumn_example'”> section to see how the parameters are provided.
Now we are finished with the changes in the ContentQueryMain.xsl file and it’s time to open up our ItemStyle.xsl file to add the Multicolumn_example style.
In the example below I created a tableStart variable which will only render when our CurPos equals 1. This variable will add a table tag. The tableEnd variable will render the closing tags when our CurPos equals the Last item number. Inside the tableRowItem variable we place the html content that is used for the single item. The content of this item is the same for the left and for our right column. The logic that renders the right and left column is put into the tableRow variable.
<xsl:param name=”CurPos” />
<xsl:param name=”Last” />
<xsl:variable name=”tableStart“>
<xsl:if test=”$CurPos = 1″>
<![CDATA[<table width=”100%” border=”0″>]]>
</xsl:if>
</xsl:variable>
<xsl:variable name=”tableEnd“>
<xsl:if test=”$CurPos = $Last”>
<![CDATA[</table>]]>
</xsl:if>
</xsl:variable>
<xsl:variable name=”tableRowItem“>
<![CDATA[<td>]]><xsl:value-of select=”@Title”/><![CDATA[</td>]]>
</xsl:variable>
<xsl:variable name=”tableRow“>
<xsl:choose>
<xsl:when test=”$CurPos mod 2 = 1″>
<![CDATA[<tr>]]>
<xsl:value-of select=”$tableRowItem” disable-output-escaping=”yes”/>
<xsl:if test=”$CurPos = $Last”>
<![CDATA[<td></td></tr>]]>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select=”$tableRowItem” disable-output-escaping=”yes”/>
<![CDATA[</tr>]]>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select=”$tableStart” disable-output-escaping=”yes”/>
<xsl:value-of select=”$tableRow” disable-output-escaping=”yes”/>
<xsl:value-of select=”$tableEnd” disable-output-escaping=”yes”/>
</xsl:template>
Inside the tableRow variable I made use of the mod calculation “$CurPos mod 2 = 1” to decide in which column the content should be processed. It returns false if the current position can be divided by 2 and true if it can’t. We add an extra “$CurPos = $Last” check in the left column to render an empty right column when it is the last item. On the bottom of our template we combine all logic by calling the defined variables.
That’s it! Now select the “Multicolumn_example” style in your content query tool webpart and you should see your content divided over 2 columns. Click here to download the modified xsl files in this example.
[update 15-11-2007]
Thomek submitted a very simple method to create a multi-column result which works fine in simple situations. I tried it at our customer, but the results where not 100% correctly. I suggest that you can always try first, if this method works in your situation, as it’s a fast solution and doesn’t require editting in the xsl files:
- Go to the Presentation properties of the CQWP and set Grouping and Sorting to Title
- Set the number of columns to 2 or more
- Go to the Styles properties of the CQWP and set the Group style to Whitespace
October 5, 2007 at 1:05 pm
Maybe it’s just the way i’ve done this, but don’t you loose the hyperlink to the content when implementing this?
October 5, 2007 at 2:01 pm
@Richard. Yes but that’s only to keep the demo as simple as possible.
Just look at the other templates in the ItemStyle.xsl. For example copy the SafeLinkUrl, LinkTarget and DisplayTitle variables from the “TitleOnly” template and then paste
<xsl:value-of select=”$DisplayTitle” />
</a>
inside my tableRowItem variable to make it work with the hyperlinks.
October 31, 2007 at 2:27 am
hey is there anyway to create more than 2 columns. I want to create 5 column for an image gallery. Any help would be much appreciated.
November 1, 2007 at 2:39 pm
I am using your tutorial and for some reason the CQWP is not displaying the data in columns correctly. It is like the xsl is not finding the first link in my list, therefore never creates the opening tag when $CurPos = 1
because of that the displayed data does not look good.
any ideas?
November 1, 2007 at 2:43 pm
oh also, is it possible to have the data displayed in the two columns with Record 1-10 on the left columb and Records 11-20 on the right column?? not like
1 2
3 4
5 6
7 8
9 10
but like
1 6
2 7
3 8
4 9
5 10
thanks!
November 1, 2007 at 9:03 pm
@chia weng yan. Yes it is possible. You have to play around a bit with the mod function. Click here for a 5 column example file. The table closing is not completely right yet, but it should be rendered correctly.
November 1, 2007 at 9:36 pm
@jeff. I can only check what goes wrong when i can see your xsl file. Just e-mail it to me if you want to.
If you would like the items to be displayed in that order, you have to generate it into 2 tables. You start the second table when you reached 50% of the items. Click here to download a full working example.
November 13, 2007 at 4:33 pm
Can’t you achieve this whole thing by simply using the presentation properties from the CQWP?
– you group by Title
– set the number of columns to 2
– set the Group Style to Whitespace so the Group Title is not displayed
November 15, 2007 at 9:07 am
@Thomek. Thanks for your suggestion. I tried it and for a lot of situations it works fine. I added your tips to the post.
September 3, 2008 at 4:11 pm
I thought I knew SharePoint MOSS 2007, but it looks like I’m a total n00b.
Today I installed SharePoint Designer 2007 for the first time.
I looked for ContentQueryMain.xsl and ItemStyle.xsl but I couldn’t find those files. In fact, I couldn’t find any .xsl file at all!
Could you please give me a gentle nudge in a good direction?
September 4, 2008 at 1:00 pm
@Amedee: Hi Amedee,
If you have a publishing site you can visit the “View all site content” page and then open the “Style Library” list. In there you will see a “XSL Style Sheets” folder which contains the xsl files.
You can also use Sharepoint designer to open the site. There you will find the “Style Library” folder inside the root of the site. I believe your site has to be a Publishing Site to have these folders.
September 5, 2008 at 9:18 am
Ok, my site probably isn’t a Publishing Site. Thank you.
I think I found some other way to do what I want, with SharePoint Designer. I feel a bit like that Frenchman who deciphered the ancient Egyptian hieroglyphs using only a stone tablet. I’m learning an entirely new and (for me) alien language…
September 22, 2008 at 10:40 am
Thanks a lot. Made some things clear to me.
December 11, 2008 at 6:49 am
I am using the the grouping in Content query webpart in MOSS. The webpart shows only 5 groups, but there is more than 5 groups. The rest of the groups are displayed at the top of the webpart. The grouping is not working properly. How can I make the Content query web part shows more then 5 groups? Thanks
January 29, 2010 at 4:33 pm
I have followed youre steps and followed youre advies on linked title, but i can’t get it working.
Is it possibel to give me a littel bid of advies?
Code:
<![CDATA[]]>
<![CDATA[]]><![CDATA[]]>
<![CDATA[]]>
December 27, 2011 at 12:12 pm
Hey this is the nice article but i am not getting how to add 6 columns in the same.Getting hell errors .
Please help me out with this 🙂