The site definition vs. web template vs custom code discussion is a very old and ever returning discussions. There are at least four different approaches:
- Creating full blown custom site definitions
- Creating custom empty or blank site definitions and provisioning those with (stapled) features and code
- Creating site templates
- Using custom code
I think it is safe to say that the first option is a bit out of date. Creating full blown site definitions requires writing a lot of tedious XML in the onet.xml and schema.xml files. Microsoft has advised against this approach for some time now and that message has gotten a lot stronger with SharePoint 2010 and the new WebTemplate feature.
The second option is still a valid option. This option means you strip a site definition to its bear minimum. All list instances, modules and web parts will be removed from the onet.xml to make the onet.xml as small and readable as possible. The functionality can be added to the empty site by using features in the site definition, stapled features or code in a feature receiver. The best options are the stapled features and the code in the feature receiver. A combination of the two can also be a good solution.
When choosing between defining a feature in the onet.xml and stapling a feature to a site definition you might want to consider the provisioning order of a site definition:
- Create the url for the site
- Provision the GLOBAL onet.xml
- When creating a new site collection - Activate site collection (SPSite) scoped features that are defined in the onet.xml, when creating a new sub site – verifying that all site collection scoped features are activated
- Activate site collection scoped stapled features in random order
- Activate sub site (SPWeb) scoped features that are defined in the onet.xml
- Activate sub site scoped stapled features in random order
- Create list instances defined in onet.xml
- Create modules defined in onet.xml
The third option is using site templates. In SharePoint 2007 site templates could only be created by using the “save site as template” option from user interface of the site settings menu. Saving a site as a template would create a .stp file, which was called a site template. In SharePoint 2010 we can still save sites as templates, but now it will create a .wsp file. Yep, that’s right, saving a site as a template creates a real SharePoint solution. The generated .wsp solution can be imported into Visual Studio 2010 and edited from there, but unfortunately the imported solution will contain all content types, site columns and properties that were available within the site, even if they weren’t actually used. This creates a lot of clutter and a pretty unmanageable solution. The novelty that makes saving a site as a .wsp solution possible is the WebTemplate feature element.
The WebTemplate feature element can also be used to create your own web templates, without saving a site as a template. Just like site definitions, site templates in SharePoint 2010 require an onet.xml file. However, instead of the webtemp.xml file you will use a feature with the WebTemplate element. In the WebTemplate element you will define a BaseTemplateName, a BaseTemplateID and a BaseConfigurationID. In the example below the BaseTemplateName is STS, the BaseTemplateID is 1 and the BaseConfigurationID is 0. Die-hard SharePointeers will recognize the template name and configuration id and know that the basis for the site template we’re creating is the Team Site. The name and title of this site template will be My Fancy Web Template, so this is what will be displayed as the title of the template when you’re creating a new site. The category where you can find the site template in is Fancy Sites. A lot of the other properties can be left out if you’re creating your own site template, I just wanted to list them all in here for your reference.
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<WebTemplate
AdjustHijriDays="0"
AlternateCssUrl =""
AlternateHeader =""
BaseConfigurationID ="0"
BaseTemplateID ="1"
BaseTemplateName ="STS"
CalendarType ="1"
Collation="25"
ContainsDefaultLists ="TRUE"
CustomizedCssFiles=""
CustomJSUrl=""
Description="Site with a lot of fancy features."
DisplayCategory="Fancy Sites"
ExcludeFromOfflineClient="FALSE"
ImageUrl=""
Locale="1033"
Name="My Fancy Web Template"
ParserEnabled="TRUE"
PortalName=""
PortalUrl=""
PresenceEnabled="TRUE"
ProductVersion=""
QuickLaunchEnabled="TRUE"
Subweb="TRUE"
SyndicationEnabled="TRUE"
Time24="TRUE"
TimeZone="272"
Title="My Fancy Web Template"
TreeViewEnabled="FALSE"
UIVersionConfigurationEnabled="FALSE" >
</WebTemplate>
</Elements>
A web template feature can be site or farm scoped. If it is site scoped it can be deployed as a sandboxed solution. This way you can easily create sub sites based on the site template. If a site collection has to be based on the site template and you still want to deploy the site template as a sandboxed solution you can use the following steps:
- You can first create the site collection without a template by selecting Select template later in the Custom template category
- After creating the site, browsing to the site will redirect you to the template selection page
- At the bottom of the settings page a link to the Solution Gallery is displayed
- Click on the link and upload the sandboxed solution containing the site template
- Activate the solution
- The site template can now be selected and the site creation will be finished
You can also create a site based on a web template by using custom code. You simply use [Feature Guid]#[Web Template Name]. Spaces in the web template name are no problem.
The good thing about web templates is that they are based on one of the standard SharePoint site definitions and that they are stored in the database. This means that they will be easier to upgrade then a site definition would probably be. Another advantage of site templates is that they can be deployed as sandboxed solutions. These should be your main drivers for using site templates.
There are a couple of things that you can use in site definitions that aren’t available in site templates.
- Module elements
* This means you can’t provision aspx pages by using the modules element in the onet.xml. Instead you can use features and feature receivers to provision your aspx pages and place web parts on them. This is a best practice anyway. Using features for you modules gives you more flexibility and also enables you to control the provisioning better. It will for instance enable you to make sure that adding the default.aspx page to the site isn’t the last step in the site creation process. Since using features is a great alternate approach for the modules in the site definition not being able to use modules in site templates is not a big deal.
- Components elements. The components element can contain two child elements that are both optional and cannot appear more than once. Both elements are rarely used, so not being able to use them in site templates won’t be a problem for most people.
* FileDialogPostProcessor – this is a class that is used to modify the file open and save dialogs on a document library. If you save a file directly from Office to a document library you will get a web interface and in the FileDialogPostProcessor you can declare a class that modifies that interface.
* 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
* This element can be used to define a footer section for email sent from the server. This element is also rarely used, so not being able to use it won’t be a big disturbance.
- Stapled features
* Now this one is a bit nasty. When creating site definitions the advice is to use stapled features for adding features and functionality to sites that are created based on the site definition. The nice thing about this is that you don’t have to add the features to the onet.xml, you can simply create a stapling feature and link the site definition and the features in there. You can’t do this in site templates. I really hope this will be made possible later on, but for now we will have to add the features directly to the onet.xml of the site template.
Because of these limitations the provisioning order of a site template will be:
- Create the url for the site
- Provision the GLOBAL onet.xml
- When creating a new site collection - Activate site collection (SPSite) scoped features that are defined in the onet.xml, when creating a new sub site – verifying that all site collection scoped features are activated
- Activate sub site (SPWeb) scoped features that are defined in the onet.xml
- Create list instances defined in onet.xml
The fourth option is to not create any custom site definitions and site templates and provision the whole site by using code. The nice thing about this is that it means not having to write any XML. Of course it does mean that you have to write a lot of custom code. You also need a way to trigger the code that will provision your site. This can be done in a feature receiver of a feature that is for instance added to the blank site definition (keep in mind that you can’t staple to the out of the box site definition). You can also create a custom site creation page that users will use to create their sites and that will fire of your code.
The all custom code approach is often used when sites are created by an automated process like a workflow, or for instance by a trigger from an external application. At Macaw we see a lot of use cases where the site creation process is triggered by a button or a change in Microsoft CRM.
Conclusion
Creating full blown site definitions and writing a lot of XML for the onet.xml file is not the best option. One of the reasons for this is of course that writing a lot XML is no fun, difficult to debug and very error prone. Another, perhaps even better reason, is that site definitions like this will almost certainly give you a headache when you want to upgrade to the next SharePoint version. Microsoft has been warning people for a while that eventually they will stop supporting site definitions. And it definitely looks like with the WebTemplate feature, they made the first step in that direction.
Using minimal site definitions with features and feature receivers is still an option that can be used. A reason for choosing this approach over the site templates approach could be if you need to use a lot of stapled features.
With the new WebTemplate feature in SharePoint 2010, the use of site templates will dramatically increase. If you are not bothered too much by the limitations of the site template this is a better bet than using site definitions. Mainly because it will make a future upgrade easier. The fact that you can deploy a site template as a sandboxed solution and thus only make a template available within a certain site collection can also be a benefit.
The custom code solution is also a valid approach. I would personally mainly use this when sites are created using automated processes. Of course approach two and three can also use custom code in feature receivers to add functionality to a site. A good reason to use this would be if you need to create list instances and add content types to them. I feel it is way easier to do this in code than to write that out using XML.
So..still not a clear and definitive answer, but I hope I was able to clarify the considerations for the different options in this post.
[Update] Microsoft Architect Vesa Juvonen also wrote a great blog post on site definitions and web templates I would advise you to read his post carefully..