SharePoint: Content Query Web Part Customizing the Query

11 12 2009

Recently I’ve been customizing Content Query Web Parts (CQWP) whereby I override the query and supply my own CAML query. The basic steps involved in doing this are;

  1. Author the Web Part using the UI
  2. Export the Web Part using the UI
  3. Customize the Web Part .webpart file
  4. Import the customized Web Part back into SharePoint

Some of these Web Parts were configured to query by Content Type, such that the Web Part property “ContentTypeName” is given a specific value as shown below;


    <property name="ContentTypeName" type="string">Period View Item</property>

Prior to customizing the CQWP query with CAML, such a Web Part worked fine. So having exported the Web Part I provided a custom CAML query using the “QueryOverride” property;


  <property name="QueryOverride" type="string"><![CDATA[<Where>...</Where>]]></property>

After importing the Web Part back into SharePoint I noticed that it would return results for other Content Types also. To work around the problem I modified the CAML query to restrict the results to the Content Type in question, like so;


  <Where><And><And><Eq><FieldRef Name="ContentType" /><Value Type="Choice">Period View Item</Value></Eq>......</And></And></Where>

I suspect this is by design rather than a bug, however the CQWP documentation indicates that the query by Content Type feature is a filter rather than part of the query, as this article aludes to.





Provision a WebPart using a SharePoint Feature.

4 08 2009

Moving on from this post, you’ve developed a custom WebPart and you want to package it up for deployment to SharePoint (and you’re not using VSeWSS or WSPBuilder for some reason), or, you’ve customized an OOTB WebPart and want to package it up for reuse in a feature.

Starting with your webpart description file, which is either a .DWP or .Webpart file, this describes the webpart to SharePoint, indicates what the backing assembly and type is, and details both standard (layout, chrome etc) and custom property (specific to the webpart) data . The difference between a v2 (.DWP) webpart and a v3 (.webpart) is described in this post. In this article I’ll be using a .DWP type webpart file, as shown below.

<?xml version="1.0" encoding="utf-8"?>
<WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
  <Title>Title of Web Part</Title>
  <FrameType>None</FrameType>
  <Description>Description.</Description>
  <IsIncluded>true</IsIncluded>
  <ZoneID>Left</ZoneID>
  <PartOrder>0</PartOrder>
  <FrameState>Normal</FrameState>
  <Height />
  <Width />
  <AllowRemove>true</AllowRemove>
  <AllowZoneChange>true</AllowZoneChange>
  <AllowMinimize>true</AllowMinimize>
  <AllowConnect>true</AllowConnect>
  <AllowEdit>true</AllowEdit>
  <AllowHide>true</AllowHide>
  <IsVisible>true</IsVisible>
  <DetailLink />
  <HelpLink />
  <HelpMode>Modeless</HelpMode>
  <Dir>Default</Dir>
  <PartImageSmall />
  <MissingAssembly>Cannot import this Web Part.</MissingAssembly>
  <PartImageLarge>/_layouts/images/mscontl.gif</PartImageLarge>
  <IsIncludedFilter />
  <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
  <TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>
  <ContentLink xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
  <Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"><![CDATA[<TABLE border=0 cellSpacing=0 cellPadding=0 width="100%"><TBODY>
<TR class=ms-WPHeader>
<TD style="WIDTH: 100%" title="Reporting Tools - This is the list of Reporting Tools provisioned on this site.">
<H3 class="ms-standardheader ms-WPTitle"><NOBR><SPAN>Reporting Tools</SPAN></NOBR></H3></TD>
<TD style="PADDING-RIGHT: 2px" align=right>
<DIV style="" class=""><NOBR>&nbsp;</NOBR></DIV></TD></TR></TBODY></TABLE>
<table class="ms-summarycustombody" cellspacing="0" cellpadding="0">
<tr>
<td class="ms-vb" style="padding-bottom:5px;width:20px;vertical-align:middle;text-align:center;">
<IMG alt="" src="/_layouts/images/square.gif" align="middle"></td>
<td class="ms-vb" style="padding-bottom:5px;">
<a href="cstools/Basic%20Analysis.aspx"><img src="/_layouts/images/calcis/basic_analysis.jpg" align="middle" border="0" />Open the Basic Analysis Tools</a></td>
</tr>
</table>
]]></Content>
  <PartStorage xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
</WebPart>

There is a lot of data in that description, but the important elements to note are;

  • Assembly
  • TypeName
  • ZoneID
  • Content and ContentLink

