Jun 22, 2008

Creating a custom Master Page Template

Creating a custom master page template involves several steps. First, you must create the master page template itself. Second, you must create a custom feature that provisions an instance of this master page template inside the Master Page gallery for a specific site. Finally, you need to add some code to redirect site pages to use your custom master page instead of using default.master. The Visual Studio project named CustomBranding provides a working sample that demonstrates how all of the pieces fit together.

Remember that the CustomBranding feature is scoped to the level of the site collection. While you can create a custom feature scoped at the site level to integrate a custom master page template, it’s better to design such a feature at the site collection level because users typically want branding to occur at this level. It is less convenient if you force users to activate the feature separately for every site within a site collection.

You can create a custom template by using two different approaches. First, you can make a copy of default.master and then modify it according to taste. A second approach involves starting from scratch so that you can design the exact HTML layout you’re looking for. If you start from scratch, be sure to think through which named placeholders you need to include. There are over 30 named placeholders defined inside default.master, and many of the standard site pages, such as default.aspx and AllItems.aspx, assume that whatever master page they link to will have these same named placeholders.

If you forget to include the same set of named placeholders found in default.master, you will likely experience problems. ASP.NET generates errors whenever it finds that a site page references a named placeholder that is not defined in the master page to which it is linked.

The custom master page template used in the CustomBranding project is named Litware.master. The Litware.master template is a variation on the default.master template with changes to allow for fly-out menus on both the top link bar and Quick Launch menu. The CustomBranding feature includes a Module element that has been designed to provision an instance of the Litware.master page template into the Master Page gallery of the top-level site.

            
            
            

            

Note that this Module element has several differences compared with the Module element for provisioning site pages shown earlier in this chapter. While the previous Module was used to provision pages into a site, it did not target a document library. However, this Module targets the Master Page gallery, which is a special type of document library. Therefore, the Module is defined with a List attribute of 116, which is the list type identifier for the Master Page gallery. The Url attribute for this Module is defined with a value of _catalogs/masterpage, which is the standard site-relative path to the Master Page gallery.

If you examine the File element that provisions an instance of Litware.master, you notice that the Type attribute has a value of GhostableInLibrary as opposed to a value of Ghostable that was shown earlier when provisioning site pages inside a site but outside the scope of a document library. A value of GhostableInLibrary should be used whenever you are provisioning an instance of a file, such as a master page template, inside a target document library.

We have reviewed the steps involved in creating a master page template and provisioning an instance of it in the Master Page gallery of the top-level site. The next step involves redirecting all site pages within a site to link to this provisioned instance of our custom master page template. To understand the technique for accomplishing this, take a closer look at the MasterPageFile attribute defined within a Page directive. Examine the following page template, which is defined to link to a target master page by using a special syntax in the form of~masterurl/default.master.

            <%@ Page MasterPageFile="~masterurl/default.master" %>

            
            Custom content goes here
            

            

The value of~masterurl/default.master represents a tokenized reference to a master page that can be changed programmatically on a site-wide basis. The support for tokenized master page references is provided by the SPVirtualPathProvider class. The way things work is that the SPVirtualPathProvider class reads the value of an SPWeb property named MasterUrl at run time and then parses this value into the MasterPageFile attribute of an .aspx file before sending it to the ASP.NET page parser. You can redirect any site page that uses this token by acquiring an SPWeb reference to the current site and then updating the MasterUrl property.

            SPWeb site = SPContext.Current.Web;
            string MasterUrlPath = site.ServerRelativeUrl;
            if (!MasterUrlPath.EndsWith(@"/"))
            MasterUrlPath += @"/";
            MasterUrlPath += @"_catalogs/masterpage/Litware.master";
            site.MasterUrl = MasterUrlPath;
            site.Update();