Update for MyMasters Solution -16th Nov 2011

Hi Everyone recently i uploaded a new version (1.1) of MyMasters solution.

the solution now covering fallowing questions’ answers :

* How to deploy a custom wellcome page to Personal Site ?
* How to add custom webparts to a page ?
* How to use XsltListViewWebPart and add a document library as a webpart ?

You can download new version from CodePlex site of MyMasters solution:

Please visit related post about MyMasters:

Here is a code sample for above questions :
as you guess CreateWellcomePage function has been calling in Feature Reciever class of MyMasters Feature.

  1. private void CreateWellcomePage(SPFeatureReceiverProperties properties)
  2.         {
  3.             SPSite site = (SPSite)properties.Feature.Parent;
  4.             SPWeb web = site.OpenWeb();
  5.             PublishingSite pSite = new PublishingSite(site); //Get Publishing Site Object
  6.             SPContentType ctype = pSite.ContentTypes[“Welcome Page”]; //Get builtin “Wellcome Page” content type
  7.             PageLayoutCollection pageLayouts = pSite.GetPageLayouts(ctype, true); //Get builtin pagelayouts for this content type
  8.             PageLayout pageLayout = pageLayouts[0]; //Select first one which is BlankWebPartPage pagelayout
  9.             PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(web); //Get Publishing Web.
  10.             PublishingPageCollection pPages = pWeb.GetPublishingPages(); // Get Page Collection
  11.             //TempFile for changing default page
  12.             string tempFileName = “TempFileForChangeWellcomePage.aspx”;
  13.             PublishingPage tempPage = null;
  14.             try
  15.             {
  16.                 //Get if there is an existing wellcome.aspx
  17.                 PublishingPage pPageExist = pPages[pWeb.Url + “/Pages/Wellcome.aspx”];
  18.                 if (pPageExist != null)
  19.                 {
  20.                     //Check wellcome.aspx is default page
  21.                     if (pWeb.DefaultPage.UniqueId == pPageExist.ListItem.File.UniqueId)
  22.                     {
  23.                         //if it is a default page we have to create a template page because the default page is not deleted.
  24.                         //Create a temporary page
  25.                         tempPage = pPages.Add(tempFileName, pageLayout);
  26.                         tempPage.ListItem.File.CheckIn(“Chk”);
  27.                         tempPage.ListItem.File.Publish(“Pub”);
  28.                         //Set this temporary file as default page so we can able to delete existing wellcome.aspx
  29.                         pWeb.DefaultPage = tempPage.ListItem.File;
  30.                         pWeb.Update();
  31.                     }
  32.                     //Delete Existing Wellcome.aspx
  33.                     if (pPageExist.ListItem.File.CheckedOutByUser != null)
  34.                     {
  35.                         pPageExist.ListItem.File.UndoCheckOut();
  36.                     }
  37.                     pPageExist.CheckOut();
  38.                     pPageExist.ListItem.Delete();
  39.                     pWeb.Update();
  40.                 }
  41.             }
  42.             catch(Exception ex)
  43.             {
  44.             }
  45.             //Create a new Wellcome.aspx file
  46.             PublishingPage pPage = pPages.Add(“Wellcome.aspx”, pageLayout);
  47.             SPListItem newpage = pPage.ListItem;
  48.             newpage[“Title”] = “Wellcome to my personal site”;
  49.             //Add need webparts to page.
  50.             using (SPLimitedWebPartManager wpMgr = web.GetLimitedWebPartManager(pPage.Url, PersonalizationScope.Shared))
  51.             {
  52.                 //Get WebPart Catalog
  53.                 SPList webPartCatalog = web.GetCatalog(SPListTemplateType.WebPartCatalog);
  54.                 foreach (SPListItem item in webPartCatalog.Items)
  55.                 {
  56.                     if (item.DisplayName == “LatestBlogPostsPublic”)
  57.                     {
  58.                         string fileName = string.Format(“{0}/{1}”, item.Web.Url, item.File.Url);
  59.                         XmlTextReader reader = new XmlTextReader(new StringReader(item.Web.GetFileAsString(fileName)));
  60.                         string error;
  61.                         System.Web.UI.WebControls.WebParts.WebPart wx = wpMgr.ImportWebPart(reader, out error);
  62.                         wpMgr.AddWebPart(wx, “Header”, Convert.ToInt32(0));
  63.                     }
  64.                 }
  65.                 //Add existing Document Library views
  66.                 SPList SharedDocumentsList = web.Lists[“Shared Documents”];
  67.                 SPView SharedDocumentsListView = SharedDocumentsList.Views[0];
  68.                 SPList PersonalDocumentsList = web.Lists[“Personal Documents”];
  69.                 SPView PersonalDocumentsListView = PersonalDocumentsList.Views[0];
  70.                 XsltListViewWebPart wp = new XsltListViewWebPart();
  71.                 wp.ListId = SharedDocumentsList.ID;
  72.                 wp.Title = “Shared Documents”;
  73.                 wp.ChromeType = PartChromeType.TitleOnly;
  74.                 wp.ViewGuid = SharedDocumentsListView.ID.ToString();
  75.                 wp.XmlDefinition = SharedDocumentsListView.GetViewXml();
  76.                 wpMgr.AddWebPart(wp, “Header”, Convert.ToInt32(1));
  77.                 XsltListViewWebPart wp2 = new XsltListViewWebPart();
  78.                 wp2.ListId = PersonalDocumentsList.ID;
  79.                 wp2.Title = “Personal Documents”;
  80.                 wp2.ChromeType = PartChromeType.TitleOnly;
  81.                 wp2.ViewGuid = PersonalDocumentsListView.ID.ToString();
  82.                 wp2.XmlDefinition = PersonalDocumentsListView.GetViewXml();
  83.                 wpMgr.AddWebPart(wp2, “Header”, Convert.ToInt32(2));
  84.             }
  85.             newpage.File.CheckIn(“Administravily Check in”);
  86.             newpage.File.Publish(“Administravily Published”);
  87.             //set wellcome.aspx as default page.
  88.             pWeb.DefaultPage = newpage.File;
  89.             pWeb.Update();
  90.             //delete if tempfile is exists.
  91.             if (tempPage != null)
  92.             {
  93.                 tempPage.ListItem.Delete();
  94.             }
  95.             pWeb.Update();
  96.         }

