<CharlieDigital/> Programming, Politics, and uhh…pineapples

2Mar/14Off

Programmatically Add SharePoint Lists with Schemas

So you want to add a custom list with a schema, eh?

In SharePoint, this is "easily" (lol) done by adding a custom list with a Schema.xml file and a list template XML file.

But what if you don't want to add a custom list template and you want to do it programmatically?  You'd want to do this, of course, if you wanted to define custom views on the list.  I've seen this done programmatically (as in verbose, custom code to build lists, add content types, build views, etc.), but SharePoint already offers you a mechanism for defining custom views using the list schema XML file.  Why duplicate what SharePoint already gives you for free?

In looking through the API, it seems that there is an API call that would support it, but it's quite cryptic in how it's actually invoked.

After a bit of testing, I found that it's actually quite easy.

Here is the API definition from Microsoft:

public virtual Guid Add(
   string title,
   string description,
   string url,
   string featureId,
   int templateType,
   string docTemplateType,
   string customSchemaXml,
   SPFeatureDefinition listInstanceFeatureDefintion,
   SPListTemplate.QuickLaunchOptions quickLaunchOptions
)

Here is the invocation in PowerShell:

$listId = $web.Lists.Add("Test List", "Test", "TestList2", 
    "00BFEA71-DE22-43B2-A848-C05709900100", 100, "100", $xml, $feature, 0)

A little explanation is in order here.  The first three parameters are very straight forward.  The fourth one is where it starts to get "funny".  Here, you will want to search in your 14\TEMPLATE\FEATURES\ directory for the feature that contains the template that you want to use.  In this case, I am creating a list based on the generic custom list type so the feature is located in 14\TEMPLATE\FEATURES\CustomList.  You need the GUID of the feature in the Feature.xml file here and not your own custom feature GUID.

The fifth and sixth parameters are straight forward.

We'll skip the seventh parameter for now.

The eight parameter here is the feature definition which contains the template that your list will be based on.  Because we are using an out-of-the-box list template, we simply need to load the feature definition for the GUID in parameter 4:

$features = [Microsoft.SharePoint.Administration.SPFarm]::Local

$id = [Guid]("00BFEA71-DE22-43B2-A848-C05709900100") 

$feature = $features[$id]

Again, because we are using the out-of-the-box template, we need to use the out-of-the-box feature definition that contains the template.

The ninth parameter is, again, straight forward.

Now back to that seventh parameter.  This parameter is simply the XML that would be generated by adding a new list in Visual Studio.  I've added a simple example here:

<?xml version='1.0' encoding='utf-8'?>
<List xmlns:ows='Microsoft SharePoint' Title='List1' FolderCreation='FALSE' Direction='$Resources:Direction;' Url='Lists/List1' BaseType='0' EnableContentTypes='True' xmlns='http://schemas.microsoft.com/sharepoint/'>
    <MetaData>
        <ContentTypes>
            <ContentTypeRef ID='0x01'>
                <Folder TargetName='Item' />
            </ContentTypeRef>
            <ContentTypeRef ID='0x0120' />
            <ContentTypeRef ID='0x010800B66F73F12643464793530152868EEE87'/>
        </ContentTypes>
        <Fields>
            <Field ID='{fa564e0f-0c70-4ab9-b863-0177e6ddd247}' Type='Text' Name='Title' DisplayName='$Resources:core,Title;' Required='TRUE' SourceID='http://schemas.microsoft.com/sharepoint/v3' StaticName='Title' MaxLength='255' />
        </Fields>
        <Views>
            <View BaseViewID='0' Type='HTML' MobileView='TRUE' TabularView='FALSE'>
                <Toolbar Type='Standard' />
                <XslLink Default='TRUE'>main.xsl</XslLink>
                <RowLimit Paged='TRUE'>30</RowLimit>
                <ViewFields>
                    <FieldRef Name='LinkTitleNoMenu'></FieldRef>
                </ViewFields>
                <Query>
                    <OrderBy>
                        <FieldRef Name='Modified' Ascending='FALSE'></FieldRef>
                    </OrderBy>
                </Query>
                <ParameterBindings>
                    <ParameterBinding Name='AddNewAnnouncement' Location='Resource(wss,addnewitem)' />
                    <ParameterBinding Name='NoAnnouncements' Location='Resource(wss,noXinviewofY_LIST)' />
                    <ParameterBinding Name='NoAnnouncementsHowTo' Location='Resource(wss,noXinviewofY_ONET_HOME)' />
                </ParameterBindings>
            </View>
            <View BaseViewID='1' Type='HTML' WebPartZoneID='Main' DisplayName='Hello, World' DefaultView='TRUE' MobileView='TRUE' MobileDefaultView='TRUE' SetupPath='pages\viewpage.aspx' ImageUrl='/_layouts/images/generic.png' Url='AllItems.aspx'>
                <Toolbar Type='Standard' />
                <XslLink Default='TRUE'>main.xsl</XslLink>
                <RowLimit Paged='TRUE'>30</RowLimit>
                <ViewFields>
                    <FieldRef Name='Attachments'></FieldRef>
                    <FieldRef Name='LinkTitle'></FieldRef>
                    <FieldRef Name='IntegrationID'></FieldRef>
                </ViewFields>
                <Query>
                    <OrderBy>
                        <FieldRef Name='ID'></FieldRef>
                    </OrderBy>
                </Query>
                <ParameterBindings>
                    <ParameterBinding Name='NoAnnouncements' Location='Resource(wss,noXinviewofY_LIST)' />
                    <ParameterBinding Name='NoAnnouncementsHowTo' Location='Resource(wss,noXinviewofY_DEFAULT)' />
                </ParameterBindings>
            </View>
        </Views>
        <Forms>
            <Form Type='DisplayForm' Url='DispForm.aspx' SetupPath='pages\form.aspx' WebPartZoneID='Main' />
            <Form Type='EditForm' Url='EditForm.aspx' SetupPath='pages\form.aspx' WebPartZoneID='Main' />
            <Form Type='NewForm' Url='NewForm.aspx' SetupPath='pages\form.aspx' WebPartZoneID='Main' />
        </Forms>
    </MetaData>
</List>

It is easily customized with additional custom views, specification of the fields on those views, and even specification of content types to associate to the list!

So why would you want to do this?  If you want a custom list with content types and custom views and all of that jazz, you can get it without writing a lot of custom code to build lists and without the hassle of custom templates (a pain in the butt); you can just write the schema XML (or maybe better yet, configure and export the list) and let SharePoint do its magic!

Posted by Charles Chen

Filed under: Dev, SharePoint Comments Off