The mystery that is SPWebProvisioningProvider

A little bit of background ( or a lot )

The SPWebProvisioningProvider lets you take control of the SPWeb (Web site) or SPSite (Site Collection) that your are provisioning. Instead of just using a Site Template and the changes that can be applied through a Site Template you can add your own custom code to the solution.

What you need to get started with this process:

  • WebTemp<Name>.XML - Your own customised WebTemp.xml file which will define the Site Templates that are available.
  • A Site Template folder containing all of the files required to apply the Site Definition (at least onet.xml and default.aspx)
  • Visual Studio 2005 to build the custom Provisioning Provider

To give you an example of what can be done you can take a look at the OOB Collaboration Portal that is shipped with MOSS 2007, we use the SPWebProvisioningProvider for the Portal templates. The Portal Templates contain all of the files listed previously - webtempsps.xml, a few site templates (SPS, SPSNHOME, SPSSITES, SRCHCEN, BDR, etc) and the visual studio code is already compiled into the Microsoft.SharePoint.Publishing dll.

If we look at webtempsps.xml this defines what templates will be shown to a user when they create a site or site collection. If you look through the xml file you will notice that there are only a few of the Templates that will be shown (Hidden = FALSE). We can then filter this down further:

Publishing Portal, Collaboration Portal and My Site Host will be shown only when creating a site collection as they have the attribute RootWebOnly = TRUE

Personalization Site, Publishing Site, Publishing Site with Workflow, and News Site will be shown only when creating subsites as they have the attribute SubWebOnly = TRUE

Site Directory, Report Center and Search Center with Tabs will be shown as options when creating Site Collections or subsites as they do not define either attribute (RootWebOnly or SubWebOnly).

The usual practice when building your webtemp file is that the Template Name attribute matches the folder name of one of the site templates. You will notice that for the Collaboration Portal (SPSPortal) and Publishing Portal (BLANKINTERNETCONTAINER) neither of these folders exist in the web server extensions\12\template\sitetemplates, there is a good reason for this which I'll mention at the end. The two templates are provisioned via the SPWebProvisioningProvider and you can see this in webtemp via the configuration attributes ProvisionAssembly, ProvisionClass and ProvisionData.

ProvisionAssembly tells SharePoint which assembly to load and which class to start in. This class needs to inherit from SPWebProvisioningProvider and override the Provision function.

Putting it together

After such a long description I thought it would be a good idea to put a small sample together so that you can walk through this and see first hand how this works. The sample will create a team site template that you can use for a new site collection with Auditing enabled.

1. Build a .Net C# Class Library (EnableAudit.dll) and add the following code

// SharePoint Specific Assemblies
using Microsoft.SharePoint;
using Microsoft.Office.Server.Diagnostics;

namespace EnableAudit
{
    public class AuditProvisioningProvider : SPWebProvisioningProvider
    {
        // <summary>
        // Gets called when a web is provisioning when the template
        // chosen has ProvisionAssembly and ProvionClass attributes
        // specified
        // </summary>

1.
        public override void Provision(SPWebProvisioningProperties props)
        {
                // Apply the hidden Site Definition to the Web Site
                SPWeb web = props.Web;
                web.ApplyWebTemplate("AuditTeam");

  1.                 // Update Audit Settings for the Site Collection
                    SPSite site = web.Site;
                    SPAudit audit = site.Audit;
                    audit.AuditFlags = SPAuditMaskType.All;
                    audit.Update()
            }

  2.       }
        }

    Note: The props object will give you access to the SPWeb that you are creating as well as a data file which is the ProvisionData file that you can specify in the webtemp file.

2. Install your custom assembly to the GAC

3. Create a custom WebTempAudit.xml.

Paste the following code into notepad and save this as web server extensions\12\template\1033\xml\WebTempAudit.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- _lcid="1033" _version="12.0.4518" _dal="1" -->
<!-- _LocalBinding -->
<Templates xmlns:ows="Microsoft SharePoint">
<Template Name="Audit" ID="10001">
    <Configuration ID="0" Title="Audit Team Site" Hidden="FALSE"
          ImageUrl="/_layouts/images/stsprev.png"
          Description="A site for teams to quickly organize, author, and share information. It provides a document library, and lists for managing announcements, calendar items, tasks, and discussions." DisplayCategory="Collaboration"
          ProvisionAssembly="EnableAudit, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=<PublicKeyToken of DLL>"
          ProvisionClass="EnableAudit.AuditProvisioningProvider"
          ProvisionData="">   
    </Configuration>
</Template>
<Template Name="AuditTeam" ID="10002">
    <Configuration ID="0" Title="Hidden Audit Team Site" Hidden="TRUE" ImageUrl="../images/stsprev.png" Description="This template is applied through the ProvisioningProvider.">   </Configuration>
</Template>   
</Templates>

4. Create a custom Site Template

a. Open the web server extensions\12\template\sitetemplates folder
b. Take a copy of the sts folder and call it AuditTeam
c. Open the AuditTeam folder
d. Remove the defaultdws.aspx page (We will be removing the reference to this in the onet.xml file)
e. Open the xml file and then open onet.xml in Notepad
f. Find the section titled <Configurations>
g. Remove all of the Configuration attributes except for ID=0
h. Find the section <Module Name="DWS"... </Module> and remove this section
i. Find the <SiteFeatures> section and add the Audit Reporting Feature
<Feature ID="7094BD89-2CFE-490a-8C7E-FBACE37B4A34" />

Your <SiteFeatures> should now look like this:

<SiteFeatures>
        <!-- BasicWebParts Feature -->
        <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
        <!-- Three-state Workflow Feature -->
        <Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
        <!-- Audit Reporting Feature -->
        <Feature ID="7094BD89-2CFE-490a-8C7E-FBACE37B4A34" />
</SiteFeatures>

j. Save the onet.xml changes

5. Run IISReset

6. Create a new site collection based off the Audit Team template and check the Audit settings for the Site Collection.

Note: As a best practice you should build this project as a package that can be deployed across the farm, the above steps will only work on a single server environment.

How this works

1. The site creation process will go to the webtemp file and find the template you have selected to apply
2. It will then look for the directory in SiteTemplates that matches the Template Name and apply that Template. (if you followed the steps then it shouldn't find a match)
3. It will then know to launch your DLL since you have the provision attributes set.
4. Your DLL will then apply the template, which is the same process as step 2 above, and do the additional actions required. (In this example, update the auditing settings)

What to look out for

If the Template Name attribute matches your Site Template, the one you are applying in your ProvisionClass, then you will end up in a loop where SharePoint will start to Apply the webtemplate and will find the configuration attributes ProvisionAssembly, ProvisionClass and ProvisionData so it will launch into your custom provisioningprovider again.

Share this post :