Friday, May 20, 2011

Deploying a Document Library including content using a Feature

Recently I needed to deploy a SharePoint document library as a feature, but with some documents already in it. In my case it was because of demo content, the customer wanted to do some training and needed a pre-filled document library. I can see this useful in other times however, such as including templates for documents, etc.

The solution for this is not difficult, but since I could not find any instructions online for this I thought I'd write a post.

In short, you need to create a feature that includes two components. A list instance based on a document library and then a module with the documents that you want to add to your library. The module has to point to your newly created library and all is well.

Let's walk through this. Start up Visual Studio and create a new empty SharePoint project. You can choose to use a sandbox solution, this code works just fine in both sandbox and farm modes.


Next add a new item, of type list instance.



Choose 'Document Library' as the base type, and make sure to clean up the display name and URL. I personally hate the defaults that Visual Studio creates for these.


Next add another new item to your project, this time of type module.


Delete the sample file from the module, and add the documents that you want to automatically be part of the feature rollout. I copy the files using windows explorer to the appropriate place and the use the "show all documents"button in Visual Studio to include them in the project


Once you have added all the required files and removed the sample file from your module, the elements.xml file of the module should look something like:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="DemoDocumentContent">
  <File Path="DemoDocumentContent\demo1.docx" Url="DemoDocumentContent/demo1.docx" />
</Module>
</Elements>

This needs to be modified so that the documents end up in the new library you are creating. First open up the elements.xml file of the list instance you created, and copy the Url attribute.
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ListInstance Title="Demo Documents"
                OnQuickLaunch="TRUE"
                TemplateType="101"
                FeatureId="00bfea71-e717-4e80-aa17-d0c71b360101"
                Url="Lists/DemoDocuments"
                Description="">
  </ListInstance>
</Elements>


Now paste that Url attribute in the Module element of the elements.xml file for the module. Then remove all but the filename form any Url attributes of individual file elements in that file.
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="DemoDocumentContent" Url="Lists/DemoDocuments">
  <File Path="DemoDocumentContent\demo1.docx" Url="demo1.docx" />
</Module>
</Elements>

The next step is to add the Type="GhostableInLibrary" attribute, otherwise your files will not be visible in the browser.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="DemoDocumentContent" Url="Lists/DemoDocuments">
  <File Path="DemoDocumentContent\demo1.docx" Url="demo1.docx" Type="GhostableInLibrary" />
</Module>
</Elements>

Lastly you should rename the feature that Visual Studio created for you by default, fill in a Display name and optionally a description and ensure that the List instance and Module elements are included in the feature.


When you deploy this solution to a SharePoint site, it will create a document library with the documents in it, as desired.

In case you are working on a similar situation as I was and are creating this for demo purposes, there is one last very useful piece. That is cleanup. I have added a feature event receiver to my solution that deletes the document library when the feature is deactivated. This ensures that the person delivering the training can very quickly recreate the document library with the initial content by deactivating and reactivating the feature. The code needed for this is:

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            //Delete the demo list with all content
            if (properties.Feature.Parent is SPWeb)
            {
                SPWeb web = (SPWeb)properties.Feature.Parent;
                SPList list = web.GetList("/Lists/DemoDocuments");
                web.Lists.Delete(list.ID);
            }
        }

So to summarize, it is very easy to build a feature (which can run in the sandbox) that creates a document library including some default documents already in the library. The feature should be web scoped, include a list instance element and a module element with all the necessary content files. By changing the url parameter in the module we can ensure that the documents are placed in the new document library.

Sunday, May 08, 2011

Great Motorcycle Ride

Disclaimer: Not a SharePoint post


Mel and I took a fantastic ride on the motorbike today. For anyone in the Amsterdam area who rides motorcycles, here is a great trip:


View Larger Map