One of the really exciting new options on the Feature Framework level of the SharePoint 2010 is the WebTemplate element. In this blog entry we’ll cover the primary site provisioning methods and we’ll concentrate especially to web template option to share the key techniques.


Introduction

As you might know, there are multiple different techniques for provisioning new sites in SharePoint. SharePoint deployments always consist from at least one site, which provides functionalities for the end users. There’s multiple ways to create these sites and to customize them based on customer requirements. In this blog post we concentrate models, which support strict versioning model. Meaning that the sites are not built directly to production environment using SharePoint Designer or browser rather deployed using solution packages.

Before we get started, let’s first concentrate on getting the terms right. There’s multiple different terms used when we reference definitions, which are used for creating new sites. Here’s the clarification on the most used one’s and how they should be used.

  • Site Template
    • Site template refers to WSP package, which was created by clicking the Save Site As Template link in the Site Settings page. In SharePoint 2007 sites were saved to specific STP format, but in SharePoint 2010 templates are using the standard SharePoint solution package model.
  • Web Template
    • Web template refers to new feature element available in SharePoint 2010, which provides us flexible way to define definition (onet.xml file), which will be used only on provisioning time, when the site is created. There are no references to the definition on runtime, which provide easy maintainability for the definition.
  • Site Definition
    • Site definition refers to classic WebTemp*.xml and onet.xml combination, which are located in the file system of server. WebTemp*.xml file is used to introduce the template for SharePoint and onet.xml file contains the actual instruction or definitions concerning which features to activate when site is created.
  • Portal site template
    • Portal site templates are hierarchy files, which are available when you use SharePoint server. Portal site templates have their own xml schema, which is used to define which kind of site definitions are provisioned and in which order. Good example of portal site template is out of the box publishing portal definitions, which provisioned example www site, with single sub site.

Why is the provisioning model such an important thing? – since overall usage models in SharePoint, especially for larger companies, are not just based on individual web parts, which are used to bring additional value over the out of the box site structures. In larger project, the productivity of the individual end users and the editors plays role for designing correct model, since we want to have as good and consistent user experience provided through out the farm.

Let’s have a real life example of one global intranet, which had 50 part time content editors and more than 700 sites in site hierarchy for each of the country sites. There’s 10 different site types, which should provide the same functionality where ever they are located. Since there’s quite a lot of content to be created and managed, it’s better to create specific templates compared to use feature stapling and browser customizations. You can only image the time spend modifying each site using browser and even though there would be documented instructions, most likely most of the sites would look little bit different than other. By providing 10 configured web templates, which will have all templates and web parts as defined by corporate communication, intranet will have consistent user experience and content editors can easily extend the sites as required.

Key point on the site provisioning is to automate something which would be done manually by site authors. Business case can be calculated quite easily from the amount time required for each site to be configured based on the company guidance. There doesn’t have to be that many sites created, before the investment for customization is worthwhile.

I’ve been still seeing demos and real production environment where the end users or content authors are forced for example to active features manually in certain order to configure the site as planned. This should not be the case, since it also increase risks of breaking up the sites by for example activating accidently wrong features.

Other consideration is obviously the implications due the customizations. Certain options available can cause implications on maintenance and upgrade processes, which will impact on the overall costs included in the deployment. Luckily in SharePoint 2010, we now have the new Web Template option, which will help to address these issues.

So key advantage of automating the site provisioning to save time and ensure consistent end users experience throughout the particular deployment. This is not only important for WCM sites, but also for other site types to provide consistency.

Different site provisioning methods in SharePoint 2010

There is four or five different main models for site provisioning in SharePoint 2010, depending what’s considered as individual models. 

  • Feature stapling
  • Site templates
  • Web Templates
  • Site definitions
  • Provisioning provides
  • Custom code (mainly for automated processes)

We’ll cover each of the options in high level to consider the different advantages and disadvantages in each of them, except the full custom code option, which obviously can be anything. These options will concentrate on different ways to control what’s provisioned when end users uses the out of the box Create functionality.

Feature stapling

Primary purpose of the feature stapling is to extend and customize existing site definitions. Usually these are used to provide some custom functionalities for the out of the box site definitions, but technique is definitely available also for the custom site definitions.

Since it’s not supported to change the onet.xml file of site definitions after it has been used in environment, feature stapling is quite commonly used also to provide versioning for the already deployed custom site definitions. You can modify the stapling definitions to different site definitions also afterwards. It’s important to remember that stapled features are only activated on provisioning time, so if there’s any existing sites already provisioned, those won’t be affected automatically just by deploying new stapling definitions.

Biggest downside with the feature stapling is that we can only extend the existing site definitions, we can’t provide new. This can be an issue for example when you’d like to have WCM templates created for multiple different site purposes. Also the fact that stapled features are activated before the module element or list elements in onet.xml file has been provisioned, can cause issues unless you use some workarounds. Notice also that feature stapling is only supported when site definitions are used, it doesn’t work if you are provisioning sites using site templates or web templates, even though these both options refers to root site definition.

clip_image001More information

More information concerning feature stapling in SharePoint 2010 can be found from following locations:


Site templates

As you might know SharePoint 2010 has changed the functionality used for saving existing sites as template. In 2007 version when site was saved as a template, specific STP file was created, which could not be modified in anyway. In 2010, when we save site as template, SharePoint generates full fledge solution package (WSP file), which can then be moved between any environment containing all site level objects, like libraries and optionally also content.

