Main Menu
Home
News
Links
Contact Us
Search
Steve's Blog
Erica's Blog
Pictures
Downloads
Guitar Music
SharePoint
Who's Online
We have 18 guests online


Using your SharePoint site Master Page on all application pages PDF Print E-mail
Written by Steve Lineberry   
Saturday, 25 August 2007
Article Index
Using your SharePoint site Master Page on all application pages
Page 2

So I found this article, http://weblogs.asp.net/soever/archive/2006/11/14/SharePoint-2007_3A00_-using-the-masterpage-from-your-site-in-custom-_5F00_layouts-pages.aspx, which explains how to use your SharePoint site's master page when you create a custom application page in the _layouts virtual directory. At this point in time I don't really have any custom application pages yet but I liked the idea of when I theme a site that all pages, including application pages in the _layouts virtual directory, use the same master page. By default all application pages use the application.master master page. After finding this article, http://www.odetocode.com/Articles/450.aspx, and a lot of playing around I believe I have found a solution. I created a HttpModule that on a page's preinit, it checks to see if the page is in the _layouts virtual directory, and if so, it will assign it the master page url from the current sharepoint site. Here's my code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using Microsoft.SharePoint;

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

	void context_PreRequestHandlerExecute(object sender, EventArgs e)
	{
		Page page = HttpContext.Current.CurrentHandler as Page;
		if (page != null)
		{
			page.PreInit += new EventHandler(page_PreInit);
		}
	}

	void page_PreInit(object sender, EventArgs e)
	{
		Page page = sender as Page;
		if (page == null) return;
		if (page.MasterPageFile == null) return;
		HttpContext context = HttpContext.Current;
		string currUrl = context.Request.Url.ToString();
		string basepath = currUrl.Substring(0, currUrl.IndexOf(context.Request.Url.Host) + context.Request.Url.Host.Length);
		//Use RawUrl, otherwise it will always use the root web.
		currUrl = context.Request.RawUrl;
		if (currUrl.ToLower().Contains("/_layouts/") &&
			page.MasterPageFile.ToLower().EndsWith("application.master"))
		{
			currUrl = currUrl.Substring(0, currUrl.ToLower().IndexOf("/_layouts/"));
			SPSite site = null;
			SPWeb web = null;
            try
            {
				site = new SPSite(basepath + currUrl);
				web = site.OpenWeb(currUrl);

				if (String.IsNullOrEmpty(web.MasterUrl) == false)
	            {
					page.MasterPageFile = web.MasterUrl; 
					page.Load += new EventHandler(page_Load);
				}
			}
            finally
            {
                if (web != null)
                {
                    web.Dispose();
                }
                if (site != null)
                {
                    site.Dispose();
                }
            }
		}
	}

	public void Dispose()
	{
	}

	void page_Load(object sender, EventArgs e)
	{
		Page page = sender as Page;
		if (page == null) return;

		try
		{
			ContentPlaceHolder placeHolderTitleBreadcrumb = page.Master.FindControl("PlaceHolderTitleBreadcrumb") as ContentPlaceHolder;
			SiteMapPath contentMap = placeHolderTitleBreadcrumb.FindControl("ContentMap") as SiteMapPath;
			contentMap.CssClass = "ms-hidden";
		}
		catch { }

		try
		{
			ContentPlaceHolder placeHolderSearchArea = page.Master.FindControl("PlaceHolderSearchArea") as ContentPlaceHolder;
			placeHolderSearchArea.Visible = false;
		}
		catch { }
	}

}


Be sure to register the HttpModule in the web.config of your sharepoint site.

This did require me to add extra contentplaceholders into my default.master. Here are the two extra placeholders I had to add:

PlaceHolderPageDescriptionRowAttr
PlaceHolderPageDescriptionRowAttr2

To add these placeholders into my default.master I replaced the following code:

