Feature Stapling in WSS V3


Background:


New to the WSSv3 Platform is a concept called Features.  These enable you to package chunks of functionality and allow this functionality to be turned on or off in a WSSv3 based site.  This could be things like:


          List templates


          List instances


          Menu Items


          Workflows


          Web Parts


         


I am not going to go into these in a lot of detail here, but if you want to read more about them then you can here:


http://msdn2.microsoft.com/en-us/library/ms460318.aspx


One of the big problems people faced in WSS (V2) was that we did not support you making changes to the out of the box site definitions.  One of the big reasons for this was that we might need to update that site definition in a Service Pack and overwrite your changes.


This meant that you need to take a copy of our out of the box site definitions and then hide the originals from the user … and then make all the changes you like.  This would ensure we would not break the site definition in a Service Pack for example.


I guess I like to refer this to who “owns” a site definition.  Microsoft “own” the out of the box site definitions and you “own” any that you create and add to the product.  That way in a service pack we will only update the site definitions that we ship with the product and not step on any site definitions you might have added.


So!  What am I attempting to get to 🙂 


We built Features so that you can turn functionality on and off in a site after it was create … even if it was not in the original site definition.


So what happens if you want to associate a Feature with a site definition?


Well, as you should know by now, it is not advisable to modify the out of the box site definitions.  So how do you do this?


This is where Feature Stapling comes in…


Solution == Feature Stapling


Feature Stapling allows you to “staple” a Feature to a site definition without modifying it in any way.  This means you can add your feature to all sites created using that site definition.


E.g.  You want to add your WidgetFeatureXYZ to the out of the box Team Site definition.  Simple … use a Feature Staple!


So how do you do this?


How-To:


To create a staple you actually create another Feature that does the staple.  Below is an excerpt from a staple feature we use in the product to staple a Multilanguage feature to the STS, BDR & SPS site definitions.


Feature.xml file:


<?xml version=”1.0″ encoding=”utf-8″ ?>
<Feature  Id=”82E2EA42-39E2-4B27-8631-ED54C1CFC491″
          Title=”$Resources:MultiLangStaplingFeatureName”
          Description=”$Resources:MultiLangstaplingFeatureDescription”
          Version=”12.0.0.0″
          Scope=”Farm”
          xmlns=”http://schemas.microsoft.com/sharepoint/
          DefaultResourceFile=”_Res”>
    <ElementManifests>
        <ElementManifest Location=”TransMgmtFunc.xml”/>
    </ElementManifests>
</Feature>


TransMgmtFunc.xml file that contains the FeatureSiteTemplateAssociation element:


<Elements xmlns=”http://schemas.microsoft.com/sharepoint/“>
 <FeatureSiteTemplateAssociation Id=”29D85C25-170C-4df9-A641-12DB0B9D4130″ TemplateName=”STS#0″ />
 <FeatureSiteTemplateAssociation Id=”29D85C25-170C-4df9-A641-12DB0B9D4130″ TemplateName=”STS#1″ />
 <FeatureSiteTemplateAssociation Id=”29D85C25-170C-4df9-A641-12DB0B9D4130″ TemplateName=”BDR#0″ />


 <FeatureSiteTemplateAssociation Id=”29D85C25-170C-4df9-A641-12DB0B9D4130″ TemplateName=”SPS#0″ />
</Elements>



In the above example it “staples” the Feature with the ID “29D85C25-170C-4df9-A641-12DB0B9D4130” to the STS#0, STS#1, BDR#0 & SPS#0 site definitions.


This is very powerful as it allows you to add functionality to site definitions without having to modify the site definitions themselves.


Now … one last final note on this, if you want to staple your Feature to ALL site definitions then you can staple it to the GLOBAL site definition and it will be added to all sites that are created.


Pretty cool huh!


TIP: ADDED BONUS FOR THOSE WHO HAVE READ THIS FAR:


Replacing ExecuteURL:


You can use Feature stapling to effectively replace your use of the ExecuteURL property in a site definition.


Scenario:  You want to run some custom code whenever a site is created. (a typical use of the ExecuteURL property in V2)


Solution:  Build a Feature that has an Event Receiver defined on it; & have it catch the Feature activation event.  Run your custom code in there.  Then, use a Feature Staple to staple your Feature to the site definition e.g. FOO#0 (or whatever one you want to run your code for).


Bingo!  You can now run your custom code whenever a site is created 🙂


Hope this helps…


-Chris.