There are two key improvements in feature framework scheme, which have made this possible. These are WebTemplate element and CustomSchema attribute for ListInstance elements. These two options will make it possible to provision sites using alternative xml definitions, but then refer back to out of the box templates. Key point is that we use alternative definitions during provisioning, but all object references will be associated to out of the box types.

One of the biggest downsides with the site templates is the fact that they are not supported when publishing features are enabled. This is also the reason why we hide the link from the site settings page to avoid anyone to use this functionality. Obviously if you know the aspx page name, you can access the page and save the site as a template also when publishing features are enabled. This is however not supported. What does that mean? – just because you can… doesn’t mean you shouldn’t. Publishing sites have complex references and dependencies, which have to be carefully defined even for site definitions. This is not supported (and link is hidden) so that inexperienced users wouldn’t break intentionally their deployments.

One of the consideration with the site templates is also the fact that unless you import them to Visual Studio and modify its settings, they are only available on site collection level (site collection scoped feature), which means that to be able to have the template available from multiple locations, we’ll have to either deploy the site template as sandbox solution to multiple site collections or deploy it as full trust solution and then activate the particular feature in site collections to have the template available.

clip_image001More information

More information concerning Site Templates can be found from following locations:


Web Templates

We’ll concentrate more detailed on the Web templates in later chapters, but basically with the web templates in this case, we refer to manually created WebTemplate elements in the Visual Studio. We need to create two files for each of the web templates. Other one is empty element (is VS2010 is used) for defining the actual WebTemplate element and other one is completely similar onet.xml file as for site definitions, with few exceptions, which we’ll cover little bit later.

When we have our web template created, we’ll associate the element file to feature, which will be responsible of deploying the web template. WebTemplate element is supported in two scopes, which are Farm and Site. This means that we can deploy the web templates to be available either throughout the farm or based on site collection scoped feature activation. It’s important to notice that dispute the fact that we’d be using site collection scoped feature for deployment, we can still deploy the web template using farm scoped feature. This would for example give us possibility to filter the options available from the Create site functionality, based on feature activation status.

One big advantage of the web templates is the fact that since they are feature based and there won’t be any files stored in file system, those are completely supported usually by the cloud services, like MS Online (BPOS). Support obviously varies based on the cloud service types, like in MS Online case, if the service is dedicated or standard. These usually mean for example differences on the support for full trusted solutions or only sandbox solutions.

One really important advantage with the web templates compared to the site templates is the fact that we can utilize the publishing features in web templates. This provides us possibility to create new site provisioning options to be available from the Create site functionality, even though we would be creating new publishing feature based sites..

We’ll walk through exact details and web template creation is upcoming chapters.

clip_image001More information

See end of the article for references and links concerning web templates and manual creation of them.


Site definitions

Site definitions are the classic xml files, which are for example used to provision out of the box sites. Many of the developers learned to create these in 2007 version, since they are very powerful and there were almost no other options available for introducing new options for the Create site functionality. As mentioned earlier site definition consists basically from two different files: WebTemp*.xml and onet.xml files.WebTemp*.xml defines how the site definition is visible for the end users and the onet.xml file contains the definitions for the actual site provisioning.

We can only deploy site definitions using farm solutions, since files will be located in the file system. They are also by default available throughout the farm in every application, unless we limit the visibility either using AvailableWebTemplates attribute for publishing sites or more generally available VisibilityFeatureDepency attribute in the WebTemp*.xml file. Since we won’t be concentrating on site definitions in this blog article, I won’t be covering these options more detailed.

Key change in the site definitions for the 2010 version is that if you have site collection scoped feature associated to site definitions under the SiteFeatures elements, those features are not activated, if you create sub sites. In 2007, also these site collection features where activated also for sub sites. This could be an issue when for example you want to add new Events site under corporate intranet and you’d like also for example content types to be created, when site is provisioned. There are workarounds for this, which are declared later in the web template creation chapters (same workaround applies for site definitions).

Whenever we create site based on any site definitions SharePoint stores the site definition identifier information to SPWeb.WebTemplate, SPWeb.Configuration and SPWeb.WebTemplateId properties. These are critical properties in the SharePoint platform, which have to be set for each of the sites. Let’s come back to this in following chapters with detailed web template information.

Biggest challenge with the site definition is that we are not allowed to change the onet.xml file after it has been used to provision any sites in the environment. This is just not supported. There are certain scenarios, which don’t impact the existing sites and it might seem that update didn’t cause any issues, but just because it didn’t hurt the first time, should you do it again? – no. This is one of the classical rules of SharePoint development, like the fact that don’t touch the databases directly.

Already in 2007 version there was numerous approaches to go around the fact that onet.xml file should not be updated. Most classic one, is the so called “minimal site definition approach”, where we all possible customizations to features, which don't’ have to be activated in certain order. Let’s not spend too much time on this, but generally out of the box site definitions are actually quite awful examples for custom site definitions (quick summary).

Due these upgradability issues and SLA commitments with the customers, site definitions are NOT supported usually by the cloud services, like in MS Online. It would be simply foolish to impact on the service quality by allowing site definitions to be used, especially since we have at least as good options available in SharePoint 2010, which don’t compromise the service in short or long term.

clip_image001More information

More information concerning the site definitions can be found from following locations:


Provisioning providers

Portal provisioning providers are technique where we completely replace the onet.xml file using code, except that we usually still use some out of the box site definition as the starting point. This means that we only use WebTemp*.xml file and assign our custom provisioning class to be used, when particular template is selected. As long as we have implemented our custom provisioning provider by inhering the out of the box SPWebProvisioningProvider class (Microsoft.SharePoint.SPWebProvisioningProvider) and the associations in WebTemp*.xml are correct, we would have full control on the actions to be performed.

