SharePoint Content Query web part like a SharePoint List View

I have been working on a solution to aggregate documents from sub sites to the top level site of SharePoint with the out of the box features. To accomplish this you will have to work with the Content Query web part of SharePoint.

The Content Query web part works great but it doesn’t look like a list view and that was the styling I wanted. So let’s get working and create the styling we want.

To get the content query web part to look like a list view you have to get trough the following steps:

Step 1

Enable the “SharePoint Server Publication Infrastructure” feature if you haven’t already got the feature enabled. This feature makes sure you have the “Content Query” web part available within the web part gallery.

SharePoint-Server-Publishing-Infrastructure

Step 2

Go to the page were you would like to display the “Content Query” web part and place it on the page. The web part can be found under the “Content Rollup” category.

Edit the web part and specify the query you would like to preform. If you have specified the query save the web part and export it.

Note: if you want to query a certain type of content and this content is available within the subsites but not on the root you can not use the UI to create the query. If you want to use the UI you have to make the type available within the root site.

Webpart-Export

Step 3

You can add your custom columns to the query. This can be accomplish by editing the “CommonViewFields” property of the web part:

<property name="CommonViewFields" type="string">LinkFilename,Text;Title,Text;</property>

The value of the property must be in the following format [InternalName],[Type];[InternalName],[Type];

Step 4

If you would like to read out those properties by a more meaningful name you can change the “DataColumnRenames” property. This property will take care of the renaming for us.

<property name="DataColumnRenames" type="string">Title,Title;LinkFilename,Name</property>

The value of the property must be in the following format [InternalName],[New Name];[InternalName],[New Name];

Step 5

Now that we have defined our columns we will need to edit the xslt template to render the columns. We will have to open SharePoint Designer and open the Style Library of the site.

SharePoint-Designer

First we will edit the “ContentQueryMain.xsl” file. Within the file find the following line (79):

<xsl:template name=”OuterTemplate.Body”>

Within this template a call will be made the ItemTemplate. Within the call we will have to pass a new parameter called “LastRow” so that we know when we will have to close our grid.

For this search for the following lines (128):

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

And change it to:

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

Now that we pass the parameter we also have to change the template to accept the parameter.

Go to line 147 and you see the “CallItemTemplate”. Copy the second line and past it directly beneath it and make it look like this:

<xsl:template name="OuterTemplate.CallItemTemplate">
<xsl:param name="CurPosition" />
<xsl:param name="LastRow" />

Because we want to use this within our custom item template we also have give the parameter through to the template by adding a when statement just before the <xsl:otherwise> within the CallItemTemplate:

<xsl:when test="@Style='SPGrid'">
 <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>

In this statement we specify that it only has to pass-through the parameter when the item template is SPGrid. So our custom template is going to be called “SPGrid”.

Step 5

Now it is  time to edit the “ItemStyle.xsl” file. Within this file we add our custom xslt item template:

<xsl:template name="SPGrid" match="Row[@Style='SPGrid']" mode="itemstyle">
    <xsl:param name="CurPos" />
    <xsl:param name="Last" />

    <xsl:variable name="SafeImageUrl">
      <xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
        <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="SafeLinkUrl">
      <xsl:call-template name="OuterTemplate.GetSafeLink">
        <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="DisplayTitle">
      <xsl:call-template name="OuterTemplate.GetTitle">
        <xsl:with-param name="Title" select="@Title"/>
        <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="LinkTarget">
      <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
    </xsl:variable>

    <xsl:variable name="tableStart">
      <xsl:if test="$CurPos = 1">
       <![CDATA[ 
        <table width="100%" class="ms-listviewtable" cellpadding="1" cellspacing="0" border="0">
          <tr class="ms-viewheadertr ms-vhltr">
            <th class="ms-vh-icon"></th>
            <th class="ms-vh2">Name</th>
          </tr>]]>   
      </xsl:if>
    </xsl:variable>

    <xsl:variable name="tableEnd">
      <xsl:if test="$CurPos = $Last">
        <![CDATA[ </table> ]]>
      </xsl:if>
    </xsl:variable>

    <xsl:value-of select="$tableStart" disable-output-escaping="yes"/>
    <tr class="ms-alternating ms-itmhover">
      <td class="ms-vb-icon">
          <xsl:if test="string-length(@DocumentIconImageUrl) != 0">
            <div class="image-area-left">
              <img class="image" src="{@DocumentIconImageUrl}" title="" />
            </div>
        </xsl:if>
      </td>
      <td class="ms-vb2">
        <a href="{$SafeLinkUrl}" title="{@LinkToolTip}">                  <xsl:value-of select="$DisplayTitle"/>
        </a>
      </td>
      <td>
        <xsl:value-of select="@Title"/>
      </td>
    </tr>
    <xsl:value-of select="$tableEnd" disable-output-escaping="yes"/>
  </xsl:template>

