Dynamically changing MasterPages in SharePoint 2013 when using Device Channels

Suppose you have a public facing website that has about 40 different page layouts. You are also using the Device Channel functionality, which is new to SharePoint 2013. Basically this means you can set multiple MasterPages, one for each device channel you use. But what if you want to have a different MasterPage for one of the page layouts you use. You have to take into consideration, that when updating the MasterPage from the code behind file, the MasterPage is updated for any and all device channels you use. But what if you only want to change the MasterPage for a certain device channel, but keep the default for all others? That’s where this post comes in.

First let’s take a look at how you can change the MasterPage from the code behind file of a Page Layout. This post by Kirk Evans shows you how to deploy a Page Layout and how to create a code behind file for this Page Layout. This post by Eric Overfield gives us a hint on how to change the Masterpage from the code behind file. As noted, you can only change this property in the OnPreInit method, otherwise the MasterPage will have already loaded and changing the property would result in an error message. MSDN shows the following example:

This would however change the MasterPage for all device channels and remember that we only want to change this MasterPage for a specific device channel. This post advices you to use a HttpContext variable that is called ‘EffectiveDeviceChannel’. The post also warns that this property might not be available everywhere because it is loaded on demand. I have tried to use this property, but unfortunately, as you would have guessed, it was not yet available during the OnPreInit method so I had to find a different solution. Browsing the web didn’t do me any good, and since most of the Mobile classes in SharePoint are sealed, those weren’t of any help either. After inspecting the entire HttpContext, there was one property that I could ‘misuse’ and was the solution to my problem. The HttpContext.Current.Items[‘MasterPageUrl’] was there, and it was showing the URL to the MasterPage that was about to be loaded. Since the device channels all have different Masterpages, this became a solution for me to change the MasterPage only for a specific Page Layout. The code used for this is displayed below:

So, when changing the MasterPage from a Page Layout file when also using Device Channels – resort to using the HttpContext variable MasterPageUrl, because the EffectiveDeviceChannel variable is not yet loaded at that point in the life cycle. Gotcha!


Un-ghosted MasterPage; extra type-safe parser check

Last night we came across a strange issue when updating a Publishing sites MasterPage. We have deployed the MasterPage through a SharePoint Feature, and wanted to upgrade the MasterPage. Only a small addition had been made, but because the solution contained a lot more changes that had not been tested yet, we opted to change the MasterPage through SharePoint Designer. We would then, after the solution had been fully tested and upgraded, restore the MasterPage back to the site definition and all would be well. We were wrong.

As soon as we changed the MasterPage through SharePoint designer, the site started throwing ‘The type is not registered as safe’ errors. Which is weird, because we did not change a thing that was remotely related to this error message. When resetting the MasterPage back to the site definition, everything was working fine, even though the web.config had not changed at all. After puzzling for several hours we figured it out.

When you change a MasterPage in any way outside of the solution, SharePoint automatically creates an un-ghosted copy of this MasterPage. When doing so, the page is now being checked by the SafeMode parser, instead of the ASP.Net parser. The SafeMode parser ensures all controls referenced on the MasterPage are listed as safe control in the web.config. In our case it wasn’t, which caused the un-ghosted MasterPage to throw an error.

In order to fix this error, you can revert the MasterPage back to its ghosted condition by following these steps:

  • Go to Site Settings
  • Go to Reset to Site Definition
  • Fill in the complete URL to the MasterPages’ location, and hit OK

Unfortunately for us this meant that we could not simply update just the MasterPage and had to wait for the entire solution to be tested before we could implement the new MasterPage.

A very good link to use for the difference between ghosted, unghosted and ghostableinlibrary can be found here: http://magenic.com/Blog/GhostedUnghostedandGhostableInLibrary . The difference between the ASP.Net parser and the SafeMode parser can be found in great detail here: http://www.bluedoglimited.com/SharePointThoughts/Lists/Posts/Post.aspx?ID=4

Fixing double scrollbar issue in SharePoint 2013

Unfortunatly with the arrival of SharePoint 2013, Microsoft still has not fixed one of the most annoying bugs out there: the double scrollbar issue on Public Facing websites. With a few modifications, a great fix for SharePoint 2010 can be applied to SharePoint 2013 as well.

The blogpost http://kyleschaeffer.com/sharepoint/sharepoint-2010-scrolling/ describes how to fix this issue for SharePoint 2010, however things are slightly different in SharePoint 2013. For the ribbon there is the user control <PublishingRibbon:PublishingRibbon runat=”server” />. This user control renders the ribbon, but with slightly different CssClasses applied. To make the fix described in the blogpost work, you have to replace all occurrences of #s4-ribbonrow in the css file with #ms-designer-ribbon . Check to make sure the <body> tag has the cssclass=”v4master” applied to it as well.

As a final modification to the blogpost, to make the various SharePoint popups work (insert tag / insert image etc.) you have to add the following CSS styling:
.ms-dlgContent { position:fixed!important; } . Thanks to this post for figuring that out. After that everything works as expected in Chrome/ FireFox / IE when logged in and for anonymous users.