Prerequisites
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.
Updates
- I added other list types. Now includes a Doc Lib and task example as well as a list example.
- I fixed the project so it could be viewed outside a SharePoint server and without the extensions.
- An issue with how I created the schema file using SharePoint Solution Generator: the schema.xml having
ColName="ntext5"
or ColName="nVarcharn"
where n = number in fields was causing the error: "The URL "FileName" is invalid. It may refer to a nonexistent file or folder, or refer to a valid file or folder that is not in the current Web."
This was fixed by removing those attributes from the fields in the schema.xml. I fixed this in the project example. Also changed the document library from List/ExampleList to Folders/Example List in instance.xml so the list would be in a folder collection.
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 included 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 base hierarchy 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 have 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 dependencies, 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 dependencies.
<ActivationDependencies>
<ActivationDependency FeatureId="9AE45499-1370-4b23-ACB1-663C142809AD"/>
<ActivationDependency FeatureId="434BA6CB-63A8-425d-8C68-CFCAA45745C3"/>
</ActivationDependencies>
Since both of the other features are hidden and SharePoint does not support hieratical dependency chains (see this article) to allow multiple features, we have to identify as dependencies 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 feature receivers 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 also put this GUID in the Example.ListDefinition.ExampleList.Instance feature file instance.xml under the ListDefinition
node's "FeatureId
" attribute. Also change the top level feature Example.ListDefinition feature.xml file under activation dependency and add a dependency node for the new feature.
="1.0"="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 ListDefinition.xml. This is our list definition manifest file. 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".
="1.0"="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 paste these list features to create new list definitions, you have to change this folder name under the 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 in the example project under the 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 schema 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 dependency 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 dependencies on the top level feature Example.ListDefinition does this.
="1.0"="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/">
<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.
="1.0"="utf-8"
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<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.
After you get the WSP file deployed, go to the site you want to activate the feature on, and go to the Site Settings/Site Features section. You should see the feature there. Activate the feature.
You can now move to the site content page and view the list.
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 paste. 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.