Tuesday, April 5, 2011

All About List/Site Definition– Part III: Site Definition Provisioning

In the last two posts (Part I and Part II), I had described on creating list definition/instance and how to attach the list definition and list instance with site definition. In this post I would go a bit farther and describe on site provisioning.

If you have followed my last two posts on this topic and developed a site definition and then created a site with that site definition, you will find the new site has nothing but the custom lists you have defined in the site definition. But in most cases we want a custom site definition alike Team Site definition, lets say, and then we want few more custom lists added to the team site definition. So in a sense we want to extend or inherit the built-in Team Site definition. So the requirement is:

  • Requirement 1:we want our custom site definition just like Team Site Definition
  • Requirement 2: but we want few more custom lists/libraries added.

Let’s discuss how to meet the requirements.

Site Provisioning

In SharePoint, you can hook the site creation (known as site provisioning) event.

Step 1 - Create Custom Site Provision Provider: You need to create a class which will inherit from abstract class “Microsoft.SharePoint.SPWebProvisioningProvider” . Then override the method Provision. In this Provision method you need to apply the template you want to use for your custom site definition. For your information, if you use your own site provision provider, then site will be crated with blank template and in this Provision method you need to explicitly apply the site template as shown below:

public class MySiteProvisioner:SPWebProvisioningProvider
{
public override void Provision(SPWebProvisioningProperties props)
{
var web = props.Web;
//apply team site template.
web.ApplyWebTemplate(SPWebTemplate.WebTemplateSTS);
}
}
Code Snippet 1: Applying Web Template in Custom Site Provision Provider.

So basically in the above code snippet, I’m using Team Site Template whereas user selected the custom site template (developed by me). Few points to notice about Custom Site Provision Provider:

  • If you custom site provision provider then the site will be created with blank template
  • Since site will be created with blank template, you need to specify the template to use for site creation by using SPWeb.ApplyWebTemplate() in Proivision method of your custom Provision provider.
  • You can activate features in Provision method after applying web templates.

So in code snippet 1, I’ve applied team site template and it was my Reqirement 1. My second requirement was to create custom list/libraries on site creation. If you can remember from my second post on this series of article that I had developed two features: One for custom list definition and another for custom list instance. Since list definition feature is site collection scoped, we don’t need to activate this feature on site creation. Rather we need to activate the list creation feature on site creation so that the custom list gets created. Once list creation feature is activated in any site, the custom list associated with the feature will be created. So I’ve shown the modified version of code from Code Snippet1 to activate features:

public class MySiteProvisioner : SPWebProvisioningProvider
{
public override void Provision(SPWebProvisioningProperties props)
{
var web = props.Web;
//apply team site template.
web.ApplyWebTemplate(SPWebTemplate.WebTemplateSTS);

//activate list instance feature
string listInstaceFeatureId = "161c4ebd-97b7-4dff-9734-c930434d3e95";
web.Features.Add(new Guid(listInstaceFeatureId));
}
}

Code Snippet 2: Applying new web template and activate feature in Site Provision Provider

So the provision provider shown in code snippet 2 is ready to go. Now we need to associate this provision provider with our custom site definition.

Step 2 - Associate custom site provision provider with site definition: To associate the provision provider with site definition, open the webtemp_SiteDefinitionName file and add two properties ProvisionAssembly and ProvisionClass as shown below:

image

Figure 1: Specify the provision attributes in Site Template file.

As shown in the Figure 1, the ProvisionAssembly value is set to a Visual Studio token ($SharePoint.Project.AssemblyFullName$) which will be replace with Project namespace by Visual Studio. However if you are using non-SharePoint project template in Visual Studio then you can use the full namespace in ProvisionAssembly instead of the token. The ProvisionClass is the full name of the custom provision provider. The full xml is give below so that you can easily copy/paste.

<?xml version="1.0" encoding="utf-8"?>
<Templates xmlns:ows="Microsoft SharePoint">
<Template Name="BlogSite" ID="100000">
<Configuration ID="0" Title="BlogSite" Hidden="FALSE" ImageUrl="/_layouts/images/CPVW.gif"
ProvisionAssembly="$SharePoint.Project.AssemblyFullName$"
ProvisionClass="BlogTest.SharePoint.Provisioning.MySiteProvisioner"
Description="BlogSite" DisplayCategory="Blogs">
</Configuration>
</Template>
</Templates>

Code Snippet 3: Site Template xml file

Now you are done. You can now deploy the SharePoint solution and try to create a new site with the custom site definition. You can check if your custom provision provider is used by attaching the debugger with w3wp and setting a breakpoint in Provision method.

Conclusion

I’m not sure if this is the last post of this series but if I get interesting topics later, I’m hoping to write another post.

5 comments:

  1. Great Post! Thanks. Please do write such posts if you have some time.

    ReplyDelete
  2. Thanks for great article!

    I would like to have a subsite as the same way the list is created. I mean, a custom site definition and when it gets created, it also creates several subsites (that already have site definition as this one explained here).

    Let me try o make myself clear:

    1. I will have like 10 sites exactly this one (from this article). Team sites with custom list.
    2. I would like to have a site template (Wiki) and when it gets created it also creates 10 subsites using the number #1.

    Is that possible?

    Bruno

    ReplyDelete
  3. I think you can do it with web event receiver. When the web will be created, the event receiver will get fired and you can then apply your logic/code to create another sites/subsites.

    ReplyDelete
  4. Thanks for articles
    Greats posts

    Is it possible to deploy and activate a new custom list in a web site.
    I mean not in the creation of the web site, but after some months of use

    Thanks ´

    Miguel

    ReplyDelete
  5. @Miguel, yes it's possible. Create a new web level feature and then either use a feature receiver to create the list programmatically or Alternatively, you can create a list definition/instance in CAML in visual studio and then associate the definition/instance to a the feature. Then activating the feature in the web level, will create the list.

    ReplyDelete

Note: Only a member of this blog may post a comment.