<PlaceHolder id="MSO_ContentDiv" runat="server">
<table id="MSO_ContentTable" width=100% height="100%" border="0" cellspacing="0" cellpadding="0" class="ms-propertysheet">
<tr>
<td class='ms-bodyareaframe' valign="top" height="100%">
<A name="mainContent"></A>
<asp:ContentPlaceHolder id="PlaceHolderPageDescription" runat="server"/>
<asp:ContentPlaceHolder id="PlaceHolderMain" runat="server">
</asp:ContentPlaceHolder>
</td>
</tr>
</table>
</PlaceHolder>
with
<PlaceHolder id="MSO_ContentDiv" runat="server">
<table id="MSO_ContentTable" width=100% height="100%" border="0" cellspacing="0" cellpadding="0" class="ms-propertysheet">
<TR valign="top" <asp:ContentPlaceHolder id="PlaceHolderPageDescriptionRowAttr" runat="server"/> >
<TD class="ms-descriptiontext" width="100%">
<asp:ContentPlaceHolder id="PlaceHolderPageDescription" runat="server"/>
</TD>
</TR>
<TR <asp:ContentPlaceHolder id="PlaceHolderPageDescriptionRowAttr2" runat="server"/>>
<TD ID=onetidMainBodyPadding height="8px"><IMG SRC="/_layouts/images/blank.gif" width=1 height=8 alt=""></TD>
</TR>
<tr>
<td class='ms-bodyareaframe' valign="top" height="100%">
<A name="mainContent"></A>
<asp:ContentPlaceHolder id="PlaceHolderMain" runat="server">
</asp:ContentPlaceHolder>
</td>
</tr>
</table>
</PlaceHolder>

I also had to change my default breadcrumbs code in the default.master to match the application.master. I replaced the following code:

<asp:contentplaceholder id="PlaceHolderTitleBreadcrumb" runat="server">
	<asp:sitemappath id="ContentMap" runat="server" sitemapprovider="SPContentMapProvider" skiplinktext="" nodestyle-cssclass="ms-sitemapdirectional"></asp:sitemappath>  
</asp:contentplaceholder>

with

<asp:contentplaceholder id="PlaceHolderTitleBreadcrumb" runat="server">
	<asp:SiteMapPath SiteMapProvider="SPXmlContentMapProvider" SkipLinkText="" NodeStyle-CssClass="ms-sitemapdirectional" runat="server"/>
		 
	<asp:SiteMapPath SiteMapProvider="SPContentMapProvider" id="ContentMap" SkipLinkText="" NodeStyle-CssClass="ms-sitemapdirectional" runat="server"/>
</asp:contentplaceholder>

--------------------------------------------------------------------------------------------------

Update (02/23/08): I've changed my default.master and my httpmodule around a lot since posting this. If you don't compile a dll you will need to place the ApplicationMasterPage.cs file in a App_Code directory of your root site and in a App_Code directory at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\IMAGES. You can download my latest files below:

default.master

ApplicationMasterPage.cs

--------------------------------------------------------------------------------------------------

All of the code and changes ended up with a site settings page that looks like this.

Comments
Written by This e-mail address is being protected from spam bots, you need JavaScript enabled to view it on 2009-09-30 12:48:02
The breadcrumb example in your current master page is displayed 2 times on the settings pages have you found a solution to this. Example go to a document library and go to the settings page and the bread crumb is displayed 2 times.
Written by Steve on 2009-11-06 09:31:36
CR, in my latest code which you can download, I have it setup so that the httpmodule should change the css class of the breadcrumb that shouldn't be displayed to ms-hidden which should in effect, hide it. This works in our environment. Please make sure that you are using the latest code from the download links.
Using custom master page with custom log
Written by This e-mail address is being protected from spam bots, you need JavaScript enabled to view it on 2010-02-24 16:25:09
Hi, 
I am trying to use a custom master page with the custom login page I have developed. The login page is deployed in the layouts directory. I am using forms authentication. 
I have followed instruction in your article. But I get 401 error when I try to browse the login page i created. 
Any help is really appreciated.


Write Comment
  • Please keep the topic of messages relevant to the subject of the article.
  • Personal verbal attacks will be deleted.
  • Please don't use comments to plug your web site.. Such material will be removed.
Name:
E-mail
Homepage
Title:
BBCode:Web AddressEmail AddressBold TextItalic TextUnderlined TextQuoteCodeOpen ListList ItemClose List
Comment:



Code:* Code

Powered by AkoComment!



Last Updated ( Wednesday, 10 February 2010 )
 
< Prev   Next >
Latest Blogs
   Home arrow Steve's Blog arrow Using your SharePoint site Master Page on all application pages