Common implementation uses SPWeb.ApplyWebTemplate method to provision the starting point based on some out of the box site definition and then manipulates the created site using code. This is extremely flexible model, since you can easily update the code just by deploying new version of the used assembly… but wait… isn’t this almost the same model as for the web templates…

One implmentation of the provisioning providers is the PortalProvisioningProvider (Microsoft.SharePoint.Publishing.PortalProvisioningProvider) which is available in the SharePoint Server side, not from foundation. This provides the capability to create portal site templates, meaning hierarchy files.

Since provisioning providers require that the they are introduced using the WebTemp*.xml file, which has to be placed to file system, these are not usually supported for the cloud based services, like in the MS Online. This is also due the fact that the provisioning engine would not be standard and if all projects could implement their own provisioning engine, quality assurance required would increase enormously.

Notice also that this model is not recommended due future plans of SharePoint. Interface is not yet deprecated, but I' would not bet my business on this one, even though it might sound really compelling.

clip_image001More information

More information on provisioning providers can be found from following locations:


Web template option in detail

Let’s cover the web template option little bit more detailed, so that overall model is understood properly. Following picture defines the process steps for creating new site based on the web template.

image

# Description
1 When ever either site collection or farm scoped feature has been activated on the particular site with web templates, these templates are available from the Create functionality in similar way as site definitions.

Web templates are deployed as features. If they are deployed as farm solution features, they are located in the 14 root folder, but obviously with Sandbox solutions, they are located in the content database. Element file define the preview picture, filtering options and the title visible in the create site functionality.
2 When web template is selected, new site is created using onet.xml file definition located in the same feature folder as the element.xml file, which was responsible of introducing it. Notice also that this onet.xml file can only have one Configuration element (with id 0).
3 In similar way as for site definitions, each feature referenced in the onet.xml file are activated in the order they are listed. When we create sub sites, web scoped features are activated, but if we use web template to provision site collection root site, also site scoped features are activated.
4 As part of the site provisioning process, the just created site is associated to some existing site definition, preferable to some out of the box site definition. This definition association is defined in the web template element file or in the WebTemplate element.

This means that SPWeb.WebTemplate, SPWeb.Configuration and SPWeb.WebTemplateId properties are associated to some out of the box template. Meaning that we only used the alternative onet.xml instructions during site provisioning, but from that point forward, site is as any out of the box site… also when we upgrade the SharePoint deployment in future.

There are minor limitations in the web template onet.xml file, meaning that certain elements are not supported there. These elements are not usually used or they can be replaced using approach to use feature activations. Following elements of the onet.xml file are not available for WebTemplate onet.xml schema.

  • Module element – Used normally for oob site definitions to provision default.aspx and other initial files to site as part of the site provisioning engine. Shouldn’t actually be used for site definitions either. You can provision the necessary files using features, which are referenced in the onet.xml file. We’ll cover this in upcoming chapters more detailed. Note. This actually works, but it’s not supported based on MSDN article and shouldn’t be used anyway in onet.xml file, even though out of the box site definitions do so.
  • Components – Not commonly used element. The Components element specifies components to include in sites created through the definition.
    • FileDialogPostProcessor – Represents an interface in Microsoft SharePoint Foundation that is used for Web views in the file dialog boxes and forms of document libraries
    • ExternalSecurityProvider – Represents an interface that returns custom information about the security used in Microsoft SharePoint Foundation for indexing by a search crawler on a portal
  • ServerEmailFooter - The ServerEmailFooter element specifies the footer section used in email sent from the server.

So what does this mean? – in similar way as in the classic minimal site definition, we should concentrate on provision and configure everything from the features, which are associated in the onet.xml file.

image

As mentioned already earlier, we cannot staple features to web templates, but there’s actually no reasons to do this. Why? – well… since web template onet.xml file is only used provisioning time of the site and it’s completely supported to update the web template onet.xml, if any changes are required. This means that we don’t actually have valid business case for feature stapling support, since we can handle the update using alternative approach. This is not actually that big a deal, since actually feature stapling can be extremely confusing in large deployments, since there’s no easy way to solve which features have been associated to which site definitions.

One of the big advantages in web templates is the fact that we are able to provide new options to Create site functionality without requirement to deploy site definitions. Since web templates are also supported if they are deployed as Sandbox solutions, we can utilize them also in hosting scenarios, like in MS Online (BPOS). This is huge advantage, since it solves one of the classic limitations of providing new templates in shared environment scenarios.

Other advantages and extremely important thing to realize with web templates is the fact that we can utilize them even if we would use publishing features in our sites, meaning that we are creating WCM sites in SharePoint. There’s clear difference in this compared to site templates. Publishing features are not supported in site templates, but they are supported in web templates.

I’ve had quite a few arguments also concerning the missing support of creating hierarchies with web templates compared to site definitions. We'll, to be precise, you can’t define hierarchies with site definitions directly, but if you utilize the portal web templates, we can create multiple sites from one option. This requires configuration in the WebTemp*.xml file, which we don’t have for the web templates. This is indeed one limitation, but as with any area of SharePoint there’s always workarounds… Winking smile

If you have requirement to create multiple sites at once, which is completely common scenario for example when we want to create the initial hierarchy of the some global intranet, you have few different options. If it’s one time or few times hierarchy creation, it’s actually much more efficient to define the hierarchy in PowerShell script and use that for creation. Other option would be to use similar approach as was used for Report Center creation back in 2007 version. This means that you create your hierarchies from features, which are associated to your onet.xml file. Those who are familiar of SharePoint object model, definitely knows how easily this can be done from feature receiver.

Whenever we need to reference to our custom web template for example for provision new site based on it, we’ll need to know the template name, which is defined for the WebTemplate element and also the GUID for the feature responsible of introducing that to SharePoint. So the format is as follows.

  • {FeatureGuid}#WebTemplateName
  • So example would be - {7642399e-798a-4eaa-9214-e80175e91463}#News

In following picture we provision new root web based on custom web template.

image

So, when we need to create site collection root site and create initial hierachy for the site collection, we can use following script. Notice that obviously your feature GUIDs and web template names will vary.



#set initial parameters
$name = "Vesku Corporation"
$url =
http://www.contoso.com
$scOwner = "contoso\administrator"
$template = "{8642399e-798a-4eaa-9214-e80175e91463}#Home"

#Create site collection and provision the root web based on web template
New-SPSite -URL $url -Name $name -OwnerAlias $scOwner -Template $template

# Services section
New-SPWeb ($url + "/Services") -template "{7642399e-798a-4eaa-9214-e80175e91463}#Section"-name "Services"
New-SPWeb ($url + "/Services/Consulting") -template "{7642399e-798a-4eaa-9214-e80175e91463}#ContentLeft"-name "Consulting"

#Products section
New-SPWeb ($url + "/Products") -template "{7642399e-798a-4eaa-9214-e80175e91463}#Section"-name "Products"
New-SPWeb ($url + "/Products/Widget") -template "{7642399e-798a-4eaa-9214-e80175e91463}#ContentLeft"-name "Widget"

#About us section
New-SPWeb ($url + "/aboutus") -template "{7642399e-798a-4eaa-9214-e80175e91463}#Section"-name "About us"
New-SPWeb ($url + "/aboutus/company") -template "{7642399e-798a-4eaa-9214-e80175e91463}#ContentLeft"-name "Company"
New-SPWeb ($url + "/aboutus/directors") -template "{7642399e-798a-4eaa-9214-e80175e91463}#ContentRight"-name "Directors"



With web templates, there’s however one big disadvantage or case where they cannot be used. This is when your technical multilingual solution would be based on variation functionality. Variations can be used for providing multilingual solution for your solution when hierarchies between the different languages are identical (or almost identical). Variations work in a way that you select one language or hierarchy to be your primary language and other site hierarchies for are created based on this primary language.

In 2010, the variation functionality was changed to be timer job based, so there’s timer job, which ensures that the sites are copied properly between different variations, based on changes in root language. Since we don’t have any out of the box indication in sites that they have been created using web template, this timer job is unaware of the fact that template information in SPWeb object is not valid, since that refers only to some base site definition.

There’s unfortunately no workaround for this limitation concerning web templates currently, but let’s hope that variation functionality would be fixed to be aware of some indication on the used web template soon, maybe in some service pack. This does not however mean that you can’t do multilingual sites with web templates; it only means that you can’t use variations with web templates. Good examples of multilingual sites without variations is for example my old baby from back in autumn 2007, which has numerous different languages, like the following: www.kone.cn, www.kone.de and www.kone.ru.

 

Additional design guidelines for web templates

Now we have covered the key concepts of the web templates. Let’s also cover few guidelines for implementing these web templates in a way that we’ll follow good practices and increase the maintainability of our sites.

One of the key things to consider is the upgrade and maintenance model of the web templates. As experienced SharePoint developers know, the quality of the code and design is actually evaluated during the upgrade of these customizations. To improve maintainability and upgradability of your web templates or actually sites, created based on your web template, we should always create specific default web scoped feature for each of the web templates. Let’s clarify this more detailed in picture below.

image

# Description
1 Obviously we can have miscellaneous amount of features referenced in our onet.xml, which are responsible of creating the required structures. You should however consider that could you associated your SharePoint project items actually to default feature, since each feature activation will have impact on the time required for site provisioning, so less is good, especially since we can associated the SPIs easily in VS2010.
2 Default hidden web scoped feature dedicated for the particular web template defined as the final feature under the WebFeatures section in the onet.xml file. This feature will be responsible of provisioning the welcome page of the site (default.aspx) and other structures required in the site.

This feature should also stamp the identifier of the web template to site property bag. This identifier would be the WebTemplate name used of the particular, which is being created.

We’ll demonstrate this in the example later in this article.

As mentioned, the default web scoped feature should be marked as hidden, so that it’s not accidently deactivated from user interface. This is also the feature, which we’ll use as part of our versioning model, since whenever we need to change the existing sites, we would have possibility to target our new customizations by versioning this particular feature. This way you can easily write the required feature upgrade actions and apply them to proper sites.

So the hidden feature is for versioning the already provisioned sites and the versioning of the actual web template can be just done simply by updating its onet.xml.

clip_image001Note

More information concerning feature versioning support in SharePoint 2010 can be found from following locations:

One of the challenges in SharePoint 2010 web template provisioning and actually also in site definition provisioning is the fact that if you provision sub sites to already existing site collection, none of the site scoped features mentioned in onet.xml file are activated out of the box, like it was the case in SharePoint 2007 for site definitions. Someone might say that this functionality was already a bug in 2007 and now it’s fixed, but add us small challenge.

Quite often in projects you’d like to introduce some new functionalities after the initial version of the collection has been already created. Let’s image following case: We have existing corporate intranet and we’d like to add new events functionality to the intranet. Events functionality will include web parts, content types and some page layouts. It will also include some other configurations. Wouldn’t it be nice, if all of these required artifacts would be provisioned when I create the Events sub site, if they are missing.

Well in this case, due the required scope of the artifacts (page layouts, content types, web parts), we would be forced to first activate the features in certain order, to be able to create the sub site, which consumes them. Not necessarily big deal, but definitely also not optimal one either. Following picture defines solutions for this case.

image

Solution is to create web scope feature, which will verify that the required site collection scoped features are activated. If they are missing, feature receiver would activate those. This is relatively simple feature and only few lines of code, but it provides us a way to create completely isolated and independent web templates, which will create all required structures required for the particular functionality.

The only downside of this solution is the fact when we create sub sites from user interface, SharePoint 2010 will check that all site collections scoped features mentioned in onet.xml are actually activated. This means that this workaround works when you create your sites from PowerShell or if you don’t list your site collection scoped feature at all in the SiteFeatures elements. I completely understand the checking and verification, but it’s not implemented in most optimal way.

We’ll cover required code for this in our step-by-step guidance later in this article.

Step by step creation of new publishing web template

In this chapter, we’ll create new globally available web template, which will use publishing features to enable efficient content editing experience. We’ll do this steps by step, including the concepts defined above.

Setup initial structures

Let’s start by creating the necessary initial structures. Since my background in from 2007, I always start by thinking the overall layout of features and then I associate the required SharePoint projects items to them.

Start Visual Studio 2010 and choose Empty SharePoint project as your starting point

  • Personally I always start with empty project template, since you get the same wizards as from other templates when you add particular SharePoint project items (SPI) to your project.
  • In my case I named the solution as Contoso.Intranet.WebTemplates, so that it follows the general guidance for naming your SharePoint solutions uniquely

Choose the solution to be farm solution, since in this case we want to deploy our template globally. As mentioned earlier, you could also deploy your template only in site collection level.

Notice that we follow few naming guidance's for the features, which are creating. This is done to optimize the developer productivity by providing easy overall picture of the solution just by viewing the solution structure in Solution Explorer or in the Packaging Explorer. We’ll also hide all features, which should not be touched by end users to avoid any issues after initial deployment.

Let’s add a new feature to your project with following attributes. This will the default web scoped feature, which will be responsible of deploying welcome page and do other web (or site) specific configurations.

  • Title: Contoso.Intranet.WebTemplates - Site - Default
  • Scope: Site
  • Is Hidden: True
  • Feature node name: SitePublishingWebTemplateDefault

Let’s add another feature to your project with following attributes. This feature will be responsible of deploying all site collection scoped configurations, which the site will consume. In this case, this includes content types and page layouts. This feature will be also used as the versioning model for the existing sites, whenever there’s some changes required. With this I mean that since the feature is hidden it should be active and available in every site which were based on this upcoming web template and therefore we can easily upgrade them by using the new feature versioning capabilities in SharePoint 2010.

  • Title: Contoso.Intranet.WebTemplates - Web- Default
  • Scope: Web
  • Is Hidden: True
  • Feature node name: WebPublishingWebTemplateDefault

We’re still missing some required structures, so add third feature, which will be responsible of activating the default site collection scoped feature in case that we create sub sites. As mentioned above, this is due the fact that if you create sub sites, the site collection scoped features won’t be activated in SharePoint 2010 without little help. We’ll implement this as generic feature, so that

  • Title: Contoso.Intranet.WebTemplates - Web- Default
  • Scope: Web
  • Is Hidden: True
  • Feature node name: WebEnsureSiteScopedFeature

So at this point we have all features, which will be associated to actual web template, but we still need to create the feature responsible deploying it or feature, which will be responsible of telling for SharePoint that the template is available. We’ll do this with farm scoped feature, so that when ever the solution package has been deployed, there’s new web template available through out the farm.

  • Title: Contoso.Intranet.WebTemplates - Farm - Web Template deployment
  • Scope: Farm
  • Is Hidden: False
  • Feature node name: FarmWebTemplateDeployment

After this your Visual Studio Solution Explorer should look like in following picture.

 image

Creating required SharePoint project items

In this business case, we’re creating new complete web template, which has also publishing features enabled. Quite often you’ll need to add new site columns to out of the box Page or Welcome Page content types (it would be long debate which one to use in WCM cases, so let’s not go there…) and therefore you’ll need to create your own content type. As you probably already know, creating new content types is relatively straight forward in the SharePoint 2010 development, so let’s not concentrate on details of getting these elements in, rather on the web template specific features.

I tend to group my SPI’s under SP folder and to specific sub folders to make the overall structure more easier to track. This is especially important in larger projects, which have multiple Visual Studio projects in them, but that’s a completely another blog entry (maybe in future :-).

We’ll nevertheless have the following folder structure as the starting point for following SPIs. We have already created the required custom content type and the page layout, which our web template will use by default.

image

Most important SPI is the welcome page module for the WebTemplate. This SPI will be associated to default web scoped feature, which will be activated as part of the site provisioning process. So how do we do that? Let’s click the Module folder and choose to add new Module element. We’ll name the module as MOPublishingtemplateWelcomePage.

image

You might again wonder the silly prefix for the module, but that’s also for increasing the developers productivity in larger projects. It will help to identify your individual elements in the Feature Designer and in the Packaging Explorer when you have tens of SPIs in your Visual Studio solution.

By default Visual Studio provides as example text file to be deployed, which we can completely remove, since we don’t use it in this case.

Since this is WCM site, we’ll need to have the default redirection page included in this module and to associate it properly to pages library with required attributes. Attributes in this case refer to page layout and content type which we want to use. We can copy the out of the box redirection page from SharePoint structures. This can be done by copying the default.aspx file for example from the following location: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\SiteTemplates\PUBLISHING. Notice that we’ll need to copy default.aspx page, which is used out of the box for publishing sites, not for foundation sites (big difference).

Following thing is to update the elements.xml file of the just created Module SPI with the following values:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="Home" Url="$Resources:osrvcore,List_Pages_UrlName;" 
          Path="MOWelcomePagePublishingWebTemplate">
    <File Url="default.aspx" Type="GhostableInLibrary" Level="Draft" >
      <Property Name="Title" Value="Welcome" />
      <Property Name="PublishingPageLayout"
                      Value="~SiteCollection/_catalogs/masterpage/
                      ContosoWelcomeLinks.aspx, Contoso Template" />
      <Property Name="ContentType" 
                Value="ContosoIntranetWebTemplatesPage" />
    </File>
  </Module>
</Elements>

Notice that we refer to our custom page layout (ContosoWelcomeLinks.aspx) and to custom content types (ContosoIntranetWebTemplatespage) in the properties. This will set the default settings properly for the page layout when the site is provisioned.

Since by default our custom content type is not available in the pages library, we’ll need to create additional SPI for it. This can be done by adding new empty element under the ContentTypeBindings folder. Element file should be updated as follows (obviously with the full GUID of the content type):

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentTypeBinding ContentTypeId="[ContentTypeGUID]" 
                      ListUrl="pages"/>
</Elements>

Since SharePoint provisioning is based on the order of the element files in the feature definition, we’ll need to ensure that the content type binding SPI (CBPublishingSite) is listed above the welcome page SPI (MOWelcomePagePublishingWebTemplate) in the Feature Designer. If that’s not the case in your environment, remove the items from the feature and associate the in correct order (in larger deployments you might want to do this by updating the order inside the VS structure).

image

We are still missing one SPI, which will be responsible of adding the upcoming web template identifier to site’s property bag, so that after we have traceability on the used web templates and we can easily solve which template was used to provision particular site. As mentioned earlier, since the SPWeb.WebTemplate and SPWeb.Configuration properties will be “stamped” using some out of the box identifiers, those cannot be used to identify the template. Not a big deal, since it only requires one more SPI to be created.

Let’s create new empty SPI to new PropertyBag folder and update it content as follows. Notice how the use the new ProperbyBag element in feature framework to add entries to SPWeb property bag.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <PropertyBag ParentType="Web">
    <Property Name="contoso.intranet-webtemplateid" 
              Type="string" Value="WTPublishingSite" />
  </PropertyBag>
</Elements>

This is the most important thing to remember in your web template development, so don’t skip this step, since otherwise you have no traceability on the created sites. Why is that so important? – For easy maintenance and upgrade models, this information could be required… there’s actually other ways to do same things, but this is easy and most straight forward way to stamp the item.

Remember to also ensure that the property bag entry SPI is associated to correct feature (WebPublishingWebTemplateDefault). Order does not actually matter in this case.

Now we have all the required SPIs for the web template in this case. Obviously you could have created other SPIs as well, for example to provision new list structures as part of the site provisioning. After this your Visual Studio Solution Explorer should look like in following picture.

image

 

Creating WebTemplate element

Since there’s no out of the box SPI template for web templates, we’ll need to create it using standard empty element. Let’s add new empty element under the WebTemplates folder and modify it as follows (in my case I named it as WTPublishingSite):

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <WebTemplate
           Name="WTPublishingSite"
           BaseTemplateName="CMSPUBLISHING"
           BaseTemplateID="39"
           BaseConfigurationID="0"
           Title="Example Publishing Site"
           Description="Custom publishing web template"
           DisplayCategory="Contoso Publishing"/>
</Elements>

Notice how we customized the display group entry. This is the key introduction file, which can be used to control web template visibility for example that can it be used to create new site collections or not. If the web template has been deployed as farm feature and you only allow it to be used as sub sites, it would not be listed in the central admin as one of the options. This can be controlled by using SubWeb attribute (note. unfortunately there seems to be bug with this one at least with the RTM to august cumulative and the attribute doesn’t have any meaning at the moment – hopefully it will be fixed soon).

Notice also the BaseTemplateName, BaseTemplateID and BaseConfigurationID – as mentioned earlier, these have to refer to some existing site definition. We don’t use any of the content from that site definition, but this information is used to “stamp” the created web with some site definition identifier.

Only thing missing is the Onet.xml file, which actually defines in detail site provisioning tasks. In this case we are creating publishing feature based web template, so easiest way to get started is to copy the onet.xml file available from following folder: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\SiteTemplates\BlankInternet\XML

Let’s copy that to WTPublishingSite SPI, right next to element.xml file in Visual Studio (drag and drop). First thing we’ll need to update is the properties of the onet.xml file to ensure that it’s deployed as part of the SPI. Just activate the file in the Visual Studio Solution Explorer and ensure that properties are as follows.

image

This will ensure that the file is packaged by the Visual Studio 2010 to the solution package, based on the associations in the Feature Designer. Following thing is to make the required updates on the onet.xml file. Onet.xml file structure for the web templates is completely identical as for the site definitions, except that there’s few elements, which are not supported. These elements are not actually that meaningful even for site definitions, since same functionality could be always provided using alternative approaches, like from feature receivers etc. I won’t go to details of the onet.xml structure too much, since that is a huge topic, but I’ll cover the key changes done in this case.

Let’s first start by removing cleaning up all unnecessary elements. We’ll get rid of following sections in the onet.xml file:

  • Document templates
    • Not meaningful for demo and could be done from feature anyway
  • Other configurations than configurations –1 and 0 – meaning getting rid of configurations 1 and 2
    • With web templates, the 0 is the only valid configuration
  • Modules
    • Referring to those listed in the bottom of the onet.xml file, we don’t need these either, since we’ll provision the default page from feature as well.

If it would be out of the box team site template, we’d also get rid of all the list instances, since those can be done more easily from features.

Associating features to web template

Association of feature to onet.xml can be done easily as you might know from site definition development. We’ll first need to solve the identifier and scope of the feature to be associated and then we’ll just include that to proper location. Since we can activate site collection and web scoped features from onet.xml file, there are separate places for these. If you associate site collection feature, it has to be listed under the SiteFeatures element and all web scope features are listed under the WebFeatures element.

In this case we have three different custom features, which we should associate to proper places in the onet.xml file. By default you’d add the site collection scoped feature to SiteFeatures section, but since we want this feature to be activated automatically as part of our provisioning technique, we can’t do that. This is due the checking SharePoint does for sub sites. If template has site collection scoped feature, which is not activated, you’d get following error when you create the site from user interface.

image

So we’ll need to be little bit cleaver with our solution.

Let’s add a feature to our onet.xml file, which will be responsible of activating the site collection feature automatically, if web template is used for sub site creation. We’ll create the necessary code for the feature receiver in following chapter, but we can already add this required xml elements. Idea is that we can define which site collection scoped feature will be activated using feature properties. Since we want to ensure that the site collection scoped feature is activated before any web scoped features, we’ll need to add this as the first feature in the WebFeatures section, like in the following snipped.

<WebFeatures>
    <!-- Custom Site collection scoped feature activation -->
    <Feature ID="6e018893-bd28-44da-8048-a9752ca9d4ae">
      <Properties xmlns="http://schemas.microsoft.com/sharepoint/">
        <Property Key="SiteScopedGUID" Value="79b93e74-ce13-49d1-825b-5007feb8d481"/>
      </Properties>
    </Feature>

Notice that the above feature is custom feature, so it’s up to us which kind of feature properties are implemented.

Following step is to add the provisioning of welcome page, which we implemented in previous chapter. Since we want all structures be ready, before we provision our welcome page and optionally do some additional customizations from feature receiver, we associate this feature as the final feature to WebFeatures section, like in the following snipped.

            <!-- Welcome page provisioning for the web template -->
            <Feature ID="5bd39d1e-9e39-4e4f-932c-eb393b5454a4" />
        </WebFeatures>
        <Modules />
    </Configuration>
</Configurations>

Notice that this is also the feature, which can do any customizations for just created site; since possible feature receiver in this feature is executed after all other configurations are applied. So for example if you’ll need to do some web part connections for the welcome page, this could be done in this feature, since welcome page is first deployed and then our feature receiver is executed.

Adding code for the feature receivers

Let’s move to add the necessary code for our feature receivers or actually to only one in this case. Required code was to activate the site collection scoped feature, which has been referenced in the WebFeatures section. So let’s right click WebEnsureSiteScopedFeature in our project structure and create the required feature receiver for the feature.

You can comment out other methods, than the FeatureActivated method, which is executed when feature is activated as part of the site provisioning. Let’s update that as in the following code example.

public override void FeatureActivated(
                       SPFeatureReceiverProperties properties)
       {
           //Ensure that scope is correctly set
           if (properties.Feature.Parent is SPWeb)
           {
               SPWeb web = (SPWeb)properties.Feature.Parent;
               foreach (SPFeatureProperty property 
                               in properties.Feature.Properties)
               {
                   Guid featureGuid = new Guid(property.Value);
                   //Verify feature status
                   SPFeature feature = web.Site.Features[featureGuid];
                   if (feature == null)
                   {
                       //Activate site collection scoped feature, 
                       //if requested and not currently activated
                       web.Site.Features.Add(featureGuid);
                   }
               }
           }
       }

So what do we do in the code? – We’ll read the GUIDs from the feature properties and activate, if they are not activated. This way we can activate site collection scoped features also from web scope feature, which provided us the way to encapsulate all features part of the web template to single provisioned package. You might want to improve the error handling and logging in real scenario, but this is fine for demonstration purposes.

Testing and ensuring that it’s working

So how do we test the functionality? You actually don’t want to just start debugging with default settings, since Visual Studio 2010 would activate the site collection scoped feature for you automatically based on the ActivateOnDefault setting of the particular feature. This is nice for debugging point of view, but that’s not actually the way it works in real life or when you deploy your customizations from development environment to production environment. ActivateOnDefault attribute for site collection scoped features is only valid for Sandbox solutions, but not when farm solutions are used, so let’s try to verify the functionality using alternative approach.

Before deploying, verify that you have No Activation as the Active Deployment Configuration for your Visual Studio solution, so that features are installed, but not activated. This can be controlled from project properties. Deploy your customization or you can also start by debugging for verifying the functionality.

image

Not that compelling, but demonstrates the web template functionality quite nicely, so it’s cool template – Yes I’m a geek.

Example project found from reference list will also contain example web template for custom collaboration or team site. Collaboration example has been only modified slightly compare to out of the box team sites, but it still has the same upgrading or maintaining support etc. There’s also example of adding web parts to welcome pages from the default web scoped feature. Nothing actually new there for web templates, meaning that same model as for site definitions will work there as well.

Web Template FAQ

In this section we’ll cover few of the most common questions concerning web templates. Most of the questions have been already covered more detailed earlier, but just to summarize them.

