Remove webpart from a page on Personal site using delegate control

Published on Saturday, January 12, 2013

Customizing Personal Sites (site collections for users in my site) could be little challenging at times. One reason being that personal site is provisioned automatically by SharePoint and there could be more than one point from which user can provision the site and there is no support to create your own web template or site definition, as we can do with every other type of site (as per my knowledge). Creating your own web template provides great flexibility and easiness to provision sites  having your own settings and all but lacking this feature for personal sites provide us more challenges, even for small customizations at times. In a recent project, one of the customer's wish was to remove "Recent Blog Posts" web part from default page when user provisions the personal site.

Solution: After trying out different approaches the final solution turned out to create a delegate control that removes the web part from the page when site is provisioned and having this delegate control added on the site collection through feature stappling.

So, here is what I did to fulfill this requirement.
  1. Create a delegate control
  2. Here is the element file for delegate control

    
    <!--?xml version="1.0" encoding="utf-8"?-->
    
     <Control
     ControlAssembly="MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b848d3ec396f6039"
     ControlClass="MyAssembly.RemoveWebPartsFromPersonalSiteDefaultPage" Id="AdditionalPageHead" Sequence="50"
    
    
    <li>Fetch the desired webpart and remove it</li>
    
and in the code behind file for this delegate control add the functionality to fetch and remove the desired webpart (I've added this logic in Render method)


//... code removed

//Fetch Web Part title from SPCore resoruce file for current web language
 //It is important to fetch the localed based on current site's language not based on Browser locale or regional settings!
 var localizedRecentPostWebPartName = SPUtility.GetLocalizedString("$Resources:spscore,MySiteOnet_WebPart_Blog", "spscore", SPContext.Current.Web.Language);

//remove the webpart
 RemoveWebPartsFromWebPartPage(SPContext.Current.Web, "default.aspx", "MiddleRightZone", localizedRecentPostWebPartName);

 //add page redirectino logic otherwise it will be an infinite loop
 // ... code removed

Here is the definition of RemoveWebPartsFromWebPartPage method:



//... code removed

using (SP.SPLimitedWebPartManager webpartManager = web.GetLimitedWebPartManager(webPartPage.Url, Web.PersonalizationScope.Shared))
{
  var collection = webpartManager.WebParts;
  List webParts = new List();

  foreach (WebPart webPart in collection)
  {
    if (fromZoneId == webpartManager.GetZoneID(webPart))
    {
      if (webPart.DisplayTitle == webPartTitle)
      {
          webParts.Add(webPart);
      }
    }
  }

 // delete the web parts
 foreach (WebPart webPart in webParts)
 {
   webpartManager.DeleteWebPart(webPart);
 }
}

That's it! that is the functionality that we need to remove the webpart. We created a delegate control that contains the code to remove the web part from desired page! Now comes the part where we need to execute this delegate. You can use different approaches depending on your requirement. For this demo, we create a simple site scoped feature and add this delegate as an item in that feature.

Build your solution, create the package and deploy it. Activate the feature. Having this feature activated, as soon as user navigates to the default page, our delegate control will kick in and looks for the desired web part and removes it!

Other approaches could be creating feature stappling mechanism that attaches our delegate control with desire web templates so that this control is attached to every site that is created.

Hope it helps!

comments powered by Disqus