How to programmatically deploy SharePoint 2010 Web Templates

Web Templates have been available in SharePoint already since the 2007 edition. I find that they are a really helpful feature, and provide a much easier and quicker way to set up a provisioning mechanism for SharePoint sites.

This blog post however is not dedicated to explaining what Web Templates are about. There is already some great material out there. Here are two links, that you should start with, to understand the pros and cons of web templates:

Vesa’s Juvonen great post, that goes into great detail about Web Templates:
http://blogs.msdn.com/b/vesku/archive/2010/10/14/sharepoint-2010-and-web-templates.aspx

Miriam van Olst post about Site Definitions vs. Web Templates
http://sharepointchick.com/archive/0001/01/01/site-definitions-vs.-webtemplates.aspx

A tutorial on how to save a site as a Web Template, and what goes into it.
http://office.microsoft.com/en-us/sharepoint-designer-help/save-a-sharepoint-site-as-a-template-HA101782501.aspx

Ok, so you now decided, that you want to use a Web Template. It’s pretty straightforward and well documented how you can do it manually, but how to do it in code?

Step 1: Save the site as a web template(as explained in the article linked above), and download the created solution file.

Step 2: Upload the solution file to your solution library, and activate it.

SPSite currentSite = SPContext.Current.Site.Solutions;
string templateName = 'TestTemplate';
SPUserSolution userSolution = null;
SPFile solutionFile = null;
string templateFilePath = @'\Templates\TestTemplate.wsp'

// Gets the solutions gallery for this
SPDocumentLibrary solutions = (SPDocumentLibrary)site.GetCatalog(SPListTemplateType.SolutionCatalog);

// Check is a solution file with this name already exists. If it does, delete it.
if (!site.RootWeb.GetFile(templateName).Exists)
{
userSolution = (from SPUserSolution s in currentSite.Solutions
where s.Name == solutionName
select s).FirstOrDefault();

if (userSolution != null)
site.Solutions.Remove(userSolution);
}

// Upload the solution file
solutionFile = solutions.RootFolder.Files.Add(templateName, File.ReadAllBytes(filePath), true);

// Activate the solution
if(solutionFile != null)
userSolution = site.Solutions.Add(solutionFile.Item.ID);

Step 3: Activate the site collection feature for the template.

Guid solutionGuid = userSolution.SolutionId;

SPFeatureDefinitionCollection siteFeatures = site.FeatureDefinitions;

var featureDefinitions = from SPFeatureDefinition f
in siteFeatures
where f.SolutionId.Equals(solutionGuid) && f.Scope == SPFeatureScope.Site
select f;

foreach (SPFeatureDefinition featureDefinition in featureDefinitions)
{
if (GetFeature(site, featureDefinition.Id) == null)
site.Features.Add(featureDefinition.Id, false, SPFeatureDefinitionScope.Site);
}

Afther that your template will be available for you to use.

Happy coding.