aarebrot.net Frode's blog on Sharepoint and other stuff

Activating a customized Master Page with a feature using a sandboxed solution in SharePoint 2010

Posted on October 15, 2010
VN:F [1.9.22_1171]
Rating: 4.0/5 (5 votes cast)

The out-of-the-box look and feel of SharePoint 2010 is a lot nicer than the 2007 version. Be that as it may be, you still might want to customize your site collections. I've been looking into a quick and easy way to do this using a feature in a sandboxed solution and I'm happy to say it's not very hard.

There's a few things we need for this to work. First create a new empty sandbox solution. Then add two new Modules to it. Name the first CustomMasterPage and the second CustomStyles (or something along those lines). A new feature should be created automatically, and you should probably change the name of that as well.

Both your modules should have been created with an Elements.xml file and a Sample.txt file. In the CustomMasterPage module, rename the Sample.txt to Custom.master. In the CustomStyles module, rename the Sample.txt file to CustomStyles.css.

Now what we want to do is to use modules to load the files into SharePoint libraries, and use the files from there. This way we can build the solution as a sandboxed solution. At first I tried to put the files in the Layouts folder, but you're going to need to use a farm solution to do that.

Open up the Elements.xml for your CustomMasterPage module. We have to reference the library that we want to put the Custom.master file in. We do this simply by adding a few attributes to the Module tag.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="CustomMasterPage" List="116" Url="_catalogs/masterpage">
    <File Path="CustomMasterPage\Custom.master" Url="Custom.master" Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE" />
  </Module>
</Elements>

Note that the List attribute it 116, which corresponds to the list template ID of the Master Page Gallery library. The Url attribute points to the URL where the library is stored. For the file itself we want to change URL to be in the root of the library. We also want the file to be ghostable, and we don't want to ignore the file if it already exists (in case we update the feature, for example).

You also need to update the Custom.master and it's content. I just did a proof of concept and copy and pasted the default Master Page which is named v4.master. You can find this file in the %ProgramFiles%\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\GLOBAL directory. I then did some minor changes to the file, to make sure SharePoint was using my file, instead of the default file.

On line 20 and 21 I added the following:

  1. <title id="onetidTitle"><asp:ContentPlaceHolder id="PlaceHolderPageTitle" runat="server"/></title>
  2.     <SharePoint:CssLink runat="server" Version="4"/>
  3.     <!-- Adding our CSS -->
  4.     <link href="/Style Library/CustomStyles.css" rel="stylesheet" type="text/css"/>
  5.     <SharePoint:Theme runat="server"/>
  6.     <SharePoint:ULSClientConfig runat="server"/>

Then further down on what is now line 374 I added this:

  1. <div id="s4-mainarea" class="s4-pr s4-widecontentarea">
  2.             FOO BAR MASTER PAGE YEAH!!!
  3.                 <div id="s4-leftpanel" class="s4-notdlg">

By adding the link to the custom css file we can now a lot of the branding aspect of the Master Page. This is handy if you want to change some colors to better fit the organization, or if you want to completely redesign the look and feel. The second change is just to demonstrate that you can change the markup itself. In the real world you'd probably create a master page from scratch if you're redesigning the look and feel.

On to the CustomStyles. We need to make some changes to it's Elements.xml file, so open that up. Basically we need to tell it where to put our custom css file. We're going to stick it in the Style Library, because you know... That's where Styles should go. You could really put it anywhere you want. So it should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="CustomStyles" Url="Style Library">
    <File Path="CustomStyles\CustomStyles.css" Url="CustomStyles.css" Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE"/>
  </Module>
</Elements>

So we're pretty much doing the same thing here that we did with the other elements file. Use the Url attribute to point to the Style Library. Change the Url attribute of the File tag to CustomStyles.css and also add the Type and IgnoreIfAlreadyExists attributes with their respective values.

Next let's update the CustomStyles.css to something that'll make our page a little more exciting. Open it up and replace it's contents with this:

body #s4-ribbonrow
{
    background-color: Red;
}

That should set the dark blue background on the top of the page to red once we load our new Master Page.

Ok, we're almost there. I promise. The last thing we need to do is to make the Site Collection use the Master Page when we activate the feature. Right click your feature and add an Event Receiver. Creating Event Receivers in 2010 isn't all that different from creating event receivers in 2007. Except that 2010 helps you out by doing most of the iffy stuff for you. You pretty much only need to worry about the code you want to write.

Anyway. Open up the code file for your event receiver and let's walk through what we need to do. Basically, when the feature is activated we want to open up a reference to the Site Collection and get the root web. Then we want to set the Master Page to be our new one, instead of the old one. When the feature is deactivated, we want to set it back to the default master page. Because that's the nice thing to do.

Here's the code I came up with:

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;

namespace ReplaceMasterPage.Features.CustomMasterPage
{
    [Guid("b33dcf15-6e5e-44cc-aa7d-eef2424b8ddb")]
    public class CustomMasterPageEventReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPSite site = properties.Feature.Parent as SPSite;
            SPWeb rootWeb = site.RootWeb;

            Uri masterUri = new Uri(rootWeb.Url + "/_catalogs/masterpage/FooBar.master");

            rootWeb.MasterUrl = masterUri.AbsolutePath;
            rootWeb.CustomMasterUrl = masterUri.AbsolutePath;
            rootWeb.Update();
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPSite site = properties.Feature.Parent as SPSite;
            SPWeb rootWeb = site.RootWeb;

            Uri masterUri = new Uri(rootWeb.Url + "/_catalogs/masterpage/v4.master");

            rootWeb.MasterUrl = masterUri.AbsolutePath;
            rootWeb.CustomMasterUrl = masterUri.AbsolutePath;
            rootWeb.Update();
        }
    }
}

And that should be all we need. If we deploy the solution it should upload the new Master Page and put it in the Master Page Gallery. It should also upload the CustomStyles.css file and put that in the Style Library. Finally it will activate the feature which will replace the default selected Master Page for the site collection with out custom one.

The front page with a custom Master Page applied

The front page with a custom Master Page applied

If you deactivate the feature, it should return back to the default Master Page.

The front page after the custom Master Page feature has been disabled

The front page after the custom Master Page feature has been disabled

This is just a quick example but it should get you going in the right direction.

Activating a customized Master Page with a feature using a sandboxed solution in SharePoint 2010, 4.0 out of 5 based on 5 ratings
Comments (5) Trackbacks (0)
  1. Thanks for the info

  2. Does it apply the feature to subsites also ???

    • If your sub sites are set to inherit the master page of it’s parent, then yes.

      If your sub sites are set to not inherit the master page from it’s parent, then no.

  3. Unfortunately using a feature to activate a new master page does not work in Visual Studio. You still need to go into SP Designer to set the new master page. When deploying via Visual Studio, an error “File does not exist” is thrown. This renders the site inoperable and can only be fixed in SP Designer.


Leave a comment

 

No trackbacks yet.