Attach custom master page to personal site using Stapling feature for Sharepoint 2010

Hi Everyone ,

In this article i am explaining how could we attach a custom master page to  Personal sites in MySite Host. I have created two Sharepoint Project named MyMasters and MyMastersStapling using Visual Studio 2010.

you can download the visual studio solution from CodePlex

The solution is anwering fallowing questions  :

* How to deploy custom master page ?
* How to customize a masterpage ?
* How to attach custom master page to personal sites using staping feature ?
* How to set wellcome page programmatically ?
* How to add document library as a web part to a page ?

MyMasters  Project
: is a sharepoint project that deploy a custom master page to a sharepoint site.
MyMasterStapling  Project: is a sharepoint project that attach feature of MyMasters to personal site template and activates the publishing features

First i created a site scope feature named “MyMasters”  and and a feaurereciever .The important part is here the feature guid . You need this guid for feature stapling configuration. you can get the feature guid from Feature manifest file.

<Feature xmlns=”http://schemas.microsoft.com/sharepoint/” Title=”MyMasters” Description=”This feature enables defined master page for your site”
Id=”09c222f7-68ed-4278-a3ce-d64b8dbfb168” ReceiverAssembly=”MyMasters, Version=, Culture=neutral, PublicKeyToken=2e49c3c1155d0e27″ ReceiverClass=”MyMasters.Features.MyMasters.MyMastersEventReceiver” Scope=”Site”>
… child nodes

And I have create two modules MasterPageModule and CustomAssests Module .

MasterPageModule : contains masterpage file and when the feature is activated it deploy master page the masterpage library under _catalogs folder.
CustomAssests : contains necessary css , js and image files. when the feature is activated it deploy assests to Style Library List of target site by creating specific folder for each asset type.

Here is the code of Feature Reciever.

