Introduction to SharePoint Feature Stapling – Part 1

Features allow you to add new functionality to SharePoint or make simple site customizations in an easy and consistent way. Features can be scoped to the Farm, Web Application, Site, and Web level depending on the purpose of the feature. The basis of a feature is implemented using a feature.xml file, but may also contain other supporting files. More information on Features can be found on the Microsoft MSDN site at http://msdn.microsoft.com/en-us/library/ms460318.aspx.

The focus of this article is going to be on a concept called Feature Stapling. Most, if not all, SharePoint developers know that Microsoft frowns on modifications to the “Microsoft” owned files that support SharePoint. If you modify these files you run the risk of your changes being broken with the installation of a service pack or hot fix. Sometimes this was your only option when attempting to customize SharePoint back in the WSS 2.0 days. The following KB article that outlines the supported / unsupported scenarios when it comes to modifying the default site definition files (http://support.microsoft.com/kb/898631).

Feature Stapling allows you to create a feature and then associate it with any site definition without ever touching the site definition files themselves. Your feature will be executed when the site is being provisioned.

As you read this series of articles I hope to explain how Feature Stapling works through the creation of a working feature and feature stapling example. I will also touch on some important points and considerations you need to be aware of about when in the life cycle of a site being provisioned your feature will be executed.

Feature Stapling

Feature Stapling is achieved through the creation of another feature that defines the association of your regular Feature and the site definition you want to “staple” it too. In other words, you need to create two Features to achieve a complete Feature Stapling implementation.

Creating Feature

There are many different recommendations on how to go about creating SharePoint Features within Visual Studio from the layout to the deployment. In this article, I am going to use the method that works best for me. I use Visual Studio 2008, a class library, and WSP Builder (http://www.codeplex.com/wspbuilder). WSP Builder is what I ultimately use to generate my solution file; however, it does have some features such as Copy to 12 Hive, and Recycle Application Pools that I used while creating my Feature.

In this scenario, I want to capture the Title and URL of any site that was created using the Team Site template in a central location.

Step 1: Create the 12 hive folder structure down to my actual Feature, created a strong named key, and added a reference to the Microsoft.SharePoint.dll assembly.

The following is a screen capture of my project in Visual Studio:

VisualStudioSolutionView
Step 2: Add a new class file in the root of the project folder called SampleFeatureReceiver.cs and use the following code:

using System;
using Microsoft.SharePoint;
 
namespace Liebrand.Sample
{
    public class SampleFeatureReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            using (SPWeb web = (SPWeb)properties.Feature.Parent)
            {
                if (web.IsRootWeb)
                    return;
 
                using (SPSite site = web.Site)
                {
                    using (SPWeb rootWeb = site.RootWeb)
                    {
                        SPList createdSites = GetProvisionedSitesListId(rootWeb);
                        SPListItem newItem = createdSites.Items.Add();
 
                        newItem["Title"] = web.Title;
                        newItem["Url"] = web.Url;
                        newItem.Update();
                    }
                }
             }
        }
 
        private SPList GetProvisionedSitesListId(SPWeb rootWeb)
        {
            try
            {
                SPList list = rootWeb.Lists["Provisioned Sites"];
                return list;
            }
            catch (ArgumentException)
            {
                Guid listId = rootWeb.Lists.Add("Provisioned Sites",
                    "This list contains all the sites that have been provisioned.",
                    SPListTemplateType.GenericList);
 
                SPList list = rootWeb.Lists[listId];
 
                list.Fields.Add("Url", SPFieldType.URL, false);
                SPField field = list.Fields["Url"];
 
                SPView view = list.DefaultView;
                view.ViewFields.Add(field);
                view.Update();
 
                list.Update();
 
                return list;
            }
        }
 
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
        }
 
        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
        }
 
        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
        }
    }
}

This code basically adds the URL of the site being provision to a listed called Provisioned Sites that is located in the root site. If the list is not found, the list is created.

Step 3: Add a new XML file called feature.xml to the feature folder and paste the following contents:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Id="2B3451F0-BC93-41A4-9FAD-3A81861D651A"
         Title="Liebrand Feature Sample"
         Description="This is a feature that will be used to demonstrate feature stapling."
         Scope="Web"
         Hidden="False"
         Version="1.0.0.0"
         ReceiverAssembly="Liebrand.Sample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=057a20dd10f3b267"
         ReceiverClass="Liebrand.Sample.SampleFeatureReceiver">
</Feature>
Note: The Id attribute value was generated using the Create GUID menu item from the Tools menu in Visual Studio.

Creating the Stapling Feature feature

At this point, our primary Feature is ready to go. The last step is to simply create another Feature that will associate my LiebrandSample Feature with the Team Site site definition.

Step 1: Add another folder under the FEATURES folder called LiebrandSampleStapler and add a file called feature.xml then paste the following contents into it:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Id="C384D136-79A8-48BD-AF73-C630547F4D8E"
         Title="Liebrand Sample Stapler"
         Description="This feature staples the LiebrandSample feature to the Team Site site definition."
         Scope="Farm"
         Hidden="False"
         Version="1.0.0.0">

  <ElementManifests>
    <ElementManifest Location="elements.xml" />
  </ElementManifests>

</Feature>

Step 2: Add a XML file called elements.xml to the LiebrandSampleStapler folder and paste the following:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <FeatureSiteTemplateAssociation Id="2B3451F0-BC93-41A4-9FAD-3A81861D651A"
                                  TemplateName="STS#0"/>
</Elements>

The ID attribute in the FeatureSiteTemplateAssociation element should match the ID of the Feature we created at the beginning of this article. The TemplateName attribute should match the site definition name and configuration ID found in the webtemp.xml file located in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML. Since we want to associate our new Feature to all Team Site sites we specify STS#0. STS is the name of the Template and 0 is the configuration ID for the Team Site.

At this point we are ready to deploy our new features and test it out.

Deployment

First build your project to insure you have no build errors and to generate the assembly Liebrand.Sample.dll.

To deploy these new Features using WSP Builder simply,

  • Right-click on the project name and select WSPBuilder, then click Copy to GAC. This will copy the assembly into the Global Assembly Cache.
  • Right-click on the project name and select WSPBuilder, then click Copy to 12 hive. This will copy the 12 hive folder structure in your project to the SharePoint 12 hive folder

WSPBuilderMenu

  • Install and activate the Features by running the following commands:

stsadm -o installfeature -name LiebrandSample

stsadm -o installfeature -name LiebrandSampleStapler

Test

At this point you can create a new sub-site using the Team Site template and you should see a new list called Provisioned Sites get created at the root site with a new entry added that will point back to the site you created.

After creating 3 team sites, this is what the Provisioned Sites list looked like:

ProvisionSitesListing

Summary

Features Stapling offers a great way for developers to extend, change, or customize the out-of-the-box site definitions without ever touching them. Hopefully this article gives you an idea of where you can utilize Feature Stapling. In the next article of this series, I am going to cover when Feature Stapling occurs in the creation of a site and some key points you need to be aware of when it comes to what elements are available to you when your feature is executed.

Twitter Digg Delicious Stumbleupon Technorati Facebook Email
  • Vinay
    Hi Paul,

    This is Vinay. I have looked at the post and it was very useful for me.
    But could you please tell me how is the feature being stapled getting activaed in the new site that is created.
    I have followed the steps above but I could see the sites created only when the feature is activated manually in the new site created. Please advise
  • anujahnavi
    Hi Vinay,
    Are you able to solve the problem. I am also facin ghte same thing. What else i have to do to activate teh feature automatically when a new team site is created. What am i doing wrong. I ahve done the same process what is mentioned inthis article. Did you achive this at any case?

    Please help me. give me a idea what could be go wrong.
    Thanks in advance.

    Regards,
    Anu
  • Vinay,

    If the feature has been stapled correctly, it should activate when the site has been created and not require manual activation. It seems that something is not stapled correctly. What site template are you selecting when you are creating a new site?

    Thanks,

    Paul
  • Sunil
    Hi Paul,
    Nice article!
    I would like to know how to use feature stapling to change the welcome page of the subsite to one of the custome page and create few fresh pages using predefied custome page layouts from the root site.

    Can u please elobrate and provide one example for doing the same.
  • In the receiver, none of web, site or rootWeb should be disposed (wrapped in using).
  • Thank you for the feedback. I'll be working with SharePoint Magazine to get the code examples updated to appropriate reflect this.
  • anujahnavi
    Hi Paul,
    I am unable to activate the feature automatically when a new team site is created. Where could be the wrong step that i have taken? why the feature is not stappled correctly?

    Please help me. give me a idea what could be gone wrong.
    Thanks in advance.

    Regards,
    Anu
  • Hi Anu,

    Make sure that the Liebrand Sample Stapler is installed in your Farm. If you are doing

    Thanks & Regards
    Senthil
  • chrislovesdana
    Nice post. Right to the point. I used your example to create a template for Visual Studio.
  • Chirag
    How do I get it so any site that is created under a site collection (user's my site) get's added to the provisioned sites list? I am assuming that I can staple the feature to GLOBAL, however wouldn't that make the code run for all site's that are create and not just the one's in the My Site web application?
  • sarangasl
    Nice !!!!!!!!

    Create Custom SharePoint Features, it is simple.
    Try this too,
    Custom SharePoint Features
blog comments powered by Disqus