Feature stapling and site provisioning challenges

Feature stapling is an interesting concept in the SharePoint world, that allows you to associate a feature with any site definition. This feature will be activated automatically when a new site is created  from the associated site definition.

Feature stapling consists of two elements :

  • “Stapler” – the feature that specifies what features to be associated with site definitions

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<FeatureSiteTemplateAssociation Id="{Guid of the staplee feature}" TemplateName="SPSPERS#2" />
<FeatureSiteTemplateAssociation Id="{Guid of the another staplee feature}" TemplateName="SPSPERS#2" />
</Elements>

This example associates two features with the personal site definition in SharePoint 2013 ( in SharePoint 2010 the TemplateName would be SPSPERS#0 )

  • “Staplee” – the feature associated with a site definition or the feature that applies the customization

This feature can contain anything: a custom master page, list instances, custom pages, custom web parts etc.

The concept itself is fairly easy to use, but an important aspect in feature stapling is the order in which a site is provisioned [see reference about site provisioning order]

  1. global onet.xml
  2. Site-scoped features defined in onet.xml, in the order they are defined in the file.
  3. Site-scoped stapled features, activated asynchronously, on multiple threads
  4. Web-scoped features defined in onet.xml, in the order they are defined in the file.
  5. Web-scoped stapled features, activated asynchronously, on multiple threads
  6. List instances defined in onet.xml
  7. Modules defined in onet.xml

Because of this order of site provisioning, there are some scenarios which raise technical challenges:

  • Suppose your stapled feature depends on another stapled feature. Example – you would like to use publishing infrastructure on the site, and your staplee should be activated after the publishing infrastructure feature was activated.
  • The staplee uses list instances created in step 6.
  • The staplee creates sub-sites for this site definition.
  • The staplee modifies the home page – provisioned by a module in step 7

I have found different methods to deal with this:

1. Use a custom control that executes only once, and hence does all the changes after all the steps in site provisioning have been completed. The technique is explained in Steve Peschka’s blog post here. As a side-note on this, you don’t necessarily have to use a custom master page, you can always register a delegate control in the default master page. This works very well when you want to customize Personal Sites.

2. Wrap your changes in a Feature Event Receiver. You can decide not to execute the code right away (when the feature is activated), but to delay it until the site was provisioned (and all the steps are completed).


public override void FeatureActivated(SPFeatureReceiverProperties properties)
 {
 var web = properties.Feature.Parent as SPWeb;
ThreadPool.QueueUserWorkItem(ApplyYourChanges, web.Url);
 }

private void ApplyYourChanges(object state)
 {
 var webUrl = state as string;
 var uri = new Uri(webUrl);

// additional conditions here -- perhaps check if a feature was activated
 while (!SPSite.Exists(uri))
 {
 Thread.Sleep(5000);
 }
 using (var site = new SPSite(webUrl))
 {
 using (var web = site.OpenWeb())
 {

//make your changes here

}
 }
 }

I prefer the second method, as it is cleaner, and doesn’t require a control that makes changes the first time the site is accessed.

Additional References:

Feature Stapling

Site Provisioning Order

http://sharepointmagazine.net/articles/introduction-to-sharepoint-feature-stapling-part-2

Advertisements
7 comments
  1. A.Ragab said:

    This is awesome. Thank you.

  2. Excellent, you saved my life!!!. Many thanks

  3. I have a problem with this 🙂 with SharePoint 2013 and VS 2013
    When I create a site definition, it does not create any feature so where will I put the stapler?
    I tried in the onet.xml but it gave me errors.

    • Hi,
      You would need to put it in an elements file, in a web application scoped feature. After the feature is activated your feature stapler will be triggered.
      If you only want a custom site definition, i dont think you need feature stapling, as in onet.xml you can define all features that should be activated in your site…

  4. Hello! I’ve been reading your blog for a while now and finally got the courage to go ahead and give you a shout out from Lubbock Tx!
    Just wanted to mention keep up the fantastic
    work!

  5. Shona said:

    Howdy! Do you use Twitter? I’d like to follow you if that would
    be okay. I’m definitely enjoying your blog and
    look forward to new posts.

  6. Abel said:

    Nice post. I learn something new and challenging on websites I stumbleupon every day.
    It’s always exciting to read through content from other authors and use
    something from their websites.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: