What Me Pa..Panic?

All MindsharpBlogs

Paul Papanek Stork

My Links

Post Categories

Archives

Blog Stats

2007 Speaking Engagements

2008 Speaking Engagements

Feature to Install a Custom Master Page

A former student brought an excellent BLOG post that Heather Solomon made last October (http://www.heathersolomon.com/blog/articles/servermstpageforsitecollect_feature.aspx) to my attention recently.  Heather demonstrated how to create a Feature that could be used to install a Custom Master Page for a Site Collection.  There was however one limitation to the approach that Heather used, it could only be used on a Site where the Publishing Feature was enabled.  My student wondered if there was a way to do something similar for regular WSS Team Sites.

Normally, I teach students how to do this by planning ahead and creating or modifying Site Definitions BEFORE you create the Site Collection and Top Level Site.    The MasterUrl and CustomMasterUrl attributes represent two replaceable parameters that can be used to set the Masterpage attribute of the @Page declaration on the pages of a SharePoint site.  “Out of the Box“ .aspx pages point to a Masterpage at ~/masterurl/default.master. This will be replaced at runtime by the MasterUrl property of the Website.  The default setting for this is _catalogs/masterpage/default.master.  This is the default.master file in the Master Pages gallery of the website.  Until you edit this file using SharePoint Designer it will point to a ghosted copy of the file in the TEMPLATE\GLOBAL directory of the 12 hive.  You can also ghost custom .Master files from your Site Definition directory into the Masterpage gallery of the site using a Module Element.  Then you can set the MasterUrl and/or CustomMasterUrl attributes of the Configuration Element in the ONET.xml file to point at these ghosted .Master files.  If you also change the @Page directive of the .aspx files on your site to use ~/masterurl/custom.master you will establish a hierarchy of master pages that will be used.  The page will first try to use the customMasterUrl setting, then the masterUrl setting, and finally the default.master file in GLOBAL. 

Making these changes later will NOT result in a change to existing Sites, but you can also set the MasterUrl and CustomMasterUrl properties of a Website programmatically.  So I reasoned it would be possible to create an Event Handler that would fire when a Feature was activated to set these properties and then move the .Master files using a Feature Module.  Activating this Feature on a site would accomplish the same changes outlined above by a custom site definition.  Here's how it can be done.

First, we need a Feature.  To create our Feature we need a Subdirectory Called CustomMaster in the TEMPLATE\FEATURES directory of the 12 hive.  Then we need add 4 files to this directory:  Feature.xml, Elements.xml, Custom.master, and myDefault.master.

FEATURE.XML - This file is used to identify the feature and list out the items that will be part of the Feature.  Our Feature will include an assembly that will contain code to run in response to Feature events and an Elements.xml file.  The code for our Feature is listed below:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="
http://schemas.microsoft.com/sharepoint/"
         Id="90969656-A1C9-4f40-A95F-A3BDDF5723BF"
         Title="Use Custom Master File"
         Scope="Web"
         ReceiverAssembly="CustomMaster, Version=1.0.0.0,
             Culture=neutral, PublicKeyToken=bcee0f83b26fbb16"
         ReceiverClass ="CustomMaster.ChangeMaster" >
    <ElementManifests>
        <ElementManifest Location="Elements.xml"/>
    </ElementManifests>
</Feature>

ELEMENTS.XML - In this file we will identify two .Master files that will be ghosted to the masterpages gallery of the site.

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="
http://schemas.microsoft.com/sharepoint/">
    <Module Name="AddMasters" Url="_catalogs/MasterPage" >
        <File Url="MyDefault.master" Type="GhostableInLibrary"
          IgnoreIfAlreadyExists="True">
          <Property Name=“ContentType” 
            Value=“$Resources:cmscore,contenttype_masterpage_name;" />
        </File>
        <File Url="custom.master" Type="GhostableInLibrary"
          IgnoreIfAlreadyExists="True"/>
         
<Property Name=“ContentType” 
            Value=“$Resources:cmscore,contenttype_masterpage_name;" />
        </File>
  </Module>
</Elements>

 MYDEFAULT.MASTER and CUSTOM.MASTER - These are copies of the default.master file from the TEMPLATE\GLOBAL directory of the 12 hive.  If your .aspx page references the master file ~/masterUrl/default.master then myDefault.master will be used.  If you reference ~/masterUrl/custom.master then Custom.Master will be used.  WARNING: Do not use SharePoint Designer to edit files stored in the 12 hive.  This would break the files.

The last piece of the Feature is a Feature event handler that will be used to modify the masterUrl and customMasterUrl properties of the Website programatically.  The event handler will set the properties when the Feature is activated and reset them to the default when the Feature is deactivated.  The code for the event handler is listed below:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace CustomMaster
{
    public class ChangeMaster:Microsoft.SharePoint.SPFeatureReceiver
    {
        public override void FeatureInstalled
          (SPFeatureReceiverProperties properties)
        {
        }
        public override void FeatureUninstalling
           (SPFeatureReceiverProperties properties)
        {
        }
        public override void FeatureActivated
           (SPFeatureReceiverProperties properties)
        {
            SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
            CurrentWeb.MasterUrl = "/_catalogs/masterpage/MyDefault.master";
            CurrentWeb.CustomMasterUrl = "/_catalogs/masterpage/custom.master";
            CurrentWeb.Update();
        }
        public override void FeatureDeactivating
           (SPFeatureReceiverProperties properties)
        {
            SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
            CurrentWeb.MasterUrl = "/_catalogs/masterpage/default.master";
            CurrentWeb.CustomMasterUrl = "/_catalogs/masterpage/default.master";
            CurrentWeb.Update();
       }
    }
}

Once the event handler has been compiled and added to the Global Assembly Cache and the Feature directory has been created you can Install and Activate the Feature.  To install the Feature use the following command line:

stsadm -o installfeature -n CustomMaster

Then you can go to the Site Features link in SiteSettings on any SharePoint website and activate the Feature.  Every website where the Feature is activated will use the myDefault.master stored in the Feature as its .master file.  If you modify the @Page declaration of a page on the site to use ~/masterUrl/Custom.master then the Custom.master will be used.

*** Updated July 3, 2008 ***

Noticed recently that I left one line out of the Elements.xml file which prevented the feature from working in Site Collections where Publishing was turned on.  In those sites the master pages gallery contains two content types so you have to specify what type of file you are "ghosting" with your <Module>.  The Code that was added is marked in RED above.

posted on Monday, June 18, 2007 10:05 PM

Feedback

# Replacing the search bar 10/4/2007 4:22 AM Mirrored Blogs

In this particular case, a customer already has a enterprise search engine so it wouldn&#39;t make sense

# re: Feature to Install a Custom Master Page 10/9/2007 4:56 AM Shailesh

Hi,
I am creating web application and site programatically and facing error in below code.

SPWebApplicationBuilder webAppBuilder = new SPWebApplicationBuilder(SPFarm.Local);
SPWebApplication newApplication = webAppBuilder.Create();
newApplication.Provision();
SPSite NewSite = newApplication.Sites.Add(SiteURL, SiteCollectionName, SiteCollectionName, 1033, SiteCustomTemplate, SiteOwnerLogin, SiteOwnerLogin, SiteOwnerEmail);


Creation of site throws error as,

"Failed to instantiate file "default.master" from module "DefaultMasterPage": Source path "default.master" not found."

Any guess about this error?

# re: Feature to Install a Custom Master Page 10/18/2007 10:41 AM Paul Stork

I suspect your error is caused by timing since the feature both copies the master file and changes the setting.

If you are creating the site programatically than I assume you have added the feature to a custom site definition. Instead of doing that you should change the masterurl attribute of the <Configuration> element and use a custom <Module> to move the file to the gallery. The Feature was written to duplicate that functionality for sites that are already provisioned.

# re: Feature to Install a Custom Master Page 12/30/2007 10:09 PM Ryan

I got this to work and it will apply changes to collaboration site, but if I try to activate the feature on a publishing site, I get a File Not Found error.

Any idea why that would be happening?

# re: Feature to Install a Custom Master Page 1/28/2008 10:38 AM Paul Stork

Publishing sites provide an inheritance structure for master pages, so every sub site looks to the top level site gallery for its master page. Using this feature to try to override that process will install the master page in a local gallery, but because of the inheritance in publishing you won't be able to find the new master page because its in the wrong gallery.

# re: Feature to Install a Custom Master Page 3/5/2008 3:48 AM ducclo

i have done this follown you, but when i click "Site feature" i see only "Team collabotion list"
not my feature, in my system i creat feature.dll in Gac , can you help me

# re: Feature to Install a Custom Master Page 3/9/2008 9:07 AM Paul Stork

Double check to make sure you have deployed the folder containing the Feature.xml and elements.xml to the 12 hive. Then make sure you ran STSADM -o installfeature ... to install your feature.

# re: Feature to Install a Custom Master Page 3/14/2008 3:02 AM ducclo

thank you , i have done this
it's great

# Cafe PayLaşım 9/28/2008 1:31 PM PayLaşım

Thanks

# re: Feature to Install a Custom Master Page 10/8/2008 12:10 AM abby

hi ive done this and it worked. however, when i create a new site collection and a new site under it - activated the feature, i got File Not Found. any idea? Thanks

# re: Feature to Install a Custom Master Page 10/17/2008 11:09 AM Paul Stork

I suspect that you are trying to use the feature on a child site of a Publishing site collection. The problem is that publishing has changed where sites look for their master pages. The Feature loads the new masterpage into the local site's masterpage gallery, but Publishing causes the site to look for the master page in the top level site's masterpage gallery. Try changing the code of the Feature receiver to force the site to load the page from its local master page gallery by adding the ServerRelativeUrl property of the SPWeb object to the front of the '_Catalogs/masterpage/...' address. This will make the Feature look in a specific place.

# Consolidating Master Pages Customized By SharePoint Designer 11/3/2008 4:24 PM Phil Wicklund

# re: Feature to Install a Custom Master Page 11/20/2008 4:40 AM sesli sohbet

thank you saolujn

Title  
Name  
Url
CAPTCHA
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments