Accessing Custom Site Templates through the Sharepoint API


Using custom site templates in Sharepoint is a really powerful feature. You can customize your WSS site through frontpage or the web UI and save the site as a template. By default the template is stored in the top-level site template gallery of the site you customized.

This template can be exported as an ".stp" file and imported on other top-level websites. But you can also place the template in two other locations. The three locations for site templates are:
Top-Level (WSS) Site Template Gallery Sharepoint Portal Server Template Gallery Sharepoint Virtual Server TemplatesTo enter the template into the Portal gallery go to Portal > Site Settings > Manage security and additional settings > Manage site template gallery and upload your ".stp" file (read on to find out why this is useless).

To enter the template into the Virtual Server Templates open the commandline at the directory \Program Files\Common Files\Microsoft Shared\web server extensions\60\BIN and run stsadm -o addtemplate -filename \sitetemplate.stp -title sitetemplate

You can run stsadm -o enumtemplates to verify that your template was added, and you'll also notice that it's been given a name like "_GLOBAL_#1". If you've added a template to the Sharepoint Portal Server Template Gallery (#2 above) you'll notice that this template is not listed when using stsadm.

  • Team Site, STS#0
  • Blank Site, STS#1
  • Document Workspace, STS#2
  • Basic Meeting Workspace, MPS#0
  • Blank Meeting Workspace, MPS#1
  • Decision Meeting Workspace, MPS#2
  • Social Meeting Workspace, MPS#3
  • Multipage Meeting Workspace, MPS#4
  • Business Activity Services Team Site, BAS#0
  • SharePoint Portal Server Site, SPS#0
  • SharePoint Portal Server Personal Space, SPSPERS#0
  • SharePoint Portal Server My Site, SPSMSITE#0
  • Contents area Template, SPSTOC#0
  • Topic area template, SPSTOPIC#0
  • News area template, SPSNEWS#0
  • News Home area template, SPSNHOME#0
  • Site Directory area template, SPSSITES#0
  • SharePoint Portal Server BucketWeb Template, SPSBWEB#0
  • Community area template, SPSCOMMU#0
  • sitetemplate, _GLOBAL_#1 <- My custom template on the Virtual Server

When you look at the Sharepoint SDK for the SPSiteCollection.Add method there is a parameter for sitetemplate. In the example they've used "STS#0", which indicated that the method expects the Name property of the SPWebTemplate, and that it makes a selection from the templates on the virtual server. So if you want to create a site with the template you just deployed with stsadm, specify "_GLOBAL_#1". If you find it uncomfortable to use this generated name a simple mapping can be applied like this:

string template = "My Template Title";
SPGlobalAdmin globalAdmin = new SPGlobalAdmin();
SPWebTemplateCollection webTemplates
= globalAdmin.VirtualServers[0].GetWebTemplates(lcid);
foreach(SPWebTemplate t in webTemplates)
if (t.Title.CompareTo(template) == 0) template = t.Name;

So what do you specify if you want to apply one of the templates in the Sharepoint Portal Server Template Gallery? After all, it's more user friendly to expose templates here than through the command line interface (if you're not doing complex automated deployments that is). Well by looking in the Gallery UI in Site settings you'll notice that the Name property of the template you've uploaded is TemplateName.stp. Supplying this as a parameter to the SPSiteCollection.Add method will not work. The template won't be found.

The only way to get a hold of these templates are by accessing the SPSite of the portal (either by using context site or creating a new object). You'll find these templates by using the SPSite.GetCustomWebTemplates method. The problem is that SPSite has no way of applying a template other than in the constructor. That leaves you with manipulating the SPSite.RootWeb object after you've created the new SPSite.

But now you've got two different SPSite objects; the portal and the top-level site you just added. Because the templates are stored on the portal SPSite object they cannot be accessed on the top level website. This is because the method SPWeb.ApplyWebTemplate(SPWebTemplate obj) actually is just an overload that reads the SPWebTemplate name property as a string and passes it down to the SPSite object, which in turn looks up in it's own template gallery.

So the conclusion is that for top-level websites you have to deploy your templates using stsadm. Then what's the use of the Sharepoint Portal Server Template Gallery? Beats me. I haven't actually found any of the templates I've added to that list anywhere else than in the SPSite object of the portal root site.