Comments (38)

  1. TomC says:

    Chris,

    If I feature staple my CustomDocLib to the standard team site, how do I get my custom document templates (*.dgn) that is defined in our CustomDocLib schema.xml to appear? Is this what the 12TemplateDocumentTemplates directory is for?  My CustomDocLib works fine on my CustomSiteDef, which includes the DocumentTemplate files.  

    TIA.

    Tom.

  2. You’ve been kicked (a good thing) – Trackback from SharePointKicks.com

  3. Peter Tobiasen says:

    Very nice feature 🙂

    Question though… When I read your post I understood that the feature you are stapling to a site definetion will be activated on both already created sites and new sites.

    I guess this is wrong and it only works on new sites created after the stapling because I can’t get it to work 😉

    Can you please clearify on this?

    -Peter

  4. By combining a few blog entries I just read – Arpan’s ROI post which talks about ROI/Chargeback and Chris

  5. Continuing from last month’s list of recommended reading, here’s my short list of favorite blog entries

  6. Sharepoint 2007 Features Stapling

  7. Adam says:

    Hi, thanks for a great article!

    I’ve tried feature stapling to GLOBAL (and GLOBAL#0) but my feature is not activated automatically on new site creation….do I need to do anything extra to make the feature active automatically? The feature works when manually activated and has scope=Web (it is an event handler so cannot be scope=Site).

    Thank you,

    Adam

  8. Adam says:

    How do I staple to GLOBAL? It doesn’t work on my install (B2TR) but does work for specific site definitions. Would you be able to provide an example of this please? Thanks for all this info!

  9. Этот пост содержит ссылки на важные материалы, c помощью которых можно качественно повысить уровень знаний

  10. DTC says:

    Thank you very much,do your last statements mean when a site is created it will invoke the "feature activation event"??

  11. Paul says:

    Is it possible to Activate a feature via feature stapling?

  12. mmascolino says:

    I’d like to report that GLOBAL is working in RTM…thanks this is very useful.  BTW, the MSDN article on this refers to it as GLOBAL#0 which is wrong obviously.

  13. MM says:

    How do you customize new sites using Feature stapling?

    I mean I need to delete Out-Of-The-Box webparts and add custom webparts to new sites using feature stapling.

    I have 2 features: One feature staples the second feature to the STS#0 template and the second feature has the code to addremove webparts programmatically and its code looks like

    SPWeb web = (SPWeb)properties.Feature.Parent;

    SPLimitedWebPartManager manager = web.GetLimitedWebPartManager("default.aspx",  System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

    SPLimitedWebPartCollection coll = manager.WebParts;

    But the problem is I can’t get SPLimitedWebPartManager object since I get error during debugging saying that the new site doesn’t exist. This means that I can’t addremove webpartslists from new site. Is this because FeatureActivated event is fired before the site gets created???

    Any workaround for this? Or how do I addremove webpartslists from new site during creation using feature stapling??

    Thanks for reading.

  14. Musa says:

    Can you addremove webparts from a new site inside the FeatureActivated event handler?

    I am getting error while trying to access the SPLimitedWebPartManager object. It says the new site doesn’t exist since it is not yet provisioned.

    Is there any work around for this?

    Thanks

    Musa

  15. Purpose: Apply a Sharepoint Theme to any provisioned webs based off any Site Definition…

  16. Hi, this is Steve Peschka from the SharePoint Rangers team again, and in this blog entry I’ll discuss

  17. Rob Edwards says:

    Do you know if you can pass a parameter to a feature?  For example, can i staple to all SPS sites and also set the <Properties> values of the feature being called or do i need to create a "new" feature for each property change i want?

    Thanks,

    Rob

  18. craig says:

    I’m stuck trying to figure out how to use a feture that will allow me to disable the wiki and blok create withing the "mysite".  These guys want blogs and wiki’s at the top level sites…..portal…but not withing the mysites.   Anysuggestions

  19. craig says:

    I’m stuck trying to figure out how to use a feture that will allow me to disable the wiki and blok create withing the "mysite".  These guys want blogs and wiki’s at the top level sites…..portal…but not withing the mysites.   Anysuggestions

  20. Feature Stapling allows you to “staple” a Feature to a site definition without modifying it in any way. This means you can add your feature to all sites created using that site definition. E.g. You want to add your WidgetFeatureXYZ to the out of

  21. Feature Stapling allows you to “staple” a Feature to a site definition without modifying it in any way. This means you can add your feature to all sites created using that site definition. E.g. You want to add your WidgetFeatureXYZ to the out of

  22. David says:

    Hi,

    I have the same problem as Adam – has anyone found a resolution?

    I’ve tried feature stapling to GLOBAL (and GLOBAL#0) but my feature is not activated automatically on new site creation.  The feature works when manually activated and has scope=Site.  I’ve also tried other template types such as STS#0, MPS#0 and BDR#0

    Thank you,

    David

  23. 2007 MOSS Resource Links (Microsoft Office SharePoint Server) Here is an assortment of various 2007 Microsoft

  24. Clint says:

    I have seen several questions, posted in various newsgroups and forums, regarding activating features

  25. Petit message à tous mes lecteurs développeurs SharePoint Je répete encore et encore que 90 % du temps,

  26. Steve says:

    I have the same issue as David & Adam…

    I’ve created a feature scoped at the site collection level (i.e. scope="site" within feature.xml), and have used feature stapling to attach it to GLOBAL site definition – so that it appears as a feature, on every site collection created.

    My only issue is that I would like this feature to be programmatically activated for every site collection.

    Any advice on how I could go about achieving this would be greatly received.

  27. For The User says:

    Hopefully it isn&#39;t any sort of a great revelation to anyone that the latest versions of SharePoint

  28. This is a repost of an article i upped on my blog back in Feb 2007 Purpose: Apply a Sharepoint Theme

  29. JDP says:

    Reading things like this reinforces my experience that sharepoint’s a complete trainwreck of mismanaged features (in a traditional sense, not in Sharepoint speak) rife with neologistic descriptions without context or meaning.

  30. chjohn says:

    Hi JDP,

    I agree that "Feature"  could have been called something less confusing 🙂  but not that it is a trainwreck of mismanaged features.  

    Sure it is more complex to develop for than a regular ASP.Net application, but we are working hard on making that a better experience. The very start of that is the Visual Studio extensions for WSS.

    -Chris.

  31. Is it possible to present a custom page somehow to a user after a site template provisioning? For example a configuration page?

  32. yesh says:

    I have the same issue as David, Adam and Steve…

    I’ve created a feature scoped at the WEb level (i.e. scope="web" within feature.xml), and have used feature stapling to attach it to GLOBAL site definition – so that it appears as a feature, on every site created.

    My only issue is that I would like this feature to be programmatically activated for every site created.

    It would be really great if you can help me regarding this.

  33. Jaymeson says:

    When the feature is scope "Web", if I put the feature xml in the Onet.xml of the site template.  It says it’s activated, although it really isn’t.  Sux.  I have to deactivate it and then activate it again to have it really take hold.  I even set a bunch of Dependencies in the feature.xml and this didn’t work either.  Same thing.  Hopefully yesh can try this approach and see if he gets any different results.

  34. Johnny Dogbert says:

    I am using FeatureSiteTemplateAssociation to activate the "publishing" feature, and also a custom feature.

    The problem is, that when my custom feature featurereceiver code is called, the site is still not considered a publishing site at that point (despite the fact that the publishing feature is specified as a feature dependency!)

    The (awful) solution seems to be to add the following code to my featurereceiver:

    bool pubWeb = false;

    while (!pubWeb)

    {

     if (PublishingWeb.IsPublishingWeb(web)) pubWeb = true;

    }

    // this will only evaluate to true because of

    // the above loop

    if (PublishingWeb.IsPublishingWeb(web))

    {

    }

  35. The FeatureSiteTemplateAssociation element is used to implement what is commonly referred to as "Feature Stapling". This allows you to automatically turn on features for spoecific site definitions without needing to modifiy the definition itself….

  36. Question Regarding Feature Stapling says:

    Hi Chris,

    I have a feature of scope web. This feature is having ItemEventRecievers defined in it. Using Feature stapling I tried to append this feature with the site definition. However, When a new site is created I get an error saying that it cannot associate ItemLevelEventreceiver with Featurereceiver.

    To put it other way:

    Web Level Feature : consists of elements.xml file which consists of Item handling events.

    Farm level feature : Consists of elements.xml file with featuresitetemplateassociationId of web feature.

    Now, the question is how to build a feature that has an Event Receiver attached to it and associate this in feature stapling?

  37. One of the most common and simple ways to customise SharePoint is to directly modify the files that are

  38. Yair says:

    Dear Chris,

    As for your example, I need to have 2 features?

    82E2EA42-39E2-4B27-8631-ED54C1CFC491

    AND

    29D85C25-170C-4df9-A641-12DB0B9D4130?

    Thank you,

    Yair