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.