Skip Ribbon Commands
Skip to main content

Tanmay Shahane | zevenseas | SharePoint Blog

:

Tanmay Shahane | zevenseas | SharePoint Blog > Posts > Adding CUSTOM webparts on publishing pages Sandbox solution through modules
August 24
Adding CUSTOM webparts on publishing pages Sandbox solution through modules

 

Hello kind readers…
 
Sandbox solutions… funny, challenging.. Pathetic… painful.. Wonderful.. Everything a developer wants to feel energized :)
 
So recently we were building one of such sandbox solution which required a lot of default web parts on different  pages in a larger hierarchy of sites and writing code to do(sandbox does not have limited webpart manager) that or doing it manually was a pain. So we wanted to automate the process and then while venturing around I found some insights on how to add default web parts like CQWP on a default.aspx.. But still we wanted more flexibility...
 
so the thing is when you are adding a page using a page layout and template redirection with some default content on it through the sandbox solution module element then the page should come from a path that is physically located on the disk (mainly 14 hive folder ..site templates), so taking an example of the default.aspx we need the xml as
 
<Module Name="SitePages" Url="Pages" SetupPath="SiteTemplates\SPS"> //The SetupPath should be pointing to the physical location of the file so the site templates folder
    <File Path="default.aspx" Url="default.aspx" Type="GhostableInLibrary"> //the setup path has the folder name and the file PATH has the file name from this folder which in this case is default.aspx so directly default.aspx
     
<Property Name="Title" Value="Home Page" />
     
<Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/yourLayout.aspx, Homepage" />
     
<Property Name="ContentType" Value="your content type" />
//then you add the webpart xml in with the respective webpart zone id as in you layout
     
<AllUsersWebPart WebPartOrder="1" WebPartZoneID="LeftColumn">
       
<![CDATA[
        <webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Name of your webpart class, four part assembly name" />
      <importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>     
    </metaData>
    <data>
      <properties>
        <property name="Title" type="string">Working</property>
        <property name="Description" type="string">My WebPart</property>
        <property name="ChromeType" type="chrometype">TitleOnly</property>       
      </properties>
    </data>
  </webPart>
</webParts>
]]>
     
</AllUsersWebPart>
   
</File>
 
</Module>
 
Now if you add a default sharepoint webpart like the CQWP here by exporting the xml and adding it here.. It will work without a problem and you have a default web part on the default.aspx… but what about the CUSTOM webparts … coz if you add a custom web part to a page manually through UI and export the xml from it… you will get the same xml for all webparts with meta data properties as,
 
<type name="Microsoft.SharePoint.WebPartPages.SPUserCodeWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
     
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
   
</metaData>
 
Now this SPUserCodeWebpart is always there so if you just copy paste this xml it won't load you webpart on deployment as it does not know which webpart you want… and if you copy the xml from the .webpart xml from your solution it will have the <$SharePoint.Project.AssemblyFullName$> as the assembly name which is resolved by VS to the respective assembly name automatically. So how do you add a custom webpart then, well that can be done with some modifications above as,
 
 
<Module Name="SitePages" Url="Pages" SetupPath="SiteTemplates\SPS"> //The SetupPath should be pointing to the physical location of the file so the site templates folder
   
<File Path="default.aspx" Url="default.aspx" Type="GhostableInLibrary"> //the setup path has the folder name and the file PATH has the file name from this folder which in this case is default.aspx so directly default.aspx
     
<Property Name="Title" Value="Home Page" />
     
<Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/yourLayout.aspx, Homepage" />
     
<Property Name="ContentType" Value="your content type" />
//then you add the webpart xml in with the respective webpart zone id as in you layout
     
<AllUsersWebPart WebPartOrder="1" WebPartZoneID="LeftColumn">
        <![CDATA[
       
<webParts>
 
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
   
<metaData>
      <type name="Name of your webpart class, four part assembly name" /> //the four part assembly name to be added for your assembly, could be found in manifest xml in your package file in VS.
     
<importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>     
//You need to add the solution ID of the solution this webpart is a part of, again can found at manifest xml
//this makes sense coz with sandbox solution SharePoint should know where to look for the assembly

<Solution SolutionId="your solution GUID" xmlns="http://schemas.microsoft.com/sharepoint/" />
   
</metaData>
   
<data>
Now with the Solution element  in your meta data properties … the Four part assembly name of the assmebly your webpart is a part of .. The name class of webpart..
The setup path pointing to a physical location and File path picking up default.aspx from that setup path folder
 
Your deployed default.aspx page will have the custom webparts as well on the page and not just SharePoint webparts, basically the important things here are,
 
  • In <Module> element the setup path of the module should point to a physical folder on the disk, mainly SiteTemplates\SPS
  • In <File> element the Path attribute should have the name of the file residing in the folder name you gave in set up path
  • The webpart  xml <type> element should have the complete type name of the webpart class plus the full 4 part assembly name
  • The webpart xml should have the <solution> element in the <metatdata> section giving the solution guid ID which the webpart is part of
 
With these things in place you can have your custom webpart on the page. Now this is not only true for default.aspx … you can use this approach for any page… what you would need to change is just the URL attribute of the <File> element and layouts property to you’re the respective layout.... So if you want to have a page with URL and name as MyWork.aspx then the xml changes would be only,
 
<Module Name="SitePages" Url="Pages" SetupPath="SiteTemplates\SPS"> //The SetupPath should be pointing to the physical location of the file so the site templates folder
   
<File Path="default.aspx" Url="MyWork.aspx" Type="GhostableInLibrary"> //the setup path has the folder name and the file PATH has the file name from this folder which in this case is default.aspx so directly default.aspx and URL has the new name you want to give
      <Property Name="Title" Value="My Page" />
     
<Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/Somelayout.aspx, whatever" />
 
Rest remains same.
 
Hope this helps you in some way to speed up or automate your deployment if you mix it up with web templates :)
 
 - "T"

 

Comments

Some Interesting Points

1. This technique also comes handy when you would like to add webpart to existing page.. you need to make sure you are setting the IgnoreIfAlreadyExists = "TRUE" on File Element.

2. You cannot control the behavior/scenario when would like to add webpart only based on some business requirement... i know you must be thinking that i could be handled with throwing Exception and cancelling the Webpart Addition process but this is not how Sharepoint works with... you have to have the Custom Feature Receiver which will delete the Webpart from the page.. 

nice post.. "T"

Akhilesh Nirapure
 on 8/24/2011 1:37 AM

@dude aka Akhilesh

Thanks man for adding that... great points!!!
Tanmay Shahane on 8/24/2011 1:40 AM

Deploying STS home.aspx

Tanmay,  have you used this on a 2010 teamsite?   I am curious what the setuppath would be, or even the contents of the home.aspx page within you module.   I would like to deploy to the Rich Content zone declaratively or replace the home page altogether.  I would like to keep the same layout currently in the team site wiki page home.aspx

Thanks,
Andrew
 on 12/7/2011 1:07 PM

Home.aspx

I am really sorry for the late reply Andrew ... Will check this out
Tanmay Shahane on 1/28/2012 11:49 AM

Not working with PerformancePoint Report Web Part

I am using PerformancePoint Report web part. How can I mention the solutionId for this? The reports are deployed at root/Reports path that i have mentioned in LocationUrl property.

Without SolutionId, it says "Cannot import this web part"

Thanks
Amit
 on 2/7/2012 4:03 AM

Not working with PerformancePoint Report Web Part

I am using PerformancePoint Report web part. How can I mention the solutionId for this? The reports are deployed at root/Reports path that i have mentioned in LocationUrl property.

Without SolutionId, it says "Cannot import this web part"

Thanks
Amit
 on 2/7/2012 4:06 AM

This doesn't work

When I use this approach I get an exception in the ULS (the webpart just adds a label with text="Hello World!"):
http://win-sps20/roadshow/Pub/Pages/default.aspx - An unexpected error has been encountered in this Web Part.  Error: Cannot import this Web Part., Source: [WebPartPageUserException: Cannot import this Web Part.]<br/>&#160; 
 at Microsoft.SharePoint.WebPartPages.WebPartImporter.CreateWebPart(Boolean clearConnections) <br/>&#160; 
 at Microsoft.SharePoint.WebPartPages.WebPartImporter.Import(SPWebPartManager manager, XmlReader reader, Boolean clearConnections, Uri webPartPageUri, SPWeb spWeb) <br/>&#160; 
 at Microsoft.SharePoint.WebPartPages.SPWebPartManager.CompressWebPartNoSave(Boolean isClosed), DesignText: <webParts>           <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">             <metaData>               <type name="SharePointProject1.WebPart2.WebPart2, SharePointProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cab361b236e16b57" />               <solution SolutionId="ee4e2533-92c2-466d-a7ab-592fca891e65" xmlns="http://schemas.microsoft.com/sharepoint/"/>               <importErrorMessage>Cannot import this Web Part.</importErrorMessage>             </metaData>             <data>               <properties>                 <property name="Title" type="string">WebPart1</property>                 <property name="Description" type="string">My WebPart</property>               </properties>             </data>           </webPart>         </webParts>, SourcePreamble: DWP
 on 5/8/2012 6:11 AM

You should provide a sample

I do not know how one could get this to work because of the following:
1)  Webparts leverages the webpart objects model.  Sandboxed web parts use a different container control for web parts.
2)  The solution element is not a child element of the metadata element this wouldn't load such a child element.
3)  Webpart element doesn't have knowledge of the location of the assembly becuase the assembly may often not even reside on the WFE.

A true to life example would enlighten all that don't see this working.
 on 5/8/2012 6:14 AM

You should provide a sample

I do not know how one could get this to work because of the following:
1)  Webparts leverages the webpart objects model.  Sandboxed web parts use a different container control for web parts.
2)  The solution element is not a child element of the metadata element this wouldn't load such a child element.
3)  Webpart element doesn't have knowledge of the location of the assembly becuase the assembly may often not even reside on the WFE.

A true to life example would enlighten all that don't see this working.
 on 5/8/2012 8:38 AM

Working example

The XML I have pasted is very much from my live work and is working fine, about the error seen in ULS, well in case your are provisioning the page before the solution is added and acitvated is where you would get that error.

Please make sure all the name space and assmbly names match with XML and also that your WP solution is avaliable before you are provisiong the page which imports the WP
Tanmay Shahane on 5/18/2012 7:20 AM
1 - 10Next

Add Comment

Title


Body *


Attachments

 

 Related Posts

 
 

 Statistics

 
Views: 10042
Comments: 16
Tags:Sandboxed Solutions
Published:637 Days Ago