Monday, 10 March 2008

How to customise the SharePoint application.master file

Complete with source code.

So you want to customise your site. You create a master page; you even create your own theme. Just look at your perfect, beautiful site. Then you realise that every time you view a page in the layouts directory your master page is ignored.

This is because all these pages use the /_layouts/application.master master page. So how does one change this setting? In short the answer is you don't. Microsoft do describe two methods for cusomising application pages in the Layouts folder but both are lacking. Each method has advantages and over the other but neither satisfy my requirements.

I'd like to be able to
  • specify an alternate master page for any site (SPWeb) and have all sub-webs inherit the master page
  • configure the url to the master page via the UI
  • still use the uncustomised version of the application.master file


There are several components to the solution of this issue which can be download at the end of this post (including source code).

Changing the Master Page
In order to change the master page we need a way to check every page requested to see if we need to change the master page. To do this we will use a HttpModule. This will allow us to inspect the page being requested and if required attach an event to modify the master page.

The HttpModule will get the page handler and check the MasterPageFile property to see if it is set to the application.master. If it is, it will check the current web's property bag to see if an alternate master page has been specified. If no alternative is set, it will check the parent webs and inherit the setting. If an alternate is found an event handler will be attached to the page's init event that will then change the master page.

Configuring the Master Page
A custom action will be used to create a link in the Site Administration section of the site settings page. This will load a new application page that allows a site admin to set the alternate url for the master page that will be stored in the current web's property bag.

Sticking it all together
Nobody likes fixes that require manual changes to the file system and to the web.config files, so the aim is to create a single web application feature the can be installed, deployed and activated. The HttpModule requires modifications to the web.config file, this will be handled via a feature receiver that applies the web config modifications.

The feature will also install the application page that allows the site administrator to modify the URL to the alternate master page and add a link to the page into site settings under the Site Administration section.

To try this solution download the SharePoint solution file and install and deploy it on your farm. In Central Administration go to Manage Web Application Features and activate the Application Master Page feature on the required web application. After doing this if you go to the site settings page of any site on the web application you will see an Application Master Page link. Change the url to the location of your new master page.

Finally the Master Page
To test this solution you may wish to simply copy the application.master and make a small alteration so that you can see the difference. My recommendation for a full solution would be to create master pages using the application.master file as a template and deploy them to the layouts folder as part of your solution.

Download the solution here seed.hf2.wsp.

Download the source code here seed.hf2.zip

Please leave a comment if you found this post helpful or if you have any suggestions on how to improve it.

12 comments:

Stephen K said...

Sorry everybody. I'd missed out the dll in the ddf file and the solution manifest file.

If you tried to install the wsp you may have received a File not found exception.

If you downloaded the solution it will have worked because of a post build script but I would still urge you to get the latest version.

Download from the links above.

Charlie said...

I figued out my problem. I needed to activate it using stsadm. After that it showed up.

When I set the new master page, it changes the master page for the site settings site, not the site that I'm trying to set the settings for.

For example, I'm on site http://localhost:1111/default.aspx, I go to site settings which is http://localhost:1111/_layouts/settings.aspx. I change to Application 2.master and Application2.master is being used for http://localhost:1111/_layouts/settings.aspx, but not for http://localhost:1111/default.aspx.

What I ultimately want to do is set it up so all pages within a site collection use the same custom master page and custom theme. When a new site is created in the collection, I want that new site to use the master page and theme too.

This seems like something a lot of people would want to be able to do and I'm surprised SP doesn't have this built in. Make the entire site look the same.

I've been able to do bits and pieces but I haven't found a comprehensive solution.

Stephen K said...

This post only addresses this issue of modifying the application master page as there is no standard functionality in SharePoint to achieve this. What you will also need to do to is change the CustomMasterUrl and MasterUrl attribute of the SPWeb object have a look at Heather Solomon's Blog.

I would like to point out though that you will probably need to create a seperate master pages for this.

One based on the default.master file in the GLOBAL directory of the 12 hive and one from the application.master in the layouts folder.

Ian said...

Awesome mate, this helped me a lot!

Clayton said...

Hi there.
Where would you recommend I save my customised application.master file...? Would it be alright to have it in the Master Page Gallery with the rest of the site master pages...??? Or does it need to be in the same area as the original application.master...?

Thanks

Stephen K said...

I would lean towards saving this in a folder in the layouts folder under the 12 hive.

There are a few reasons why, mainly with regards to security, availability to the application and also this would remove the ability for privileged users to alter the custom application master page.

However if you're comfortable with "super users" editing this file you may prefer to put it in the master page gallery. At least this way you'd have version control, approval workflow etc etc.

Anonymous said...

Did I miss a step? I change the newly created newapplication.master after pointing to it and _layouts pages don't look any different. I even gutt the file or specify a non existent file and no reaction or change?

Looks very promising.

One question I have is how different will the application.master and default.master be?

Stephen K said...

It appears the wsp file was out of sync with the source code. I've rebuilt the wsp, tested it and uploaded it.

Try downloading and reinstalling the solution. The problem should be fixed.

As with the default.master file the application.master has it's own minumum requirements; it has it's own placeholders that are required.

Anonymous said...

Hello Again, I posted the last Anonymous entry about having missed at step. I was at home on my lab install. This will sound odd, but somehow changes would not take affect and then suddenly changes to the copy of the Application.master just started working. Like 3 minutes after deployment.

I'm at work now on a much more complicated Topology. I just deployed your solution and activated it. I started to compare the Application.master to the default.master and they look the same (at a glance). Then I thought wouldn't it be grand if I could use your great solution to just point to /_catalogs/masterpage/newdefault.master and then it dawned on me .. where is /_catalogs .. hell (sorry) it's in the database.

Well I'm trying this and it's not taking it for Application.master.. but wondering about this mornings Odd delay.

Can I do this? Are the files compatible enough and is that db driven location even available when application.master loads.

Oh, BTW - great solution regardless. MS is great, but they leave these giant opportunties out there like this.

JC

Simon King said...

Hi

This looks like a really neat solution and if I add it to my current feature I can provide a really simple deployment approach.

The only question really is will Microsoft support sites where this is used.

I did a lot of work on WSS 2.0 sites that subsequently became unsupported. So in the upgrade of these sites I'm really keen that the customisations and web parts are supported by MS.

Thanks though very helpful.

Stephen K said...

I'm pretty sure that /_catalogs would be avaiable but I'd appreciate it if you let me know how you get on.

As for the delay in the application master I think this may be down to the app pool needing to be recycled for the module to be picked up.

Stephen K said...

Is this supported by Microsoft? Is a very good question. I've not found anything suggesting that it wouldn't be as this method means you do not alter any of the app files in the 12 hive.

However, Im not qualified to give a definitive answer to this question.