다음을 통해 공유


What if you need to hide site templates in MOSS 2007?

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.