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> </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.
Can we provision the webpart with connection ?
Connectable webparts are provisioned in the same way as ordinary webparts.