tags:

views:

2651

answers:

2

Does anyone know how to customize the master page (i.e. default.master) for a WSS 3.0 site? Actually, I already know how to customize the master page (i.e. via SharePoint Designer, or a text editor), I'm more interested in learning how to tell WSS 3.0 to use my customized master page.

I've renamed the default.master with my customized version and that works, but that sets it for all WSS sites. I want to be able to use version A of a master page for site collection A, and a separate master page for other site collections.

Note, I'm NOT referring to MOSS 2007. I already know how to set the master page for MOSS 2007. I can't seem to figure out how to do it for WSS 3.0 though.

Thanks.

+2  A: 

WSS pages use Master Pages just like regular web apps. However, the value if the MasterPageFile attribute is a token, and is set to "~default.master". This token gets replaced with the actual reference to the master page in the page's PreInit method.

You can change the value of ~default.master to anything you like. But a better solution is to do the same type of thing that SharePoint does.

I added an HttpHandler to my SharePoint site. The handler attaches to the PreRequestHandlerExecute method, and changes the value of the master page file attribute before SharePoint starts rendering the page.

Add a line to the httpModules section of the web.config that looks like this:

Then create a class like this:

namespace MyClassLibrary.Utility { public class MasterPageHttpModule : IHttpModule { public void Init(HttpApplication context) { context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); }

    void context_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        bool useCustomMasterPages = Convert.ToBoolean(ConfigurationManager.AppSettings["ShowCustomMasterPages"].ToString());
        if (useCustomMasterPages)
        {
            Page page = HttpContext.Current.CurrentHandler as Page;
            if (page != null)
            {
                page.PreInit += new EventHandler(page_PreInit);
            }
        }
    }

    void page_PreInit(object sender, EventArgs e)
    {
        bool useThreeColumnMaster = Convert.ToBoolean(ConfigurationManager.AppSettings["UseThreeColumnMasterOnDefaultPage"].ToString());

        try
        {
            Page page = sender as Page;
            if (page != null && SPContext.Current != null)
            {
                string url = page.Request.Url.AbsolutePath.ToLower();
                if (url.IndexOf("/public/") > -1)
                {
                    if (url.IndexOf("sitemap.aspx") == -1)
                    {
                        page.MasterPageFile = "~/_catalogs/masterpage/edge_con.master";
                    }
                    else
                    {
                        page.MasterPageFile = "";
                    }
                }
                else if (url.IndexOf("default.aspx") > -1)
                {
                    if (useThreeColumnMaster)
                    {
                        page.MasterPageFile = "~/_catalogs/masterpage/edge_con.master";
                    }
                    else
                    {
                        page.MasterPageFile = "~/_catalogs/masterpage/edge.master";
                    }
                }
                else if (url.IndexOf("sitemap.aspx") > -1)
                {
                    //
                    //  Sitemap pages should not have a master page
                    //
                    page.MasterPageFile = "";
                    page.Controls.Clear();
                }
                else if (url.IndexOf("/admin/") > -1)
                {
                    page.MasterPageFile = "~/_catalogs/masterpage/edge.master";
                }
                else if (url.IndexOf("/member/") > -1)
                {
                    page.MasterPageFile = "~/_catalogs/masterpage/edge.master";
                }
                else if (url.IndexOf("/supplier/") > -1)
                {
                    page.MasterPageFile = "~/_catalogs/masterpage/edge.master";
                }
                else if (page.MasterPageFile == "~masterurl/default.master")
                {
                    page.MasterPageFile = "~/_catalogs/masterpage/edge.master";
                }
            }
        }
        catch (Exception exception)
        {
            LogWriter logWriter = new LogWriter();
            logWriter.WriteToLog("Could  not set master page: " + exception.Message, LogType.MasterPage, DateTime.Now);
        }
    }

    public void Dispose()
    {
    }
}

}

Now you are dynamically choosing a mater page.

Bill
+2  A: 

You need to change the MasterUrl property on the SPWeb object representing the site. A good way to do this is to create a SharePoint feature that when activated sets the property, and when deactivated restores the original value. The Feature.xml could look like this:

<?xml version="1.0" encoding="utf-8"?>
<Feature  Id="8651CC66-FEB1-4255-B7E9-0DFE24367DAB"
          Title="My Master Page"
          Scope="Web"              
          SolutionId="06D3B01F-0C26-457a-BFA5-A1B0BC8D4225"
          ReceiverAssembly="MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9e95445247029289"
          ReceiverClass="MyFeatureReceiver"
          xmlns="http://schemas.microsoft.com/sharepoint/"&gt;
  <ElementManifests>
    <ElementManifest Location="Masterpage.xml"/>
    <ElementFile Location="my.master"/>
  </ElementManifests>
  <Properties>
    <Property Key="MyMaster" Value="my.master" />
  </Properties>
</Feature>

The file Masterpage.xml uploads your master page to the gallery:

 <?xml version="1.0" encoding="utf-8" ?>
 <Elements xmlns="http://schemas.microsoft.com/sharepoint/"&gt;
   <Module Name="UploadMaster" Url="_catalogs/masterpage" >
     <File Url="my.master" Type="GhostableInLibrary" IgnoreIfAlreadyExists="True"/>
    </Module>
 </Elements>

Include this feature in a WSP solution along with the MyAssembly.dll containing the MyFeatureReceiver class, which goes like this:

public class MyFeatureReceiver : SPFeatureReceiver
{
  public override void FeatureActivated(SPFeatureReceiverProperties properties)
  {
    SPWeb web = (SPWeb)properties.Feature.Parent;
    web.MasterUrl = properties.Definition.Properties["MyMaster"].Value;
    web.Update();      
  }

  public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
  {
    SPWeb web = (SPWeb)properties.Feature.Parent;
    web.MasterUrl = "default.master";
    web.Update();      
  }

  public override void FeatureInstalled(SPFeatureReceiverProperties properties)
  {
  }

  public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
  {
  }
}

Finally, deploy the solution and activate the feature on your site(s).

Lars Fastrup