MOSS / WSS 3.0: Creating a custom list feature

Rough guide to creating a custom list feature (aka a list definition).

Creating our list feature

  1. Copy an existing feature e.g. 12\Features\ContactsList to a new feature folder such as 12\Features\SkypeContacts (where SkypeContacts is the name of the new feature).
  2. In the new feature folder, edit the feature.xml file changing the following:
    • Create a new guid for the feature (via vs2005 tools menu). Remember to strip out braces when putting in
    • Replace title and description (note that you are supposed to refer to a resource to aid globalisation, but I personally didn?t bother (for the time being) and simply replace with strings.
    • Leave everything else as is (including the element manifest node). Your feature.xml file should look similar to this:

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="2C3A48D0-9FF2-487b-9F02-B5C2A8D42261"
    Title="Skype Contacts List"
    Description=" Skype Contacts List, used to store skype contacts."
    Version="1.0.0.0"
    Scope="Web"
    Hidden="TRUE"
    DefaultResourceFile="core"
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <ElementManifests>
        <ElementManifest Location="ListTemplatesContacts.xml"/>
    </ElementManifests>
</Feature>

Altering the element manifest

Go the the elementmanifest (i.e. ListTemplates\Contact.xml in our example) and make the following changes:

  1. For the list template node, change the type attribute (it is recommended that you use a number over 10000, as low numbers are reserved by Microsoft).
  2. Change the title and description attribute (note that you are supposed to refer to a resource to aid globalisation, but I personally didn?t bother (for the time being) and simply replaced with strings.
  3. Note that you should leave the name as it is (i.e. contacts in our example) as this seems to be used to reference the subfolder of our feature that contains the schema. You xml file should look similar to this:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <ListTemplate
        Name="contacts"
        Type="40006"
        BaseType="0"
        OnQuickLaunch="TRUE"
        SecurityBits="11"
        Sequence="330"
        DisplayName="Skype Contacts List"
        Description="Contacts list for recording my skype contacts."
        Image="/_layouts/images/itcontct.gif"/>
</Elements>

Adding an extra field to our list feature

Edit the schema.xml file. Make the following changes.

  1. In the fields section add a new field (my example creates a text field called SkypeId). Create a new guid for the id of this field. <Field ID=”{BD387A0C-A1C2-405e-A48B-234CC0CE6828}” Name=”SkypeId” DisplayName=”SkypeId” Type=”Text” SourceID=”http://schemas.microsoft.com/sharepoint/v3″ StaticName=”SkypeId”><!– _locID@DisplayName=”camlid9″ _locComment=” ” –></Field>
  2. In any views you want the field to appear (i.e. within the ViewFields node, add the field e.g. <FieldRef Name=”SkypeId” />
  3. Important: so that the field is available on the add / edit pages, you need to alter the contents types used by your list (altering field attributes in schema.xml is not sufficient). If your custom list feature is based on another list feature (as per our example) you have three options:
    • All Microsoft pre-defined content types are stored in a feature named ctypes. You can simple edit the ctypeswss.xml file that defines the content types and add your fields to the relevant content type (if you look at the ContentTypes node in the schema.xml file for your list feature you can determine which one needs to be altered). Note that if you alter this file directly, you are carrying out and unsupported modification and may be prone to problems if Microsoft release services packs etc. Note that when adding a field to a content type, the guid of that field should match that used in schema.xml.
    • Second approach is to create a feature that contains your new content type (simple copy from ctypeswss.xml and alter accordingly). You can then set a reference to this in the ContentTypeRef node in schema.xml
    • The third (and my preferred approach) is to copy the appropriate existing content type definition from ctypeswss.xml to the schema.xml. You should replace the content type node with the what it references in ctypeswss.xml. In our example, our schema.xml before altering the content type is: <ContentTypes>
            <ContentTypeRef ID="$Resources:core,ContactCTID;">
              <Folder TargetName="Contact" />
            </ContentTypeRef>
            <ContentTypeRef ID="0x0120" />
      </ContentTypes>

      EDIT: I would recommend that you create a content type in a seperate feature (adding the content type to the elements.xml file). This way you can inherit from other content types. Please see my article http://www.rnowik.com/blogpost/161/ for pointers on how to do this and how to set up necessary content type ids.
      Shown below is the ContentTypes node after the content type has been copied across and the additional field has been added to the content types (Note that if you create new content type, you need to create a new content type id (hex ? in my example my content type id is Ox1DD). <ContentTypes>
      <ContentType ID="0x01DD"
      Name="SkypeContact"
      Group="$Resources:List_Content_Types"
      Description="ShareWorkz Content Type"
      Version="0"
      >
      <FieldRefs>
      <FieldRef ID="{82642ec8-ef9b-478f-acf9-31f7d45fbc31}" Name="LinkTitle" DisplayName="$Resources:core,Last_Name;" Sealed="TRUE"/>
      <FieldRef ID="{bc91a437-52e7-49e1-8c4e-4698904b2b6d}" Name="LinkTitleNoMenu" DisplayName="$Resources:core,Last_Name;" Sealed="TRUE"/>
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="$Resources:core,Last_Name;" Sealed="TRUE"/>
      <FieldRef ID="{fdc8216d-dabf-441d-8ac0-f6c626fbdc24}" Name="LastNamePhonetic" Hidden="$Resources:core,True_Unless_Jpn" Required="FALSE"/>
      <FieldRef ID="{4a722dd4-d406-4356-93f9-2550b8f50dd0}" Name="FirstName" />
      <FieldRef ID="{ea8f7ca9-2a0e-4a89-b8bf-c51a6af62c73}" Name="FirstNamePhonetic" Hidden="$Resources:core,True_Unless_Jpn"/>
      <FieldRef ID="{475c2610-c157-4b91-9e2d-6855031b3538}" Name="FullName" />
      <FieldRef ID="{fce16b4c-fe53-4793-aaab-b4892e736d15}" Name="Email" />
      <FieldRef ID="{038d1503-4629-40f6-adaf-b47d1ab2d4fe}" Name="Company" />
      <FieldRef ID="{034aae88-6e9a-4e41-bc8a-09b6c15fcdf4}" Name="CompanyPhonetic" Hidden="$Resources:core,True_Unless_Jpn"/>
      <FieldRef ID="{c4e0f350-52cc-4ede-904c-dd71a3d11f7d}" Name="JobTitle" />
      <FieldRef ID="{fd630629-c165-4513-b43c-fdb16b86a14d}" Name="WorkPhone" />
      <FieldRef ID="{2ab923eb-9880-4b47-9965-ebf93ae15487}" Name="HomePhone" />
      <FieldRef ID="{2a464df1-44c1-4851-949d-fcd270f0ccf2}" Name="CellPhone" />
      <FieldRef ID="{9d1cacc8-f452-4bc1-a751-050595ad96e1}" Name="WorkFax" />
      <FieldRef ID="{fc2e188e-ba91-48c9-9dd3-16431afddd50}" Name="WorkAddress" />
      <FieldRef ID="{6ca7bd7f-b490-402e-af1b-2813cf087b1e}" Name="WorkCity" />
      <FieldRef ID="{ceac61d3-dda9-468b-b276-f4a6bb93f14f}" Name="WorkState" />
      <FieldRef ID="{9a631556-3dac-49db-8d2f-fb033b0fdc24}" Name="WorkZip" />
      <FieldRef ID="{3f3a5c85-9d5a-4663-b925-8b68a678ea3a}" Name="WorkCountry" />
      <FieldRef ID="{a71affd2-dcc7-4529-81bc-2fe593154a5f}" Name="WebPage" />
      <FieldRef ID="{9da97a8a-1da5-4a77-98d3-4bc10456e700}" Name="Comments" />
      <FieldRef ID="{BD387A0C-A1C2-405e-A48B-234CC0CE6828}" Name="HelloWorld" />
      </FieldRefs>
      </ContentType>
      <ContentTypeRef ID="0x01BA">
      <Folder TargetName="Contact" />
      </ContentTypeRef>
      <ContentTypeRef ID="0x0120" />
      </ContentTypes>

Deploying our list feature

To deploy and activate the feature, you need to run the following commands (note that as lists have web scope you will need to activate on each web that you want to use it):

  1. Stsadm ?o installfeature ?name [name of feature]
  2. Stsadm ?o activatefeature ?id [guid from feature.xml] ?url [url of web to deploy to]

Alternatively, you can create a custom site definition and reference our list by adding the following node the appropriate configurations WebFeatures node: <Feature ID="2C3A48D0-9FF2-487b-9F02-B5C2A8D42261" />

Notes

  • Note: It is worth noting that all of the Microsoft lists are grouped together in one feature (.xml) so that a reference to each list feature does not need to be made in the site definition, hence why you don?t see a reference to each list definition in the standard Sharepoint site definitions.
  • Tip: remember to change xmlns:ows=”Microsoft Sharepoint” to xmlns=”http://schemas.microsoft.com/Sharepoint” to get intellisense when working on the xml files.
  • Note that in an ideal world, I would be able to create an event handler that provisions additional fields when a new list is added, however there are no list created events in MOSS / WSS3 (only field added / deleted / adding / deleting on a list).

Related References:

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>