Home > SharePoint > Customising SharePoint 2010 MySites with Publishing Sites Part 1

Customising SharePoint 2010 MySites with Publishing Sites Part 1

So you may have seen the MSDN blog here (http://blogs.msdn.com/b/sharepoint/archive/2007/03/22/customizing-moss-2007-my-sites-within-the-enterprise.aspx) which shows you how to customise MySites.

The approach the above design takes is to have a control on a custom master page which checks whether this is the first time you have accessed MySites and if so will get the Default.aspx page and add webparts to it.

The Problem
With this approach the Default.aspx page is not GhostableInLibrary so if you later need to make a change to the default.aspx page, say add an extra webpart zone or a new usercontrol into the page it becomes inefficient and error prone.

The Solution
So in comes publish sites to the rescue.
With publishing sites we can utilise pagelayouts which are GhostableInLibrary, meaning that a simple Update-SPSolution (aka UpgradeSolution in stsadm) will push out any updates to users home pages, and we could possibly have a set of different pagelayouts for users to select from.
So to achieve this we start by having a feature stapler that is stapled to the MySites much like the MSDN approach but we include Publishing features as shown below.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >  
 <!-- Publishing Site Collection Level --> 
 <FeatureSiteTemplateAssociation Id="F6924D36-2FA8-4f0b-B16D-06B7250180FA" 
 TemplateName="SPSPERS#0" /> 
 
 <!-- Publishing --> 
 <FeatureSiteTemplateAssociation Id="22A9EF51-737B-4ff2-9346-694633FE4416" 
 TemplateName="SPSPERS#0" /> 

 <!-- Publishing web --> 
 <FeatureSiteTemplateAssociation Id="94C94CA6-B32F-4da9-A9E3-1F3D343D7ECB" 
 TemplateName="SPSPERS#0" /> 

 <!-- Custom MySite Webparts --> 
 <FeatureSiteTemplateAssociation Id="0708462c-25ef-4ccd-a822-73b6a946d23b" 
 TemplateName="SPSPERS#0" /> 

 <!-- MySite Provisioner --> 
 <FeatureSiteTemplateAssociation Id="7549e9df-9360-48f7-bfe9-7b09e60e9f42" 
 TemplateName="SPSPERS#0" /> 
</Elements>

So when someone accesses their MySite for the first time we will activate publishing features, any custom features like custom webparts that you may have created and trigger the MySite Provisioner feature to run.

First the provisioner feature will copy over our custom masterpages using the following module:

<?xml version="1.0" encoding="utf-8"?> 
<Elements xmlns="http://schemas.microsoft.com/sharepoint/"> 
 <Module Name="MasterPages" Url="_catalogs/masterpage" RootWebOnly="TRUE" 
 xmlns="http://schemas.microsoft.com/sharepoint/"> 
 <File Url="CustomV4.master" Path="MasterPages\CustomV4.master" 
 Type="GhostableInLibrary"> 
 <Property Name="ContentType" 
 Value="$Resources:cmscore,contenttype_masterpage_name;" /> 
 <Property Name="MasterPageDescription" 
 Value="Custom V4 Master Page" /> 
 </File> 
 <File Url="CustomMySite.master" Path="MasterPages\CustomMySite.master" 
 Type="GhostableInLibrary"> 
 <Property Name="ContentType" 
 Value="$Resources:cmscore,contenttype_masterpage_name;" /> 
 <Property Name="MasterPageDescription" Value="Custom MySite Master Page" /> 
 </File> 
 </Module> 
</Elements>

Next we copy over our page layout:

<?xml version="1.0" encoding="utf-8"?> 
<Elements xmlns="http://schemas.microsoft.com/sharepoint/"> 
 <Module Name="PageLayouts" Url="_catalogs/masterpage" RootWebOnly="TRUE" 
 xmlns="http://schemas.microsoft.com/sharepoint/"> 
 <File Path="HomePage\HomePage.aspx" Url="HomePage.aspx" 
 Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE"> 
 <Property Name="Title" Value="Home Page" /> 
 <Property Name="ContentType" 
 Value="$Resources:cmscore,contenttype_pagelayout_name;" /> 
 <Property Name="PublishingAssociatedContentType" 
 Value=";#Page;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F
 2007948130EC3DB064584E219954237AF39;#" /> 
 </File> 
 </Module> 
</Elements>

Then our feature reciever code will run as follows:

using System; 
using System.Runtime.InteropServices; 
using Microsoft.SharePoint; 
using Microsoft.SharePoint.Publishing; 
using System.Linq; 

namespace YourCompany.SharePoint.Sites.MySites 
{ 
 [Guid("cd93e644-553f-4486-91ad-86e428c89723")] 
 public class MySitesProvisionerReceiver : SPFeatureReceiver 
 { 
 private const string MySiteCreated = "MySiteCreated"; 
 private const string ResourceFile = "MySiteResources"; 
 private const uint _lang = 1033; 

 public override void FeatureActivated(SPFeatureReceiverProperties properties) 
 { 
 using (SPWeb web = properties.Feature.Parent as SPWeb) { 
 //run only if MySite hasnt been created yet as 
 //feature could be run after provisioning 
 if (web.Properties.ContainsKey(MySiteCreated)) return; 
 ActivatePublishingFeature(web); 
 SetUpMySite(web);          
 } 
 }
 
 private void ActivatePublishingFeature(SPWeb web) { 
 //Activate Publishing Web feature as the stapler does not do 
 //this consistently in a farm (stapler works fine in a single server setup) 
 try 
 { 
 web.Features.Add(new Guid("94C94CA6-B32F-4da9-A9E3-1F3D343D7ECB"));          
 } 
 catch (Exception) 
 { 
 //already activated 
 } 
 }
 
 private void SetUpMySite(SPWeb web) {          
 //turn off versioning, optional but keeps it easier for users 
 //as they are the only users of their MySite home page  
 var pubWeb = PublishingWeb.GetPublishingWeb(web); 
 var pages = pubWeb.PagesList; 
 pages.EnableVersioning = false; 
 pages.ForceCheckout = false; 
 pages.Update(); 
 
 //set custom masterpage 
 var customMasterPageUrl = 
 string.Format("{0}/_catalogs/masterpage/CustomV4.master", 
 web.ServerRelativeUrl); 
 web.CustomMasterUrl = customMasterPageUrl; 
 web.MasterUrl = customMasterPageUrl; 
 var layout = pubWeb.GetAvailablePageLayouts().Cast<PageLayout>()
 .Where(p => p.Name == "HomePage.aspx").SingleOrDefault();   
 
 //set default page 
 var homePage = pubWeb.GetPublishingPages().Add("Home.aspx", layout); 
 homePage.Title = "Home Page"; 
 homePage.Update(); 
 pubWeb.DefaultPage = homePage.ListItem.File;          
 
 //Add initial webparts 
 WebPartHelper.WebPartManager(web, homePage.ListItem.File.ServerRelativeUrl, 
 Resources.Get(ResourceFile, "MySiteSettingsListName", _lang), 
 Resources.Get(ResourceFile, "InitialWebPartsFileName", _lang)); 
 web.AllowUnsafeUpdates = true; 
 web.Properties.Add(MySiteCreated, "true"); 
 web.Properties.Update(); 
 pubWeb.Update(); 
 
 //set the search centre url 
 web.AllProperties["SRCH_ENH_FTR_URL"] = 
 Resources.Get(ResourceFile, "SearchCentreUrl", _lang); 
 web.Update(); 
 
 //delete default page 
 var defaultPageFile = web.GetFile("Pages/default.aspx"); 
 defaultPageFile.Delete(); 
 web.AllowUnsafeUpdates = false; 
 } 
 } 
}

In Part 2 we will look at the Static method WebPartHelper.WebPartManager(SPWeb web, String homePageUrl, String documentLibraryName, String xmlDocumentName) which will add our webparts.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: