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="

Wednesday, September 14, 2011

List Item URL (Edit- Link to Item) using CAML query

The method SP.UI.ModalDialog.showModalDialog can be used for opening list item in model dialog. It requires target URL as input parameter.

<a href="{$hyperLink}" title="{$TaskTitle}" >
<xsl:attribute name="onclick">
SP.UI.ModalDialog.showModalDialog({url:'<xsl:value-of select="$hyperLink"/>' });return false;
</xsl:attribute>
<xsl:value-of select="$TaskTitle"/>
</a>

Below is the complete example. The xml data generated from task list.

E.g

XML

<NewDataSet>
<PMOProject>
<ListId>9C5526E2-205E-491D-865E-2B1FB9634080</ListId>
<WebId>05DEA448-7E27-4104-93CB-27D90A8E9A00</WebId>
<ID>1</ID>
<Title>test123 task</Title>
<Status>Not Started</Status>
<ProjectProperty.Title>test123</ProjectProperty.Title>
<ListProperty.Title>Tasks</ListProperty.Title>
<EncodedAbsUrl>http://sitecoll/</EncodedAbsUrl>
<FileDirRef>1;#sites/PMO/test123/Lists/Tasks</FileDirRef>
</PMOProject>
<PMOProject>
<ListId>E560F3F9-4E80-455D-8840-423B72761007</ListId>
<WebId>50BB0EA1-3004-4DB7-B7CF-30AC2BA0941E</WebId>
<ID>1</ID>
<Title>PMO Task01</Title>
<Status>Not Started</Status>
<ProjectProperty.Title>PMO</ProjectProperty.Title>
<ListProperty.Title>Tasks</ListProperty.Title>
<EncodedAbsUrl>http://sitecoll/</EncodedAbsUrl>
<FileDirRef>1;#sites/PMO/Lists/Tasks</FileDirRef>
</PMOProject>
<PMOProject>
<ListId>E560F3F9-4E80-455D-8840-423B72761007</ListId>
<WebId>50BB0EA1-3004-4DB7-B7CF-30AC2BA0941E</WebId>
<ID>2</ID>
<Title>ssstest321</Title>
<Status>Not Started</Status>
<ProjectProperty.Title>PMO</ProjectProperty.Title>
<ListProperty.Title>Tasks</ListProperty.Title>
<EncodedAbsUrl>http://sitecoll/</EncodedAbsUrl>
<FileDirRef>2;#sites/PMO/Lists/Tasks</FileDirRef>
</PMOProject>
</NewDataSet>

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="hyperLink"/>
<xsl:variable name="baseurl"/>
<xsl:variable name="TaskTitle" />
<xsl:key name="proj" match="PMOProject" use="node()[name()='ProjectProperty.Title']" />
<xsl:template match="NewDataSet">
<xsl:for-each select="PMOProject[count(. | key('proj', node()[name()='ProjectProperty.Title'])[1]) = 1]">
<xsl:sort select="node()[name()='ProjectProperty.Title']" />
<b>
<xsl:value-of select="node()[name()='ProjectProperty.Title']" />
</b>
<br />
<xsl:for-each select="key('proj', node()[name()='ProjectProperty.Title'])">
<xsl:sort select="node()[name()='Status']" />
<xsl:variable name="TaskTitle" select="node()[name()='Title']" />
<xsl:variable name="baseurl" select="substring-before(node()[name()='FileDirRef'],'Lists/')"/>
<xsl:value-of select="node()[name()='Status']" /> <xsl:variable name="hyperLink" select="concat(node()[name()='EncodedAbsUrl'],substring-after($baseurl,'#'),'Lists/ProjectPlan/editform.aspx?ID=',node()[name()='ID'])"/>:-
<a href="{$hyperLink}" title="{$TaskTitle}" >
<xsl:attribute name="onclick">
SP.UI.ModalDialog.showModalDialog({url:'<xsl:value-of select="$hyperLink"/>' });return false;
</xsl:attribute>
<xsl:value-of select="$TaskTitle"/>
</a><br />
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Wednesday, September 7, 2011

Find the SharePoint web Template ID

The web template id can be found using object model or Power shell script.
Powershell script to find the specific web template details:
Open windows Powershell ISE to execute the comments/scripts. Load the SharePoint assembly if those are not loaded.
To load the SharePoint assembly
[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
OR
This assembly can be referred using the “LoadWithPartialName” function which doesn’t require the full assembly information:
[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)

$web = Get-SPWeb http://portal
write-host "Web Template:" $web.WebTemplate " Web Template ID:" $web.WebTemplateId
$web.Dispose()
Above script can be stored as a .ps1 file and can be executed using SharePoint PowerShell window.

C# code to find out the web template details:
Server Object model can be used for finding out the web template details.
using System;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
using(SPSite site=new SPSite(@"http://sitecoll/"))
{
SPWeb web = site.RootWeb;
Console.WriteLine("Web Name : "+web.Title);
Console.WriteLine("Web Template Name : " + web.WebTemplate);
Console.WriteLine("Web Template ID : " + web.WebTemplateId);
Console.WriteLine("Web GUID : " + web.ID);
}
Console.Read();
}
catch (Exception ex)
{
Console.WriteLine("Error: "+ex.Message);
}
}
}
}


Tuesday, September 6, 2011

Tips on Blank site Template

The Blank site template is somewhat defferent from other site templates in SharePoint 2010.

Taxonomy will not work in Blank site template since the feature is not activate. User has to activate the feature manually. The Taxonomy Feature Stapler attached with global and some of site templates but not with blank site template. The attribute AllowGlobalFeatureAssociations=”False” in blank site template.

To activate Taxonomy Feature using Power Shell

Enable-SPFeature -identity “73EF14B1-13A9-416b-A9B5-ECECA2B0604C” -url “http://sitecollection/”
OR
Enable-SPFeature -identity “TaxonomyFieldAdded“ -url “http://sitecollection/”

To activate Taxonomy Feature using STSADM command

STSADM -o activatefeature -id “73EF14B1-13A9-416b-A9B5-ECECA2B0604C” -url “http://sitecollection/” –force
OR
stsadm -o activatefeature name TaxonomyFieldAdded -url “http://sitecollection/”