Sunday, October 26, 2008

Programmatically uploading master pages to master pages gallery in MOSS 2007

We recently had a requirement to set a custom master page to a blog site when blog site is created in Microsoft Office SharePoint Server (MOSS) 2007. There are couple of things we had to consider:
  • blog is a separate website with its own Master Pages gallery
  • the master page must be uploaded to blog's Master Pages gallery as soon as blog website is created
  • uploaded master page must be assigned to blog as soon as blog website is created
  • regular users (non-administrators) should be able to create blog websites

We decided to use "feature-stapling" mechanism in MOSS to be able to get notified when a new blog website is created and to be able to performed the required operations. I will not write about the feature-stapling mechanism in this blog post because it is fully covered in other blog posts (like in: http://www.sharepointnutsandbolts.com/2007/05/feature-stapling.html).

We made a custom master page, put it in a folder on file system of a MOSS server and added one feature property to hold full path to master page.

Out class that will handle master page uploading and assigning inherits from SPFeatureReceiver class and the method that peforms required operations executes in elevated privileges context.

Next listing shows the code that performs above mentioned operations:




private void UploadMasterPage(string pathToBlogMasterPage, SPWeb web)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite blogSite = new SPSite(web.Site.Url))
{
using (SPWeb blogWeb = blogSite.OpenWeb(web.ID))
{

byte[] contents = null;
using (Stream fStream =
File.Open(pathToBlogMasterPage, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
contents = new byte[fStream.Length];
fStream.Position = 0;
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
}

//We need to extract a server relative URL of current web
string webRelativeUrl = web.Site.ServerRelativeUrl + web.Url.Replace(web.Site.Url, "");
string url = webRelativeUrl + "/_catalogs/masterpage/" + BlogCustomMasterpage;

SPFile currentFile = web.Files.Add(url, contents);
web.MasterUrl = web.MasterUrl.Replace(BlogDefaultMasterpage, BlogCustomMasterpage);
web.CustomMasterUrl =
web.CustomMasterUrl.Replace(BlogDefaultMasterpage, BlogCustomMasterpage);
web.Update();
}
}
});
}


NB: pathToBlogMasterPage is extracted from SPFeatureReceiverProperties instance and web is an instance of SPWeb that represents the newly created blog website.

No comments: