Sharepoint 2007 List Definition Feature How To
PreReq
This project was created in VS 2008 with the Visual Studio 2008 extensions for Windows SharePoint Services 3.0 (version 1.2) and WSPBuilder installed. To compile and deploy you need to open this project on a machine with MOSS 2007 installed.
Background
In this article I will discuss how to create your own List Definition project for MOSS 2007, including the definition code and schemas for a document library list. I also include a feature to create your list once it is activated, and even a global feature in case you have several lists.
Using the code
Building any feature is no simple matter in Sharepoint 2007. You have to do everything just right to succeed. Your project hierarchy is important.
The basc heirarchy of a project will not be discussed here in any depth, but suffice it to say it is important. for our needs the HIVE location of C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\FEATURES will be the area where we locate and install our features. In our project this hierarchy starts at TEMPLATE. So our features will live in TEMPLATE\FEATURES\ and the feature name.
For this project we have three features:
- Example.ListDefinition.ExampleList - this contains the actual list definition
- Example.ListDefinition.ExampleList.Instance - this contains the feature which will create a list on our site once it is deployed and activated.
- Example.ListDefinition - since the other features are marked hidden for purposes of activation ease this is the feature we use to activate the other two. Also if you had multiple features (or multiple lists for a project) you could use this feature to tie them all in from an activation stand point. Since all your other features are marked "hidden" meaning they won't appear in the Sharepoint Site Features list of the UI, only the top level feature will appear. Since they are hidden dependancies they will be activated or deactivated with the top level or visible feature.
The Example.ListDefinition feature is unremarkable except for the section of the feature.xml file that defines dependancies.
<ActivationDependencies> <!-- Requires the Example.ListDefinition.ExampleList.Instance to be installed --> <ActivationDependency FeatureId="9AE45499-1370-4b23-ACB1-663C142809AD"/> <!-- Requires the Example.ListDefinition.ExampleList to be installed --> <ActivationDependency FeatureId="434BA6CB-63A8-425d-8C68-CFCAA45745C3"/> </ActivationDependencies>
Since both of the other features are hidden and Sharepoint does not support hierarical dependancy chains (see this article) to allow multiple features we have to identify as dependancies both the list definition feature and the list creation feature in the top level feature.
The actual list definition files exist in the Example.ListDefinition.ExampleList feature, which includes a schema file (under the ExampleList folder of the feature) for a modified document library with some custom columns added. The first part of this feature is the feature.xml. There are featue recievers but they don't do much, except clean up the list on deactivation. Be careful with that though, your content will go too!
Note: If you cut and paste this code to make a new list feature you have to change the "Id" attribute of the List Definition feature (actually you should probably change all the Guids under your copied feature). Copy the new Guid you create and put that in the Example.ListDefinition feature.xml and as well put this Guid in the Example.ListDefinition.ExampleList.Instance feature file instance.xml under the ListDefinition nodes "FeatureId" attribute. Also change the toplevel feature Example.ListDefinition feature.xml file under activation dependancy and add a dependancy node for the new feature.
<?xml version="1.0" encoding="utf-8"?> <Feature Id="434BA6CB-63A8-425d-8C68-CFCAA45745C3" Title="Example.ListDefinition.ExampleList" Description="DO NOT mess with this list definition feature to prevent dependancy crashes. Perform all activation deactivation against the TOP LEVEL Example.ListDefinition feature." Scope="Web" Hidden="true" ActivateOnDefault="FALSE" AutoActivateInCentralAdmin="FALSE" AlwaysForceInstall="TRUE" ImageUrl="Example_ListDefinition\cl.jpg" ReceiverAssembly="Example.ListDefinition, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5" ReceiverClass="Example.ListDefinition.ExampleListFeatureReceiver" xmlns="http://schemas.microsoft.com/sharepoint/"> <ElementManifests> <ElementManifest Location="ExampleList/ListDefinition.xml"/> </ElementManifests> </Feature>
Notice in the Example.ListDefinition.ExampleList feature the element reference to the ListDefinition.xml. This is our list definition manifest file. The feature.xml points to this. The location name "ExampleList/ListDefinition.xml" is important because when the feature that creates an instance uses this feature to create an instance it looks in the folder with the name "ExampleList".
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <ListTemplate Name="ExampleList" DisplayName="ExampleList" Description="" BaseType="1" Type="101" OnQuickLaunch="FALSE" SecurityBits="11" Sequence="110" Image="/_layouts/images/itdl.gif" DocumentTemplate="101" /> </Elements>
As I stated above the important thing to notice here is the "ExampleList" name. The name itself is unimportant but it must match the folder it is located in under the Example.ListDefinition.ExampleList feature.
Note: If you cut and past these list features to create new list definitions you have to change this folder name under Example.ListDefinition.ExampleList feature to match the "Name" attribute in the ListTemplate.
Next you have the schema.xml file and support files.
These are under folder in the example project under folder TEMPLATE\FEATURES\Example.ListDefinition.ExampleList\ExampleList.
To create a schema file for your project you can use a tool like SharePoint Manager to get the scema for a list from Sharepoint that you create through the Sharepoint Site Settings UI, or roll your own.
The schema file for our example is based on a document library. This is indicated by the schema structure and by the "Type" and "BaseType" attributes.
<List Name="ExampleList" Title="ExampleList" Direction="0" BaseType="1" Url="ExampleList" DisableAttachments="TRUE" Type="101" Id="42AB31FD-4935-4c70-9397-78B3E5EEA3A9" xmlns="http://schemas.microsoft.com/sharepoint/"> .....
Any columns you create on top of the default Document Library columns are located in various places in the schema. I included an example of some just so you can see what it might look like.
<Fields> <Field .... <Field Type="Text" DisplayName="ExampleListType" Required="TRUE" MaxLength="255" ID="{039b22c9-7967-4e46-8550-ca4d933c19a8}" SourceID="{0ea41a0b-8f0c-4af0-8d9f-57909e889a8a}" StaticName="ExampleListType" Name="ExampleListType" ColName="nvarchar10" RowOrdinal="0" /> <Field Type="Text" DisplayName="ExampleListId" Required="TRUE" MaxLength="255" ID="{B412DE16-5CEC-4be0-BA27-D265C0B0EEC5}" SourceID="{0ea41a0b-8f0c-4af0-8d9f-57909e889a8a}" StaticName="ExampleListId" Name="ExampleListId" ColName="nvarchar10" RowOrdinal="0" /> <Field Type="Text" DisplayName="MemberId" Required="TRUE" MaxLength="255" ID="{0B63375F-A0B1-4fb9-901C-41CD1DBD3E6A}" SourceID="{0ea41a0b-8f0c-4af0-8d9f-57909e889a8a}" StaticName="MemberId" Name="MemberId" ColName="nvarchar10" RowOrdinal="0" /> <Field Type="Text" DisplayName="Status" Required="TRUE" MaxLength="255" ID="{5E724380-F055-46a6-A961-D524C86B2690}" SourceID="{0ea41a0b-8f0c-4af0-8d9f-57909e889a8a}" StaticName="Status" Name="Status" ColName="nvarchar10" RowOrdinal="0" /> <Field Type="Text" DisplayName="Phase" Required="TRUE" MaxLength="255" ID="{F4FAF8DA-7861-4226-B86A-78780DB9AE90}" SourceID="{0ea41a0b-8f0c-4af0-8d9f-57909e889a8a}" StaticName="Phase" Name="Phase" ColName="nvarchar10" RowOrdinal="0" />
The feature to create your list instance is Example.ListDefinition.ExampleList.Instance.
Note: Notice in the example below I removed the dependancy to the list definition feature. This is because I made all the list features hidden. I did this because I wanted to put a number of lists in the project under one top level feature, but didn't want the user to have to activate each one. Making them hidden and giving them all dependancies on the top level feature Example.ListDefinition does this.
<?xml version="1.0" encoding="utf-8"?> <Feature Id="9AE45499-1370-4b23-ACB1-663C142809AD" Title="Example.ListDefinition.ExampleList.Instance" Description="DO NOT mess with this list definition feature to prevent dependancy crashes. Perform all activation deactivation against the TOP LEVEL Example.ListDefinition feature." Scope="Web" Hidden="true" ActivateOnDefault="FALSE" AutoActivateInCentralAdmin="FALSE" AlwaysForceInstall="TRUE" ImageUrl="Example_ListDefinition\cl.jpg" xmlns="http://schemas.microsoft.com/sharepoint/"> <!--<ActivationDependencies> --><!-- Requires the ContentType to be installed --><!-- <ActivationDependency FeatureId="434BA6CB-63A8-425d-8C68-CFCAA45745C3"/> </ActivationDependencies>--> <ElementManifests> <ElementManifest Location="instance.xml"/> </ElementManifests> </Feature>
The list instance.xml in the folder Example.ListDefinition.ExampleList.Instance contains a reference to the feature that contains the list definition. It also tells sharepoint where to put the list via the "Url" attribute.
Note: The "Title" attribute in the ListInstance node should match the folder name under the Example.ListDefinition.ExampleList feature.
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <!-- The following Guid for FeatureId is used as a reference to the list definition, and it will be automatically replaced with actual feature id at deployment time. --> <ListInstance FeatureId="434BA6CB-63A8-425d-8C68-CFCAA45745C3" Title="ExampleList" Url="Lists/ExampleList" RootWebOnly="FALSE" DocumentTemplate="101" Id="101" TemplateType="101" > </ListInstance> </Elements>
I included in the sample project install scripts as cmd files that once you run WSPBuilder against the project will take your WSP file and move it to your favorite server. Follow the "README TO INSTALL.txt in the sample project for more information on this.
Points of Interest
Yea...as usual with Sharepoint 2007 figuring all the settings out so it would work was difficult, but once I got it working to put in a new list was cut and past. You will need to change the feature name, list definition folder name, list guids, names and the like. If you use my example as a template for your list definition projects it will probably save you some time. Suffice it to say I use them when on new projects I work on right off this site. Always takes a little tweaking. But since this is a free article...don't complain if it doesn't work for you. That is part of what we get paid for is to make this stuff work. Else happy coding!
One last note...if you are wondering what the web parts code is for I use it as a MOSS 2007 hack so it doesn't belly ache about not having web level code to deploy when deploying to a server.
Post Comment
60PBJM Great blog.Thanks Again. Much obliged.