public class MyMastersEventReceiver : SPFeatureReceiver
// Uncomment the method below to handle the event raised after a feature has been activated.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
// Uncomment the method below to handle the event raised before a feature is deactivated.
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
SPSite site = (SPSite)properties.Feature.Parent;
if (site != null)
//Remove custom master page
SPFile masterFile = site.RootWeb.GetFile(“_catalogs/masterpage/PersonalSite.master”);
//Remove assets folders.
site.RootWeb.Folders[“Style Library”].SubFolders.Delete(“CustomCssFiles”);
site.RootWeb.Folders[“Style Library”].SubFolders.Delete(“CustomJSFiles”);
site.RootWeb.Folders[“Style Library”].SubFolders.Delete(“CustomImages”);
}   private void ApplyTheme(SPFeatureReceiverProperties properties)
SPSite site = (SPSite)properties.Feature.Parent;
if (site != null)
// Set the System Master Page to orginal
Uri masterUri = new Uri(site.RootWeb.Url + “/_catalogs/masterpage/v4.master”);
site.RootWeb.MasterUrl = masterUri.AbsolutePath;
// Set the Publishing Master Page our custom PersonalSite.master page.
Uri customMasterUri = new Uri(site.RootWeb.Url + “/_catalogs/masterpage/PersonalSite.master”);
site.RootWeb.CustomMasterUrl = customMasterUri.AbsolutePath;
private void RevertTheme(SPFeatureReceiverProperties properties)
SPSite site = (SPSite)properties.Feature.Parent;
if (site != null)
// Set the System Master Page to orginal
Uri masterUri = new Uri(site.RootWeb.Url + “/_catalogs/masterpage/v4.master”);
site.RootWeb.MasterUrl = masterUri.AbsolutePath;
// Set the Publishing Master Page  to orginal
Uri customMasterUri = new Uri(site.RootWeb.Url + “/_catalogs/masterpage/v4.master”);
site.RootWeb.CustomMasterUrl = customMasterUri.AbsolutePath;

By default the following rule applies when you deploy a master page:

  • Site Master Pages: used by all publishing pages – and only by publishing pages
  • System Master Pages: used by everything else including forms and view pages

So in Feature reciever ->  ApplyTheme() function we set two master page first one is V4.master the orginal master for System masterpage and our custom master for Site Master page. As you know you have to enable Publishing Features for  the site if you want to this deplotment work correctly.
For deploying PersonalSite.master via module the element file :

   <FilePath=MasterPageModule\PersonalSite.master  Url=PersonalSite.masterType=GhostableInLibrary >
        <PropertyName=UIVersionValue=4 />
        <PropertyName=ContentTypeIdValue=0x010105 />

You can deploy this solution any site by using visual studio at the end you can able to see this view :

For MyMasterStapling Project . I have created a farm level feature named “MyMastersStapling” and an empty element named “StaplingElement”

Element.xml :

<FeatureSiteTemplateAssociationId=f6924d36-2fa8-4f0b-b16d-06b7250180faTemplateName=SPSPERS#0 />
<FeatureSiteTemplateAssociationId=22a9ef51-737b-4ff2-9346-694633fe4416TemplateName=SPSPERS#0 />
<FeatureSiteTemplateAssociationId=09c222f7-68ed-4278-a3ce-d64b8dbfb168TemplateName=SPSPERS#0 />

The FeatureSiteTemplateAssociation element maps feature GUIDs to site defintions – note that the format of the TemplateName attribute value is <SiteDefName>#<ConfigurationID>. This obviously allows a degree of flexibility and allows you to do fairly complex things with different configurations of site definitions. As you now at the beginning of article we highlighted a GUID the feature of MyMasters.

The third item is using this guid 09c222f7-68ed-4278-a3ce-d64b8dbfb168 .What about first two ? these feature ids are blong to Publishing Features. First one is “Publishing Feature Site”  feature’s id at site level and the second one is Publishing feature’s id at web level.

These two ids are built in sharepoint 2010 and it is not change by installation .If you wonder how could i found this ids ,i used the powershell console for sharepoint :
get-spfeature | where-object { $_.DisplayName -like “*Publish*” }

For Template name  SPSPERS is the personal site template name.  for #Zero i am attaching the default configuration.

For More information about site templates.

So far so good. After you deploy our stapling project and activate the feature , the users can able to see our custom master page even if self site creation is enabled for personal sites .

See you next articles.