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)

foreach (SPWebTemplate template in collection)
          if (template.Name == "BLOG#0")
          Console.WriteLine("Template name in collection: {0}",template.Name);
web.SetAvailableWebTemplates(collection, (uint)1033);

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)

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.