Step by step tutorial : using the Content Query Web Part /Enhanced Query Web Part (MOSS 2007)

 

Logo-Devoteam-Groupe

Introduction

One of the most important web part provided with MOSS 2007 is the Content Query Web Part which allows to “rollup” list items.This web part is very flexible and extremely fast

You will find a lot of descriptions of  this Web Part in web sites and blogs like the Sharepoint team blog, ,Heather Solomon and Paul Galvin. I recently evaluated the Enhanced Query Web part code from Codeplex that displays data in html tables, so I will quickly describe what I’ve learnt plus new stuff.

My step by step code can be downloaded here.

Step1. Create the contacts list

 

First off, let’s create a list of contact named “devoteamcontacts” by using the demo-contacts.stp template file provided in the folder step1 of the solution.zip file (import the .stp file in the list templates and create a list instance).

image

Just to make sure everything works correctly, you can add a Content Query Web part to display the data :

In the Query property :

image

In the Presentation property :

image

I’ve renamed the Title step1 :

image

So far so good!

The Content Query Web part cannot fetch data across site collections ; if you really need it, you can take a look at the Lightning Conductor Web Part.

Step 2.Retrieving raw data

Open you web site with Sharepoint Designer and go the XSL Style Sheets under the Style Library, the CQWP uses 2 important stylesheets :

image 

The Content Query Web part parses the data from the data source and send the data to an xsl template. The “bootstrapper” is the template OuterTemplate in ContentQueryMain.xsl , which among others, defines several interesting variables like the number of rows (“Rows”) and the current row) .

Just to illustrate the raw data the CQWP generates, I suggest that make a copy of ContentQueyMain.xsl, you open up ContentQueryMain.xsl, and find the root template :

image

Replace it with xslt code that parses everything :

image

Also, switch the method attribute of the <xsl:output …> from html to “xml” and indent from “no” to “yes” like this :

image

Then the CQWP will display this :

image 

The link between the raw data and the variables defined in ContentQuerymain.xsl is obvious

image

You will find a raw version of ContentQueryMain.xsl in the step2 folder of the solution.zip file.

Replace the modified version of ContentQueryMain.xsl with the backuped version.

Step 3. Display and additional field :  Company

 

Company is provided with the Contacts list, no need to add it !

Each web part instance in the web part page has a set of properties coming from  the Web part gallery and customized at the instance level. As described the Sharepoint sdk, if we want to display an additional field, we have to declare it in the CommonViewFields property like this :

<property name="CommonViewFields" type="string">Company, Text</property>

The way to achieve this is quite simple : export  the .webpart file and name it step2.webpart:

image

 

Modify the file by locating CommonViewFields and change it accordingly (if you want to display several fields, they must be separated with semi columns).

Import the new WebPart file  and add a new web part to the page to take the change into account; to achieve this : move the page to edit mode->Add a web part to a web part zone->and in the web part gallery, click on “Advanced Web Part gallery and options” (a bit tricky to find ) :

 

image

Then in the next window (“Add Web Parts”), click on the “Browse” option :

image

Select “Import” :

image

Import you .web part file and drag and drop the associated web part just below the previous web part; change its title to “Step3”.

image

As you noticed, nothing seems to be changed. Indeed we still need to put our fingers into some xslt code to display the “Company” field.

Sharepoint Designer is our friend here (at least in the “development” phase); 

image

At a certain point, OuterTemplate.CallItemTemplate is invoked

image

By default, “CallItemTemplate” is resolved to fetch the file ItemStyle.xsl (this can be changed we’ll see that later).

If (as we did), you choose The style “Title Only”, the following in “ItemStyle.xml” will be invoked :

image

Just to verify this, add the following message:

image

If you refresh you page, you will get this :

image

Let’s clean up the previous code ‘(“Hi There”) and add our own Custom template just below the template “TitleOnly”; Just copy and paste the template “TitleOnly” and rename it as “devoteamstyle”.

image

This is not the good practice as you’ll see later, there will be an alternative; Refresh the page, and reload the item style list in the web part property page; our custom style will show up :

image

Now we need to make sure the Company field is parsed by the web part; to display the value of all fields fetched by the web part, add the next xslt (in bold) fragment in your custom style style.

(you can also you the raw xslt code used in step2)

<xsl:template name="devoteamstyle" match="Row[@Style=’devoteamstyle]" mode="itemstyle">
            <xsl:for-each select="@*">
                <br><xsl:value-of select="name()" /></br>
            </xsl:for-each>
<xsl:variable name="SafeLinkUrl">

….

 

If you refresh the page, you will notice the Company field in the Web part “Step3”, but not in “Step1”.

Let’s remove the code, and  try to display the Company field :

image

If we take a look at the rendered page, we will get this :

image

 

Step 4. Displaying Content Query Web Part fields in a table

 

Go back contentQueryMain.xsl and find the template <xsl:template name="OuterTemplate.Body">; as mentioned before, this template invokes another template “OuterTemplate.CallItem” for each row found. Only one parameter is provided to this template (CurPosition), we need to supplement it with an indication about  the index of the last row; also go to the definition of the template ”OuterTemplate.CallItemtemplate”  and define the new LastRow parameter:

