Wednesday, September 21, 2011

Add a custom webpart to a SharePoint site/page

I came across the situation like need to add more than a custom webpart on the landing page of my SharePoint site when creating a new site collection or sub site using custom site definition. Of course the answer will be "Yes, You can add the webpart in the onet.xml file" But the question is Will onet.xml file allow user to add more than a webpart in it?

<AllUsersWebPart WebPartOrder="1" WebPartZoneID="Right">
<![CDATA[
<webParts> <webPart><data><properties>
Custom webpart property details
</properties></data></webPart></webParts>
]]>
</AllUsersWebPart>


If you try adding more than a webpart in onet.xml file the throws flowing error.

Error: Web Part Error: Invalid Web Part tag.

Show Error Details

Error Details

[WebPartPageUserException: Invalid Web Part tag.]
at Microsoft.SharePoint.WebPartPages.WebPartImporter.ProcessNodes(ProcessNode fixupNode, String xpath, Boolean deleteProcessedNodes)
at Microsoft.SharePoint.WebPartPages.WebPartImporter..ctor(SPWebPartManager manager, XmlReader reader, Uri webPartPageUri, SPWeb spWeb)
at Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(SPWebPartManager manager, XmlReader reader, Boolean clearConnections, Uri webPartPageUri, SPWeb spWeb)
at Microsoft.SharePoint.WebPartPages.SPWebPartManager.CompressWebPartNoSave(Boolean isClosed)

So the another way of adding webpart on the site is via Feature stapler or directly by activating the feature. If the webpart want to be placed by default when the site created then the preferred choice is feature stapler. If user wants to add the webpart on need basis then go for activating feature.

Feature that add the webpart on the SharePoint site.

1. Assume that the custom/required webpart is available in the webpart gallery
2. Create the empty SharePoint 2010 project in visual studio 2010.
3. Add a new Feature in the project name as your wish(e.g "MyCustom webpart Feature" and GUID is "7bf8afb6-57dd-408d-b7c5-fea4b861b3cc")
4. Make the feature scope to web level
5. Add the Event receiver to the Feature
6. Add the System.Web.dll in the Refernces
7. Add below name spaces

using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
8. Use below source code to add the webpart on the site.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPWeb currentWeb = (SPWeb)properties.Feature.Parent)
{
using (SPLimitedWebPartManager webPartMgr = currentWeb.GetLimitedWebPartManager("default.aspx", PersonalizationScope.Shared))
{
using (System.Web.UI.WebControls.WebParts.WebPart webPart = CreateWebPart(currentWeb, "MyCustom.webpart", webPartMgr))
{
webPart.Height = 300;
webPart.Width = 300;
webPartMgr.AddWebPart(webPart, "Right", 1);
}
}
}
});
}
catch (Exception ex)
{
throw ex;
}
}

public static System.Web.UI.WebControls.WebParts.WebPart CreateWebPart(SPWeb web, string webPartName, SPLimitedWebPartManager manager)
{
SPQuery query = new SPQuery();
query.Query = String.Format(CultureInfo.CurrentCulture, "<Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='File'>{0}</Value></Eq></Where>", webPartName);
SPList webPartGallery = null;
if (null == web.ParentWeb)
{
webPartGallery = web.GetCatalog(SPListTemplateType.WebPartCatalog);
}
else
{
webPartGallery = web.Site.RootWeb.GetCatalog(SPListTemplateType.WebPartCatalog);
}
SPListItemCollection webParts = webPartGallery.GetItems(query);

if (webParts.Count > 0)
{
XmlReader xmlReader = new XmlTextReader(webParts[0].File.OpenBinaryStream());
string errorMessage;
System.Web.UI.WebControls.WebParts.WebPart webPart = manager.ImportWebPart(xmlReader, out errorMessage);
return webPart;
}
else { return null; }
}

9. Buid and deploy the solution

Note: Parameters for GetLimitedWebPartManager("default.aspx", PersonalizationScope.Shared) relative url and personalization scope. The relative url should your target page url. In above example used "default.aspx" where the Wiki Page Home Page feature deactivated. For default wiki page it may be "SitePages/Home.aspx".


"MyCustom.webpart" is name of the webpart that you want to add in the home page.

Need to create a stapler feature To attached with any site template.

1. Add a another feature to the project/solution
2. Add the empty element file to the feature
3. Add below tag with correct feature GUID of "MyCustom webpart Feature" in the element file

<FeatureSiteTemplateAssociation Id="7bf8afb6-57dd-408d-b7c5-fea4b861b3cc" TemplateName="

8 comments: