Create a multi column layout with the content query tool web part
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
Maybe it’s just the way i’ve done this, but don’t you loose the hyperlink to the content when implementing this?
@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.
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.
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?
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!
@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.
@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.
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
@Thomek. Thanks for your suggestion. I tried it and for a lot of situations it works fine. I added your tips to the post.
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?
@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.
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…
Thanks a lot. Made some things clear to me.
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
Pingback: links list wrapping to multiple columns | keyongtech January 18, 2009
[...] But I’m afraid it will fall outside the scope. Anyway I Googled a bit and found this page: http://edwin.vriethoff.net/2007/09/1…tool-web-part/ He talks about editing the file ItemStyle.xsl. Where can I find that file? I tried opening the [...]
Pingback: SPPD077 SharePointPodcast - SharePointPodcast - SharePointCommunity June 9, 2009
[...] Create a multi column layout with the content query tool web part [...]
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[]]>
Pingback: curpos April 5, 2010
[...] is able to modify existing TextBox controls to display wavy red underlinesEdwin Vriethoff Create a multi column layout with the …A blog with tips and info about .NET, C# , Sharepoint en BizTalk written by Edwin Vriethoff … The [...]
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