Assembly and TypeName are used to indentify the code which implements the webparts logic, ZoneID is used to indicate in which webpart zone to place the webpart (which is dependent on the target page).

Content and ContentLink are specific (properties) to the implementing webpart, which in this case is the OOTB Content Editor WebPart.

Next create the feature files (feature.xml and elements.xml). Your feature.xml file which describes the feature should look like this;

<?xml version="1.0" encoding="utf-8"?>
<Feature  Id="ca02dcce-00e2-4061-abf0-d01603e96605"
          Title="Title"
          Description="Description"
          Version="12.0.0.0"
          Hidden="FALSE"
          Scope="Site"
          ActivateOnDefault="FALSE"
          ImageUrl="myimages/myfeature.gif"
          DefaultResourceFile="core"
          ReceiverAssembly="Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e9979221f05968b5"
          ReceiverClass="Assembly.FeatureReceiver"         
          xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
  <ElementFile Location="Web Part.dwp"/>
  </ElementManifests>
</Feature>

Webparts provisioned via a feature must be scoped at the Site Collection level (see the Scope attribute) since the webpart gallery lives at the site collection level.  

Note the ReceiverAssembly and ReceiverClass attributes, these are used to implement a feature receiver, which I use to remove or unprovision the webpart from the webpart gallery in SharePoint when the feature is deactivated – more about this later.

Next comes the feature manifest file (elements.xml) file which should look like this;

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
	<Module Name="WebParts FileSet" Url="_catalogs/wp" RootWebOnly="TRUE">
		<File Url="Web Part.dwp"
				Type="GhostableInLibrary">
			<Property Name="Group" Value="MyGroup"></Property>
			<Property Name="QuickAddGroups" Value="MyGroup" />
		</File>
	</Module>
</Elements>

This is where the webpart file is provisioned into SharePoint, using a module. The module describes a fileset to be introduced to SharePoint, see the link for more information.

The URL attribute of the module element, indicates the target SharePoint URL/Path of the modules files (which in this case is the the URL of the site collections webpart gallery). This path can also be a Folder, and if the target path is not found, the provisioning service will create a new folder for you.
The URL attribute of the File element(s) indicates the target file name part of the URL to be used in SharePoint. You can also use the Path attribute of the File element(s), which refers to the actual path/file name of the provisioned file as it resides as on the hard disk filesystem. The combination of these 2 attributes allows you to give a feature file a different SharePoint URL name, than it is named on the hard disk.

The Type attribute of the File element(s) indicates whether the file can be customized or not and is either Ghostable or GhostableInLibrary.  Since the webpart gallery is actually a document library and not a list or a folder, this is set to GhostableInLibrary. If you are provisioning a file into a Folder, then set the Type attribute to Ghostable.

As child elements of the File element you can include other property (metadata) data supported by WebPart list item types. In this case I’ve specified custom grouping labels.

Finally the feature.xml, elements.xml and your .DWP file should all reside in the same folder in your solution. It is possible to manipulate the source and target paths/URLS and filenames  of Modules and File(s) – check out the schema documentation for more information on how to do this.

At this point I’d build the SharePoint feature/solution package (.WSP) using WSPBuilder or VSeWSS, if you don’t know how to hand craft .WSP files, then I’d recommend you take a look at WSPBuilder.

I did mention earlier on I use a feature receiver to remove or unprovision the webpart file from the webpart gallery, when the feature is deactivated. I’ll show how this is done in another post, but , the reason I do this is because files provisioned into SharePoint using Modules, do not get removed when the feature is deactivated.

This may or may not be a problem to you, except that, my own experience has shown that, say, when upgrading features, existing files provisioned by a previous version of a feature, sometimes do not get overwritten, or new files in a new version of the feature sometimes get ignored if the file already exists. Meaning that you may not get the right files for your feature installed into SharePoint.

The next post will show some fairly simple code which removes feature files from SharePoint when the feature is deactivated.





Free SharePoint / MOSS WebParts List

14 04 2009




Sharepoint Webpart Lifecycle Events Updated

14 01 2009

I’ve updated my post on Sharepoint WebPart Lifecycle events, since the previous version wasn’t that acurate.





Visual XSLT/StyleSheet Design Tool

11 11 2008

Recently I’ve been developing Sharepoint 2007 Web Parts to connect with the standard features of Sharepoint (Lists, Form Library web parts etc) and needed a bunch of stylesheets to do transformations into something reasonable for display purposes.

Rather than cobble together something with notepad!, I found StyleVision from Altova, with which you can do visual design of your stylesheets, works a treat and quickly allowed me to put together the stylesheets I needed.

stylevision011