“I associated my web template to some existing site definition, what is used from the root site definition’s onet.xml file?”

  • Absolutely nothing. Onet.xml of the web template will completely replace the referenced site definition during provisioning. Model is actually identical as if you would be using the new CustomSchema attribute available for list instances.

“When I use site definitions, object properties will get recorded correctly (SPWeb.WebTemplate etc.), so I’m unable to track which sites were created using which template. This is huge disadvantage on web template. “

  • That is true, but nevertheless you’ll need to write some logic to access those properties in your custom code. It’s as easy to access the property bag of the SPWeb as long as you remember to add the information there as suggested earlier in this article.
  • You actually never know what features have been activated on top of the initial site definition, so the advance of having exact identifier available is not actually even that important. In upgrade or maintenance scenarios, we’ll nevertheless need to figure out the actual features which have been activated.

“Why wasn’t the requirement to stamp the SPWeb to site definition removed or support to use the web template identification information added for that? “

  • This is due the backward compatibility requirements. If these would have been completely removed, there would have been lot of the custom code developed by you and me, which would not worked in SharePoint 2010. These properties are also one of the core properties of the whole SharePoint platform, so changing those would cause huge quality assurance activities.
  • Those of you who been working in R&D definitely understand the historical legacy products are carrying – let’s not go too much details on this.

“You can use the WebTemp*.xml to define the portal hierarchy to be created using the portal site template approach. If I use web template approach, there’s no way to do the same.”

  • True, since the WebTemp*.xml file is not created or required, since all web template related files are actually stored in the database and WebTemp*.xml file changes requires deployment of the files to file system of the servers.
  • As covered earlier in this article, there’s two different workarounds for this. For in-frequent use, you should be using PowerShell for the hierarchy creation and if you constantly create multiple sites at once, you can easily achieve this from feature receiver.

“What about BPOS (MS Online) and generally other hosting companies? “

  • Generally, like for BPOS, web template is supported way to deploy your customizations, since that way individual sites can be more easily upgraded in future versions. If you create site definitions to some deployment, migrating that to cloud could be enormous effort. By utilizing the web template approach, you provide more flexibility for that deployment also in long run.

“I heard that WebTemplate element is designed only for Sandbox solutions, is this true? “

  • No. WebTemplate element is part of the feature definition schema and it’s available also for full trust solutions. References to Sandbox solutions are only caused by the fact that it has been the most visible usage for the WebTemplate element in public demos.

“When I’m creating my web template I need to decide to which out of the box site definition it will be associated. Does the definition actually matter, couldn’t I choose any of them? “

  • Yes you could, but it’s better to choose as close as possible similar site definition as your custom web template. Meaning that if you create publishing web template, associate it to out of the box publishing site definition and similarly when you’re creating for example enhanced team sites. This is just due the fact that it will most likely help in your future upgrade to following SharePoint version.

“Provisioning providers can be as easily updated as web templates, why would I use web template model? If I create my site based on some out of the box site and then activate what ever is required in my own provider? “

  • Since provisioning provides will be completely based on custom code, they indeed can be easily upgraded, but this comes down on standardization of development and future considerations concerning deployment. When developers are moving between different companies and projects, it would be good that we would have standardized process for site provisioning. If you base your solution to provisioning provider, it’s custom code, which is not standard.
  • Other consideration is the deployments future. Web templates are also supported usually by hosting providers (like MS Online), but provisioning providers not. Even though requirement for cloud based solution is not in the objective of the first release, it doesn’t mean that it couldn’t be popping up in future.

“Somebody was discussing this concept called feature groups – which would be excellent way to just define what features would be activated when site is created. Onet.xml is so complicated, why can’t this be more simplified“

  • Who knows what the future brings (some do, but they are not telling… :-), but basically if you follow up the guidance of provisioning everything from features, not from onet.xml file, you actually have similar functionality. You only need to concentrate on what features will be activated and on which order. It’s not even close rocket science… especially since I got it…

“I heard that variations doesn’t work with web templates – is this true?”

  • Yes, this is really unfortunate limitation, but it only affects the variations and it’s actually quite understandable, since there’s no out of the box way to indicate that site was created using custom web template. Variation functionality is dependent on the site definition information available from the SPWeb level and it has no glue that the site has been created using alternative onet.xml file.
  • This does not however mean that you couldn’t do multilingual sites, since variation is only way to do this and quite often it’s not usable due differences between the hierarchies in language versions.

 

Summary

So, when should I be using web templates? – This is commonly asked question. Answer is actually extremely simple: Whenever possible. Web template provides highest flexibility for maintenance and easy upgradability support. It provides also easy way to to provide templates only in site collection level, not always throughout the farm, like with site definitions. They can be freely updated based on new technical and business requirements.

If for some reasons you still choose to use site definitions, you’ve already impacted enormously to the future of the particular deployment. What if in long run they’d like to move to use some cloud service? – if site definitions have been used, it’s impossible or you have to create separate migration project first to get the content from custom definitions to web templates. Those who’ve been involved since SP2003, can remember those jolly upgrade projects we had from 2003 to 2007.

Let’s try to avoid unnecessary complexity and consider the consequences of our decisions we make with custom architectures and customizations.

“The purpose of software engineering is to control complexity, not to create it.” – Dr. Pamela Zave


References and links

Here’s few good links concerning web template related information.

Note. I’ll be updating this blog entry based on all the questions and comments coming in (rather in blog post, than to email please)… and there’s few things which I didn’t have time to include to this post, which I’d love to get updated soon…