Setting master page for SharePoint publishing sites

I am upgrading local community portal from SharePoint Server 2007 to SharePoint Server 2010. I also have to write deployment scripts so other guys can also use our codebase. One thing my deployment script has to do is to force correct master pages to sites. There is one little trick you should know when setting master pages for publishing webs. Here’s how I got things work.

The problem

Publishing site have two master pages – one is custom master page that is used to show site for visitors and the other is system master page that is used with site settings etc. SharePoint publishing infrastructure allows webs to inherit master page settings from parent web. If you do something like this:


$web.CustomMasterUrl = "/_catalogs/masterpage/My.master"


then it sometimes works and sometimes it doesn’t.

How is master page inheritance defined?

SharePoint Publishing infrastructure extends SharePoint existing sites. Yes, it extends, it doesn’t replace anything. If we need to keep custom information about web we have to use web’s properties collection. Let’s see what we have there.


__WebTemplates: 
__InheritsMasterUrl:  True 
vti_defaultlanguage:  en-us 
vti_approvallevels:  Approved Rejected Pending\ Review 
__ImagesListId:  a20437ed-9fe4-41f1-8e58-7a41218f7928 
__PublishingFeatureActivated:  True 
vti_associategroups:  8;4;4;7;6;9;10;11;12;13;14 
NavigationPropertiesSet:  True 
vti_customuploadpage:  /_layouts/UploadEx.aspx 
vti_filedialogpostprocessorid:  {f68e6d4e-383a-4c8d-ba4d-d2139f164281} 
__DocumentsListId:  a5c43bc5-92f3-4e3e-ae9d-91228756bc53 
__InheritsCustomMasterUrl:  True 
__CurrentNavigationIncludeTypes:  3 
vti_associatevisitorgroup:  7 
vti_extenderversion:  14.0.0.4762 
__InheritWebTemplates:  True 
__NavigationShowSiblings:  True 
__GlobalNavigationIncludeTypes:  3 
__PageLayouts:  __inherit 
vti_associateownergroup:  6 
__DefaultPageLayout:  __inherit 
__InheritsThemedCssFolderUrl:  True 
__NewPageUrlToken:  __inherit 
__InheritsAlternateCssUrl:  True 
__PagesListId:  5a169de8-6d00-444a-882a-3a47f10422fd 
vti_associatemembergroup:  8 
vti_categories:  Travel Expense\ Report Business Competition Goals/Objectives Ideas Miscellaneous Waiting VIP In\ Process Planning Schedule


Okay, seems like we are on our way. Take a look at the property that I made bold. This property affects the checkbox selection on the following screenshot fragment (taken from master page settings screen).

Master page selection

You may set custom master to whatever you want but if you don’t change inheritance rule too then SharePoint still uses master page of parent web.

My solution

Here is my solution and that works for me. Besides setting master page for web I also set __InheritsCustomMasterUrl to False.


$site = new-object Microsoft.SharePoint.SPSite("$siteUrl") 
$web = $site.OpenWeb("/news/blogs/") 

# break custom master inheritance and set correct master 
$web.AllProperties["__InheritsCustomMasterUrl"] = "False" 
$web.CustomMasterUrl = "/_catalogs/masterpage/My.master" 

$web.Update() 
$web.Dispose(
)


One thing more to mention – this is PowerShell script here. Don’t be confused! 🙂

Conclusion

As with many other things the behavior of SharePoint is unintuitive. You can find a lot of different sources from web where people suggest you to set custom master page and they don’t know that it doesn’t work without additional cool porn I just described here. Changing properties like this directly is technical design flaw in SharePoint and things like these should be done through PublishingWeb or another class one day when SharePoint API evolves.


Leave a Reply

Your email address will not be published. Required fields are marked *