Quantcast
Viewing all articles
Browse latest Browse all 10

SharePoint provision default WebParts for MySites

SharePoint adds a new site collection for every user when their MySite is created. Recently I had a requirement to add a custom WebPart into a zone on the root page when the MySite gets created. I accomplished this requirement with the following:

  • Feature to create the WebPart
  • Feature Receiver to add the WebPart (this feature receiver ran off of the Feature to create the WebPart)
  • Feature Stapler to activate the Feature to create the WebPart when the site collection is created

The Feature to create the Webpart and Feature Stapler were easy (standard SharePoint development). The Feature Receiver to add the WebPart to a zone on the page is where it got a little tricky and is why I felt a blog is necessary.

Steps

  1. Create a new SharePoint 2010 solution in Visual Studio 2010
  2. Right-click on your project and choose to add a WebPart Feature (you can use a regular webpart or a visual webpart).
    1. For purposes of this blog, we will call this “MySiteWebPartFeature”
    2. Make sure this is a “Site” scoped Feature
  3. Right-click on your project and choose to add an Empty Element for your Feature Stapler
    1. For purposes of this blog, we will call this “MySiteFeatureStapler”
    2. Add a FeatureSiteTemplateAssociation to the MySite templates. Please delete the Id in the example below and replace it with the Id of the feature you created in Step 2
      <FeatureSiteTemplateAssociation Id=”9f8085c2-70cb-4ce1-814b-52e3967e5c3e” TemplateName=”SPSMSITEHOST#0″/>
      <FeatureSiteTemplateAssociation Id=”9f8085c2-70cb-4ce1-814b-52e3967e5c3e” TemplateName=”SPSPERS#0″/>
  4. Right-click on your Features and choose “Add Feature”. This is for your Feature Stapler.
    1. For purposes of this blog, we will call this “MySiteFeatureStapler”
    2. Set the Scope of this Feature to “WebApplication”
    3. Make sure the “MysiteFeatureStapler” element is added as an Item in this feature. Also, go back to the MySiteWebPartFeature and make sure the “MysiteFeatureStapler” element is removed from that one.
  5. Right-click on the MySiteWebPartFeature and choose “Add Event Receiver”
  6. Add the following code in the Event Receiver
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(RunProcess), properties);
}

private void RunProcess(object state)
{
    SPFeatureReceiverProperties properties = (SPFeatureReceiverProperties)state;

    using (SPSite site = (SPSite)properties.Feature.Parent)
    {
        bool provisioned = false;
        while (provisioned == false)
        {
            provisioned = site.RootWeb.Provisioned;
            Thread.Sleep(5000);
        };

        AddWebPart(site.RootWeb.Url);
    }
}

private void AddWebPart(string url)
{

    using (SPSite site = new SPSite(url))
    {
        using (SPWeb web = site.OpenWeb())
        {
            try
            {
                SPLimitedWebPartManager wpm = web.GetLimitedWebPartManager("default.aspx", System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

                bool webpartexists = false;
                foreach (Microsoft.SharePoint.WebPartPages.WebPart webpart in wpm.WebParts)
                {
                    if (webpart.Title == "My Custom WebPart")
                    {
                        webpartexists = true;
                        break;
                    }
                }

                if (!webpartexists)
                {
                    Treasury_MySites.PrivacyStatement.PrivacyStatement privacyStatementWebPart = new Treasury_MySites.PrivacyStatement.PrivacyStatement();
                    privacyStatementWebPart.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.None;
                    privacyStatementWebPart.Title = "My Custom WebPart";
                    wpm.AddWebPart(privacyStatementWebPart, "TopZone", 0);
                }
            }
            catch
            {
                //do nothing
            }
        }
    }
}

In the end, the Feature Stapler needs to be activated at your web application level. When a new site is created within that web application the MySiteWebPartFeature will activate. When that feature activates it will add the WebPart to the webpart gallery (because that’s the standard behavior of a SharePoint WebPart feature). In addition it will run the custom Event Receiver code upon Feature Activation.

The magic of this solution is in the Event Receiver itself. It is using a seperate thread to make sure the root web gets provisioned before adding the WebParts to the zones on the page. Why is this important?

  • If you don’t use a separate thread you could hold up the web from getting provisioned and you will just hang
  • If the web is not provisioned there is no page to add the WebParts to

Is there other ways of doing this? At first I thought the WebProvisioner class would accomplish the same thing. But, that only works on sub-webs, not the root. Other than that, I couldn’t think of another way other than custom master pages or custom site definitions. I’d be glad to hear if anyone else knows another way.


Viewing all articles
Browse latest Browse all 10

Trending Articles