Customizing SharePoint Site Creation

  • December 22, 2008
  • By David Mann
  • David
  • More Articles »

The SharePoint Object Model contains a wealth of classes that you can use to programmatically perform many SharePoint-specific tasks. In fact, the object model provides an equivalent way to accomplish just about anything you can do through the user interface—plus a few more things. Some of the object model's classes are common and you'll use them quite frequently in day-to-day SharePoint development; others are less well-known, and you'll typically use those only for very specific tasks that cannot be accomplished any other way.

The SPWebProvisioningProvider class is one of these very specific tools. You'll use it only in certain situations; however, it is often the only way to meet certain business needs.

This article covers how and why you would make use of the SPWebProvisioningProvider class—creating a custom site definition.

Author's Note: This article does not cover the process of creating and deploying a custom site definition in detail; it covers only the elements that are unique to customizing site provisioning. For more detailed information on creating a custom site definition, see Todd Baginski's blog posting.

The Site Provisioning Process

When creating a new site, you need to be able to answer the question: Exactly what is it that you want to accomplish? To answer that question, it's worth exploring what SharePoint does when you create a new site. At a very high level, the tasks are:

  1. Create the site.
  2. Create default lists, specified in ONET.xml.
  3. Associate and activate Features.
  4. Configure settings, specified in ONET.xml.

If you're creating the site through the user interface, the completed site will now be ready to be shown to users. This is the default process, and it consists almost entirely of creating new entries in various SharePoint database tables. If you don't need to do anything special or the order of operations is not important, this process works very well—after all, SharePoint is a product built so that non-technical end users can easily create multiple hierarchical sites.

But problems begin to occur when you need:

  1. To deviate from the standard process
  2. Increased control over the order in which things happen
  3. To inject new functionality into the process
  4. To implement logging or auditing of the process

For example, the out-of-the-box process will not meet your needs when you need to:

  • Record details of the request to create a new site—who requested the site, when they requested it, the name and URL of the site, etc.
  • Retrieve some information from an external LOB application to complete the provisioning process
  • Add custom web parts to a page on the site
  • Create a hierarchy of sub-sites below the requested site
  • Determine which template to apply to the new site based upon some criteria
  • Determine which lists, web parts, Features, etc. to include with the site based upon some criteria

These are just some possibilities where the default process will not meet your needs; your business requirements could dictate a multitude of others.

As you've likely guessed, customizing the site provisioning process is the answer to all of these problems, and others as well.

Getting Started—Creating the Class

At its core, customizing the site provisioning process is extremely simple; it requires only creating a class that inherits from the proper parent, and overriding one method. Here's the bare minimum code necessary to create a custom provisioner:

public class SiteDefProvisioner : 
   SPWebProvisioningProvider
{ 
  public override void Provision(
     SPWebProvisioningProperties props)
  {
    SPWeb site = (SPWeb)props.Web
    site.ApplyWebTemplate("MySiteDef#1"); 
  }
 }

Starting from the top, the important parts of the preceding code are:

  • Line 1: Inherit the new class from SPWebProvisioningProvider, which is part of the Microsoft.SharePoint namespace, located in Microsoft.SharePoint.dll.
  • Line 3: Override the Provision method and configure it to accept a parameter of type SPWebProvisioningProperties (more about this parameter shortly).
  • Line 5: get a reference to the site being created from the props parameter mentioned above. Microsoft currently provides no clear guidance about whether you need to dispose of this SPWeb object explicitly. While this instance will be flagged by, SPDisposeCheck, I don't dispose of it explicitly because my code did not create it. Future information may necessitate a change in this approach. For details on the dispose problem, see Roger Lamb's blog.)
  • Line 6: Call the SPWeb object's ApplyWebTemplate method, passing a string parameter containing the name of the template and site definition you want to apply to this new site. Note that this parameter takes the form of Site_Definition_Name#Configuration_Number (in other words, the name and configuration number separated by a pound sign). For details on site definition names and configuration numbers, see Todd Baginski's blog.

Naturally, you'll need to apply any customizations you need to this skeleton code. Typically, you'd simply add customization code directly to the overridden Provision method. Here's another example with additional custom logic:

public override void Provision(SPWebProvisioningProperties props)
{
  SPWeb site = (SPWeb)props.Web;
  site.ApplyWebTemplate("MySiteDef#1"); 
  SPFile homePage = site.GetFile("default.aspx");
  SPLimitedWebPartManager wpMgr = 
      homePage.GetLimitedWebPartManager(PersonalizationScope.Shared);
               
  if (site.Url.ToLower().Contains("marketing"))
  {
    PhotoShowWebPart wpPhotoShow = new PhotoShowWebPart();
    wpImg.PictureLibrary = "name_of_picture_library";
    wpMgr.AddWebPart(wpPhotoShow, "Right", 0);
  }
}

Like the first sample, this one, too, is pretty straightforward—it simply instantiates a new webpart (in this case, a fictitious custom webpart that presents photo slideshows) and adds it to the top of the right hand web part zone of the default.aspx page—but only when the new site is in the marketing area. While quite simple, the conditional check on the URL of the new site would make this example impossible to accomplish strictly within the ONET.XML of the site definition. Also, you can't rely on Feature stapling and a Feature Receiver because the provisioning and stapling process is non-deterministic with regard to firing order; the default.aspx page may not exist yet at the point the receiver event is fired.

TAGS:

SharePoint, Web development, application development, Visual C#
12


Networking Solutions





Partners