The displayed xslt has to be placed just above the closing </xsl:stylesheet> tag. This xsl creates a template for each item and will display the icon , the title link and the title of the document.

Result

21 comments

  • Hi

    This is really useful. I have applied this a custom docu library and the only things is I can’t get the Group by to work. In my case
    I get

    Group heading 1

    Group heading 2

    Nicely formatted table …..

    I think the issue is with the ContentQueryMain.xls

    Daniel

  • Awesome Post. Works like a charm. Thanks for the walkthrough
    Now the struggle to customize it to my needs.

  • Hi,

    Can we change the look and feel of CQWP to have same look and feel of Views/lists, to be able to see Document properties and Edit Functionalities.

    • Hi Shashi,

      You can but that will need some work. You can get the context menu to work within your view or create one yourself.

      • You mention the edit functionalities, have you guys ever achieved this? I would like for the documents to be able to:
        1. Open in Browser
        2. Have the Document Drop Down functionality with Download, Edit, Send

  • Nice post, but where is paging like we have in XSLT view webpart have.

    if you have solution kindly reply, urgent solution needed.

  • Hi,
    Nice post! Can you help me to do paging of content query webpart? Thanks!

  • Thank you this works really well on SP online (2013). Steps 3 and 4 were not necessary in my case, just modifying the two XSL files.

  • Hi,
    I am a bit stuck on “Type” in step 3. I am using SP 2013. I have drop down/choice and rich text fields. I am addinh exact type name, but it doesn’t seem to work.
    Do i have to use square brackets or something?

    Thanks!

  • Maik, thanks for this tutorial. It has worked quite well. However I am also facing the same issue as Daniel (posted here on October 25, 2012). I’m by no means an experienced SP developer, but agree that the issue looks like it lies somewhere in the ContentQueryMain.xsl since this is where all the XSL tags related to grouping appear to reside.

    Do you know how to resolve this issue so that the items are called within their group and not at the end of the list?

    Thanks in advance!

    P.S.: At first the tutorial above didn’t work for me. As I said, I am new at developing SP and essentially self-taught. I figured out that I needed to update the ItemStyle property in the exported CQWP from Default to SPGrid as shown below.
    SPGrid

  • How could I add a custom hyperlink field into this table? I am using a custom list that uses a custom content type and I want to display the Title field, the Description field and the the title of the hyperlink field.

    Thanks in advance!

    • Hi Sean,

      You will need to adjust the item template to include another column with the information from the hyperlink.

      If you need more help send me a mail.

  • Hi Maik,

    This is a very useful workaround.

    We also have made some changes to the ItemStyle.xsl file for the custmo style SPGrid in order to display a few extra columns using the Content Query Web Part.

    The thing is, site collection admins can perfectly see the changes as expected. For other users I first had to republish the item style again as there was some caching issue. Secondly, the normal users get a complete different output. They see the new columns, however the rendering still doesn’t happen properly. Users see LI elements for the items whereas the template is based on TABLE elements and adds some headers too. What is causing this and how can we get this resolved?

    See also http://sharepoint.stackexchange.com/questions/84989/spgrid-itemstyle-custom-changes-not-displayed-for-normal-users

    Many thanks!

  • Pingback: Show Multiple Columns in Content Query Web Part | SNR SharePoint Blog

  • Maik,

    Thanks for the post.
    I followed the entire article and created required files on SharePoint 2013.
    i`m following the solution for custom lists and not document library.
    My understanding the logic should work and it should show the basic table.
    But it doesnt shows the following :

    a) Table Header Names (Name, Document)
    b) Is it possible to have the link show the URL of the Site where the SharePoint List is stored rather the document link, as in my case the user (non techies) would like to see the Site where the file is hosted.

    Any assistance will be deeply appreciated.

    Cheers,

    Jason

    • Hi Jason,

      Most of the time everything is possible, but I’m not totally sure if you can display the site url, I think you will need to get that information from the document url it self.

      The information you have regarding the items its just the item metadata of the documents, and every property there is can be used in the template.

  • Hi ,
    This is really useful and saves my time.
    Thanks a lot for your good work.
    Thank you.

Leave a Reply

Your email address will not be published. Required fields are marked *