Partager via


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.

Comments

  • Anonymous
    July 28, 2007
    Some of you might want to make only certain site templates (otherwise called site definitions like STS#0

  • Anonymous
    August 09, 2007
    The first method you mention is now an exception and is no longer unsupported.

  • Anonymous
    August 24, 2007
    Thanks Drew, I don't know who you are :) but looking at the tiny change, I guess it will be fine! Sri

  • Anonymous
    October 04, 2007
    Site templates are NOT site definitions, it's a mistake

  • Anonymous
    June 25, 2008
    An easy way of getting your templates back is to use the SPWeb.AllowAllWebTemplates(); ;-)

  • Anonymous
    July 11, 2008
    Microsoft says in the articel that they will support you only if you change the webtemp file to hide templates in this paragraph below from the kb article. With one exception, we do not support modifying the Webtemp.xml file or the Webtempsps.xml file. The exception is the Webtemp.xml file. We support modifying the Webtemp.xml file only if you want to hide a specific template. To hide a specific template, you modify the Hidden parameter of that template in the Webtemp.xml file.

  • Anonymous
    October 12, 2009
    Hi This solution works great. I have a minor issue though, I find that the collaborations tab in the template selection gets moved. How do I get it to stay as the first tab. Regards Riedoh

  • Anonymous
    December 04, 2009
    You can also <a href="http://egrimmett.wordpress.com/2008/08/15/hide-site-definitions-via-a-feature/">hide them using features.</a>

  • Anonymous
    December 18, 2009
    Anyone figure out how to control the order in which the allowed templates appear? How would you control the tab order in the Template Selection area? I have a case where I need to default the template to be used so I need to control how the templates are ordered.

  • Anonymous
    May 02, 2011
    Must agree with Jason the SDK explicitly states editing the WEBTEMP.xml is supported, when you change the Hidden attribute. However Editing File systems on the fly to make these changes Is a definate no-no, bad admin practice. So create yourself an Admin Page in Central Admin with a pair of buttons.   Hide/Show.  This fires off a job to make those changes on each machine.  You need to monitor the state of the job to ensure it worked, and pick up the pieces if for some reason it failed.

  • Anonymous
    December 18, 2011
    I have a business requirement that hide certain templates for all users except Site collection Administrator. I thought of solving this using most commonly and easy-to-do technique is to set the "hidden" attribute value to "true" in the WEBTEMP.xml file but it has limitations that too don't know how to unhide for Site collection admi  if i follow this approach. What they need is more like dynamic.  Sometimes they want to hide or sometimes they don't want to hide.  So its difficult to move folders within template folder to hide to unhide and change everytime the HIDE FLAG.   so i thgouth of going below approach. We can make use of "SPWebTemplateCollection", using SetAvailableWebTemplates , getAvailableWebTemplates and Update member funcs. I am able to hide tempaltes from all users using above class and member funcs when feature activated by getting template names from web.config. As far as i know, feature activation/deactivation works at web/site/farm level for all users,we can not control the 'hide' depends upon user role within featureactivation. It has to be delt outside. I am not sure how and where to handle that. I thought it can be done while site provisioning but you already hide templates so how we can check that webadding event for that particular webtemplate? Is it WebAdding(SPWebEventProperties) / WebProvisioned(SPWebEventProperties). I would want to know is it possible to hide templates based on user role? If so what is the approach can you kindly let me know.  I am feeling it can be done but whats right and what better way to do it. pls guide me .