Document libraries, Folders & Content Types


I have been asked a few times if it is possible to associate different Content Types with different folders within the same document library.  From the Web UI in WSS this does not seem to be possible.  However,  there are sneeky ways to achieve this.

Scenario:  I have a document library that has some document content types (say Report, Review & Results).  I want to have people create Reports in the root of my document library & only Review and Results in sub folders.

Solution

First up I would create a new folder Content Type (called say Collateral Folder) and associate that with the document library.  Then I would make sure all my document Content Types are associated with the document library but set only Report to show on the new button (you do all this in the content type settings area of your library) .. nothing special yet.

At this point you need to know how to write a document library event handler (If you want to know how to do this I would read this blog post: http://blogs.msdn.com/brianwilson/archive/2007/03/05/part-1-event-handlers-everything-you-need-to-know-about-microsoft-office-sharepoint-portal-server-moss-event-handlers.aspx)

What you need to do is create an event handler for this library that uses the ItemAdded event to set the UniqueContentTypeOrder property on the folder.  This will set the correct items on the New button for you.

(Caveat:  I have pulled this from an example & I have and chopped out other code for the purposes of this post … the following may or may not compile … its just an example 🙂

public override void ItemAdded(SPItemEventProperties properties)
{

base.ItemUpdated(properties);

SPListItem item = properties.ListItem;

// get the content types we need… 
SPContentType collateralFolderCT= item.ParentList.ContentTypes[“Collateral Folder”];
SPContentType reviewCT= item.ParentList.ContentTypes[“Review”];
SPContentType resultsCT= item.ParentList.ContentTypes[“Results”];

// if the item that was created is a Collateral Folder then we want to set the property.
if(item.ContentType.Id == collateralFolderCT.Id)
{

// build a collection of content types that we want on the New button
Collection<SPContentType> order = new Collection<SPContentType>();

// add the content types we want to that collection
order.Add(reviewCT);
order.Add(resltsCT);

SPFolder folder = item.Folder;

// set the property to our collection
folder.UniqueContentTypeOrder = order;

// and update 🙂
folder.Update();

}

 

That should do the trick.  Now when a Collateral Folder is added this code will run and set that only the Review and Results content types should be on the new button.

Good luck!

-Chris.

Comments (5)

  1. 2007 MOSS Resource Links (Microsoft Office SharePoint Server) Here is an assortment of various 2007 Microsoft

  2. Jacob Kapp says:

    I am seeing an issue and believe its due a specific reason.  I am using the code in a similiar way but instead of the content types already added to the list.  I am creating a content type based off the new folder name. when the code attemtps to run folder.UniqueContentTypeOrder i receive an error Specified argument was out of the range of vailid values.  paramenter name: value.  I believe the newly created content type isnt available to the newly created folder.  Is this true?

    here is a snippet:

    SPListItem item = properties.ListItem;

                   //create the log handler object

                   log = new HTMLFileLogging(c_logFileFolder, string.Format(LogFileName, properties.ListTitle, properties.OpenWeb().Title), true, true);

                   this.WriteToLog("ItemAdded was triggered", false);

                   if (properties.ListItem[properties.ListItem.Fields["Content Type"].Title.ToString()].ToString() == "Folder")

                   {

                       SPList list = web.Lists[properties.ListTitle];

                       SPContentType parentCT = web.ContentTypes["Document"];

                       SPContentType newCT = new SPContentType(parentCT, web.ContentTypes, properties.ListItem.Name);

                       ContentType.AddToList(list, newCT);

                       Collection<SPContentType> orderedCT = new Collection<SPContentType>();

                       orderedCT.Add(newCT);

                       item.Update();

                       base.ItemUpdated(properties);

                       this.WriteToLog("Item : " + item.Name, false);

                           SPFolder folder = item.Folder;

                           this.WriteToLog("Folder Name : " + folder.Name, false);

                           foreach (SPContentType ct in orderedCT)

                           {

                               this.WriteToLog("Content Type : " + ct.Name, false);

                           }

                           folder.UniqueContentTypeOrder = orderedCT;

                           folder.Update();

  3. Gracias a Mark Kruger (SharePoint MVP) por esta lista de recursos de SharePoint donde podréis encontrar

  4. Gracias a Mark Kruger (SharePoint MVP) por esta lista de recursos de SharePoint donde podréis encontrar