SharePoint Products TechCenter >
SharePoint Products and Technologies Forums
>
SharePoint - Enterprise Content Management
>
Adding a "Content Type / Document" to many/all libraries in a site
Adding a "Content Type / Document" to many/all libraries in a site
- Hi everyone,
I'm an IT professional completely new to Sharepoint, and while I found a code snippet related to my question on the forums here I am hoping for more step by step instructions (or a link to an installable Feature) to achieve this.
As the title of the post implies, I need to add new document types so they can be created with the "new->Document" menu from a site library. The catch is that this is for an already implemented collection of sites, with a very large number of document libraries, and going through and adding new content types to each of them would take a considerable amount of time.
I am willing to achieve this in a programmatic fashion, but for this particular issue don't have enough time to learn the whole gamut of Sharepoint coding. Anyhow, all help is appreciated.
Thank you in advance,
Jeff D Whitehouse
Answers
- Create a web part project in Visual Studio 2008, with the Sharepoint extensions installed.Insert the code below into it. Add some error handling!Compile and deploy to your site. It will recurse through your site and add the conent types.Double check the code first. I knocked it up in 5 minutes and it is untested.The code is;using System;using System.Runtime.InteropServices;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Xml.Serialization;using Microsoft.SharePoint;using Microsoft.SharePoint.WebControls;using Microsoft.SharePoint.WebPartPages;namespace JM.Sharepoint.Webparts{[Guid("e1c2e841-b952-4a7c-86b6-6d91373de714")]public class AddContentTypeToList : System.Web.UI.WebControls.WebParts.WebPart{private TextBox _tbxListName;private TextBox _tbxCTName;private Button _btnUpdate;private string strListName = string.Empty;private string strContentTypeName = string.Empty;public AddContentTypeToList(){}protected override void CreateChildControls(){this._tbxCTName = new TextBox();this._tbxCTName.ID = "tbxCTName";this._tbxCTName.Text = "enter content type name here";this.Controls.Add(_tbxCTName);this._tbxListName = new TextBox();this._tbxListName.ID = "tbxListName";this._tbxListName.Text = "enter list name here";this.Controls.Add(_tbxListName);this._btnUpdate = new Button();this._btnUpdate.ID = "btnUpdate";this._btnUpdate.Text = "Update Lists";this._btnUpdate.Click += new EventHandler(_btnUpdate_Click);this.Controls.Add(_btnUpdate);}void _btnUpdate_Click(object sender, EventArgs e){strListName = _tbxListName.Text;strContentTypeName = _tbxCTName;AddContentTypeToAllLists();}void AddContentTypeToAllLists(){RecurseWebs(SPContext.Current.Site.RootWeb);}void RecurseWebs(SPWeb web){ChangeTheList(web);foreach (SPWeb subWeb in web.Webs){RecurseWebs(subWeb);}}void ChangeTheList(SPWeb web){SPList theList = web.Lists[strListName];theList.ContentTypes.Add(web.AvailableContentTypes[strContentTypeName]);theList.Update();}}}
Blog; http://www.the-north.com/sharepoint --- Posting is provided "AS IS" with no warranties, and confers no rights.- Proposed As Answer byChakkaradeep Chandran Wednesday, July 15, 2009 8:40 PM
- Marked As Answer byLionel Chen - MSFTMSFT, ModeratorFriday, July 17, 2009 9:02 AM
- If you want to achieve it in SharePoint UI, then here are the steps:
1) Add the content type to the document library.
2) Go to Document Library settings page.
3) Select Advanced Settings and enable Allow management of content types and click OK to get back to settings page.
4) In the Content Types section, select Change new button order and default content type
5) Now you can specify whether it is visible in the New and appear on the new button
And Yes, it is easy via code to implement these changes across different document libraries and you can probably use something that @Jamie MacAllister has suggested in this thread.
Hope that helps.
Regards,
Chakkaradeep
Twitter: http://twitter.com/chakkaradeep
Blog: http://www.chakkaradeep.com- Marked As Answer byLionel Chen - MSFTMSFT, ModeratorFriday, July 17, 2009 9:01 AM
- Proposed As Answer byChakkaradeep Chandran Wednesday, July 15, 2009 8:40 PM
All Replies
- Create a web part project in Visual Studio 2008, with the Sharepoint extensions installed.Insert the code below into it. Add some error handling!Compile and deploy to your site. It will recurse through your site and add the conent types.Double check the code first. I knocked it up in 5 minutes and it is untested.The code is;using System;using System.Runtime.InteropServices;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Xml.Serialization;using Microsoft.SharePoint;using Microsoft.SharePoint.WebControls;using Microsoft.SharePoint.WebPartPages;namespace JM.Sharepoint.Webparts{[Guid("e1c2e841-b952-4a7c-86b6-6d91373de714")]public class AddContentTypeToList : System.Web.UI.WebControls.WebParts.WebPart{private TextBox _tbxListName;private TextBox _tbxCTName;private Button _btnUpdate;private string strListName = string.Empty;private string strContentTypeName = string.Empty;public AddContentTypeToList(){}protected override void CreateChildControls(){this._tbxCTName = new TextBox();this._tbxCTName.ID = "tbxCTName";this._tbxCTName.Text = "enter content type name here";this.Controls.Add(_tbxCTName);this._tbxListName = new TextBox();this._tbxListName.ID = "tbxListName";this._tbxListName.Text = "enter list name here";this.Controls.Add(_tbxListName);this._btnUpdate = new Button();this._btnUpdate.ID = "btnUpdate";this._btnUpdate.Text = "Update Lists";this._btnUpdate.Click += new EventHandler(_btnUpdate_Click);this.Controls.Add(_btnUpdate);}void _btnUpdate_Click(object sender, EventArgs e){strListName = _tbxListName.Text;strContentTypeName = _tbxCTName;AddContentTypeToAllLists();}void AddContentTypeToAllLists(){RecurseWebs(SPContext.Current.Site.RootWeb);}void RecurseWebs(SPWeb web){ChangeTheList(web);foreach (SPWeb subWeb in web.Webs){RecurseWebs(subWeb);}}void ChangeTheList(SPWeb web){SPList theList = web.Lists[strListName];theList.ContentTypes.Add(web.AvailableContentTypes[strContentTypeName]);theList.Update();}}}
Blog; http://www.the-north.com/sharepoint --- Posting is provided "AS IS" with no warranties, and confers no rights.- Proposed As Answer byChakkaradeep Chandran Wednesday, July 15, 2009 8:40 PM
- Marked As Answer byLionel Chen - MSFTMSFT, ModeratorFriday, July 17, 2009 9:02 AM
- If you want to achieve it in SharePoint UI, then here are the steps:
1) Add the content type to the document library.
2) Go to Document Library settings page.
3) Select Advanced Settings and enable Allow management of content types and click OK to get back to settings page.
4) In the Content Types section, select Change new button order and default content type
5) Now you can specify whether it is visible in the New and appear on the new button
And Yes, it is easy via code to implement these changes across different document libraries and you can probably use something that @Jamie MacAllister has suggested in this thread.
Hope that helps.
Regards,
Chakkaradeep
Twitter: http://twitter.com/chakkaradeep
Blog: http://www.chakkaradeep.com- Marked As Answer byLionel Chen - MSFTMSFT, ModeratorFriday, July 17, 2009 9:01 AM
- Proposed As Answer byChakkaradeep Chandran Wednesday, July 15, 2009 8:40 PM
- Alright, thanks for the good responses.
- Following is a more complete version of the code. It has a couple of basic fixes and checks for various errors. It also includes an if statement to not try and add document types if the site does not have the requested list... nothing too complex, but as I said I'm completely new to this. There is one issue (the try catch does catch if, but not quite... properly, since it gives the catch error but should give a custom error) if the document type already belongs to the list the web part will simply crash. The other quirk, but in my case not really an issue, is that if you have multiple lists with the same name, this will go and add the document type to all of them. Thank you guys again for your *very* helpful response that got me on the right path.
using System; using System.Runtime.InteropServices; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Serialization; using Microsoft.SharePoint; using Microsoft.SharePoint.WebControls; using Microsoft.SharePoint.WebPartPages; // Based on code from the MSDN forums // http://social.msdn.microsoft.com/Forums/en-US/sharepointecm/thread/e61f920c-b9ba-44a9-8502-3243621bcdc8?prof=required namespace AddContentTypes.Deploy.WebPart { [Guid("C2233EA9-8361-400f-97D6-0215A1D98EB1")] public class ContentAdding : Microsoft.SharePoint.WebPartPages.WebPart { private TextBox _tbxListName; private TextBox _tbxCTName; private Button _btnUpdate; private string strListName = string.Empty; private string strContentTypeName = string.Empty; public ContentAdding() { } //This just renders our button and text fields, basic stuff protected override void CreateChildControls() { this._tbxCTName = new TextBox(); this._tbxCTName.ID = "tbxCTName"; this._tbxCTName.Text = "enter content type name here"; this.Controls.Add(_tbxCTName); this._tbxListName = new TextBox(); this._tbxListName.ID = "tbxListName"; this._tbxListName.Text = "enter list name here"; this.Controls.Add(_tbxListName); this._btnUpdate = new Button(); this._btnUpdate.ID = "btnUpdate"; this._btnUpdate.Text = "Update Lists"; this._btnUpdate.Click += new EventHandler(_btnUpdate_Click); this.Controls.Add(_btnUpdate); } //Take in the text fields and initiate the action when the button is clicked void _btnUpdate_Click(object sender, EventArgs e) { strListName = _tbxListName.Text; strContentTypeName = _tbxCTName.Text; AddContentTypeToAllLists(); } //Took the listExists function from here, why write when you can copypaste, why write when you can copypaste //http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/bd7d09d9-541c-4882-8dea-4b8faa14a551/ //I use this to not go and try to add content to lists that don't exists, because otherwise if a list is //Not in the rootweb but is in a subweb... well, it would crash first private static bool listExists(SPListCollection collection, string title) { foreach (SPList list in collection) { if (list.Title == title) { return true; } } return false; } //Really this just gives us a starting place (the root website) //then it calles RecurseWebs with that piece of context //Really, that is all it does, but you need to do it this way basically void AddContentTypeToAllLists() { RecurseWebs(SPContext.Current.Site.RootWeb); } //This goes through every 'web' AKA SITE >:-( //in the site AKA sitecollection and if the lists exists, adds the content type void RecurseWebs(SPWeb web) { if (listExists(web.Lists, strListName)) { ChangeTheList(web); } foreach (SPWeb subWeb in web.Webs) { RecurseWebs(subWeb); } } //This has been fixed up (IE error exceptions added) based on //http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.availablecontenttypes.aspx void ChangeTheList(SPWeb web) { SPContentType theContentType = web.AvailableContentTypes[strContentTypeName]; //perhaps the value does not fall within expected range error happens here if (theContentType != null) //we have a content type, yay { try //get a list { SPList theList = web.Lists[strListName]; //already checked above, should not throw exception ever // Set it up to be able to add content types, won't break it if already true theList.ContentTypesEnabled = true; // Add the content type to the list if (!theList.IsContentTypeAllowed(theContentType)) throw new Exception("The content type is not allowed on the list"); else if (theList.ContentTypes[theContentType.Name] != null) throw new Exception("The content type name is already in use on the list"); else theList.ContentTypes.Add(theContentType); theList.Update(); } catch (Exception ex) // No list { throw new Exception("The list can not be found, or already contains the content type."); } } else // No content type { throw new Exception("The content type is not available in this site."); } } } }
- Hi
Just wanted to say thanks to the posters and especially Jeffimix for posting his final solution. I've taken this and expanded it so I can choose which sub-site I want to perform miracles on and I'm also about to add some more functionality like renaming a folder etc. With very many libraries and sites it perfect to do it with code intead of click, click, click...
- Hi,
Just wanted to add my two cents regarding the code:-
//This goes through every 'web' AKA SITE >:-( //in the site AKA sitecollection and if the lists exists, adds the content type void RecurseWebs(SPWeb web) { if (listExists(web.Lists, strListName)) { ChangeTheList(web); } foreach (SPWeb subWeb in web.Webs) { RecurseWebs(subWeb); } }
At no point do these SPWeb objects get disposed in the code. Its very important if your code creates a reference to an SPSite or SPWeb, that it performs the necessary cleanup.
Here's a best practices article on the subject
http://msdn.microsoft.com/en-us/library/aa973248.aspx
Paul. - Hi All,
This is an excellent solution to add content type to many or all of the site. It sounds silly but can some one please advise wether to run this script on sharepoint environment? I dont have any development environment.
so do I have to install Visual studio on my SharePoint environment?
Any help would be much appreciated.
Thanks
Pramod
SP.UK | MCTS (Microsoft Office SharePoint Server 2007) - I've deleted your duplicate post in this forum.
Either post a reply or start a new thread - not both.
Here having this post as a new thread didn't in any case make sense. ("This is an excellent solution")
(Moderator)
FAQ sites: (SP 2010) http://wssv4faq.mindsharp.com; (v3) http://wssv3faq.mindsharp.com and (WSS 2.0) http://wssv2faq.mindsharp.com
Complete Book Lists (incl. foreign language) on each site. - PramodP,
This solution as posted would need to be compiled in order to work. The code is the class file for a webpart. You would compile this webpart in Visual Studio, deploy it to Sharepoint, enter the appropriate details in it's form fields, and click the button to make the changes to your Sharepoint environment.
Jamie
Blog; http://www.the-north.com/sharepoint --- Posting is provided "AS IS" with no warranties, and confers no rights.