image

Just below provide the paameters to the “devoteamstyle” item :

image

Now, we need to create our table and this will happen in our devoteamstyle in itemStyle.xsl; the table will only be created one time; however “devoteamstyle” will be invoked for each row.

In the devoteamstyle, provide 2 new params to host the current index and the number of rows:

image

Now, we can create the table by declaring 2 variables : “tableStart” and “tableEnd”

    <xsl:variable name="tableStart">

      <xsl:if test="$CurPos = 1">

        <![CDATA[

        <table>

            <tr>
                       <td align="left">

                    <b>Title</b>

                </td>

                <td align="left">

                    <b>Company</b>

                </td>

            </tr>]]>

      </xsl:if>

    </xsl:variable>
    <xsl:variable name="tableEnd">

      <xsl:if test="$CurPos = $LastRow">

        <![CDATA[</table>]]>

      </xsl:if>

    </xsl:variable>

image

Now, let’s make use of tableStart, tableEnd  and display our data in rows and columns as described below :

image

You will get something like this :

image

If you want a more Sharepoint like look and feel, you need to modify your table definition by creating a child table for each column (plus an extra column as a separator) and use appropriate css styles:

 

<![CDATA[
<table width="100%" class="ms-listviewtable" border=0 cellspacing=0 cellpadding=1 dir="None">

<!–HEADER–>
<tr class="ms-viewheadertr" VALIGN=TOP>

<th nowrap scope="col" class="ms-vh2"><div style="width:100%;position:relative;left:0;top:0;">
<table style="width:100%;" CtxNum="1" height="100%" cellspacing=1 cellpadding=0 class="ms-unselectedtitle">
<tr>
  <td width="100%" Class="ms-vb" nowrap>
  Name
  </td>
  <td style="position:absolute;">
  </td>
</tr>
</table>
</th>

<th nowrap scope="col" class="ms-vh2"><div style="width:100%;position:relative;left:0;top:0;">
<table style="width:100%;" CtxNum="1" height="100%" cellspacing=1 cellpadding=0 class="ms-unselectedtitle">

<tr>
  <td width="100%" Class="ms-vb" nowrap>
  Company
  </td>
  <td style="position:absolute;">
  </td>
 
</tr>
</table>
</th>

</tr>        ]]>

 

You should therefore get something like this :

image

The problem: Custom stylesheets

One of the common problem with the basic Content Query web part is that developers usually modify existing files xslt that may be used by other web parts, sites, site collections..

We can define our own stylesheets by setting up the properties HeaderXslLink, ItemXslLink and MainXslLink:

HeaderXslLink = "/Style Library/XSL Style Sheets/devoteamHeader.xsl"
ItemXslLink = "/Style Library/XSL Style Sheets/devoteamItem.xsl"
MainXslLink ="/Style Library/XSL Style Sheets/devoteamMain.xsl"

But then, it may be easier to use the Extended Content Query Web part.

Crash of the CQWP when one site column has no display name

My team recently noticed that in some situation the CQWP crashes with the following error:

“Key cannot be null.
Parameter name: key”

This happens when one site column has no display name; more details here.

 

Step 5. The Extended Content Query Web part (ECQWP)

 

We can override the Content Query Web part to specify the fields we want to display and also the style sheets we want to use.

That’s basically what the Extended Content Query Web Part (ECQWP) does :

Download the solution from Codeplex , add it to the solution store and activate the site collection feature.

image

 

Add an instance of the Enhanced Content Query Web part to your Web part page , and set the Query property as we did before. We can enjoy additional properties like Common View Fields (let’s specify the Company Column here, no need to export/re-import a .webpart file anymore), and also Show Context Menus for items; most customers want their objects to be actionable.

 

image

If you apply these settings, you will get this :

image

The objects are actionable; but even if extra fields have been declared, they won’t show up immediately, we still have to add some xsl code.

Custom style sheets

One of the common problem with the basic Content Query web part is that developers usually modify existing files, that may be used by other web parts, sites, site collections and application.

We can easily make use of a custom stylesheet by defining it in  the property ItemXslLink and we can also provide our own bootstrapper sylesheet (the main).

This is quite easy with the ECQWP.

We can reuse our previous  item style code and paste it in a custom .xslt file, or in an existing one.

image

Here is a Folder view of the Extended Content Query Web part style sheets folders :

image

For instance, I’ve copied and pasted my devoteamstyle in ECQWPItems.xslt :

image

The new style will show up again in the web property window :

image

Don’t forget to pass the “CurPos” and “Last” parameters to the devoteamstyle template from the “main” stylesheet:

image

We get this :

image

But we don’t have our contextual menu anymore.

So I’ve replaced and customized my “devoteamstyle” with a copy of the template that displays the context menus “Context_Menus_With_Icons”

image

 

Step 6. Extending the style sheets with your own custom function (in .Net)

 

You can find more details about this here.

Advertisements

One response to “Step by step tutorial : using the Content Query Web Part /Enhanced Query Web Part (MOSS 2007)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s