Some of you might want to make only certain site templates (otherwise called site definitions like STS#0 for team site definition, STS#1 for blank site definition) available for creating sites in WSS 3 or MOSS 2007. Well, there are quite a few ways to do that. The most common and easy-to-do technique is to set the "hidden" attribute value to "true" in the WEBTEMP.xml file. Which, will no doubt, lead you into an unsupported scenario (as I always say 898631).
So what are the other options then? We can make use of "SPWebTemplateCollection" class to achieve this. It's a bit of a work though. But it will keep you in supported scenario and given that you don't want to do this on a daily (or perhaps hourly?) basis, I guess this is good enough solution. I have provided the sample code below: both to remove the available template and to re-add them if necessary.
To remove the site definitions available in a top-level site.
string myName = String.Empty;SPSite site = new SPSite("<sharepoint server>");SPWeb web = site.OpenWeb();SPWebTemplateCollection templates = web.GetAvailableWebTemplates((uint)1033);Collection<SPWebTemplate> collection = new Collection<SPWebTemplate>();foreach (SPWebTemplate template in templates){ collection.Add(template);}
foreach (SPWebTemplate template in collection){ if (template.Name == "BLOG#0") { collection.Remove(template); break; } Console.WriteLine("Template name in collection: {0}",template.Name);}web.SetAvailableWebTemplates(collection, (uint)1033);web.Update();
Now, for some reason if we have to get the "lost" site definition back? It's going to be tricky! Since we removed the site definition from the top-level site itself, we have no way to get a reference to the "lost" site definition just from the current top-level site's context. So now, comes the real fact! You need to have at least once site collection where "all" OOB site definitions are available in order to revert a removed site definition back. Just take a look at the following code sample that will get us the "lost" site definition and you will understand what I mean:
SPSite sourceSite = new SPSite("<url of the site where 'all' site definitions are available>");SPWeb sourceWeb = sourceSite.OpenWeb();SPWebTemplateCollection sourceTemplates = sourceWeb.GetAvailableWebTemplates((uint)1033);foreach(SPWebTemplate sourceTemplate in sourceTemplates){ if(sourceTemplate.Name == "BLOG#0") { SPSite targetSite = new SPSite("<url of the site where you want to restore the removed site definition>"); SPWeb targetWeb = targetSite.OpenWeb(); SPWebTemplateCollection targetTemplates = targetWeb.GetAvailableWebTemplates((uint)1033); Collection<SPWebTemplate> targetCollection = new Collection<SPWebTemplate>(); foreach(SPWebTemplate targetTemplate in targetTemplates) { targetCollection.Add(targetTemplate); } targetCollection.Add(sourceTemplate); targetWeb.SetAvailableWebTemplates(targetCollection,(uint)1033); targetWeb.Update(); }}
You might think the code doesn't "look" too good. I agree it introduces unnecessary complexities for a task so simple as this. However, I do believe it is for a reason (which is unknown to me).
Hope this was helpful. So remember, whenever you need to remove/hide certain site definitions from your user's sight, DO NOT TOUCH THE WEBTEMP.XML FILE. Oh, just one more thing, I haven't had a chance to try the above in SharePoint Portal Server 2003 though. But looking at the code, I don't have a reason for it to not work there.