Most if not all of us in SharePoint 2010 created custom master pages and designs for portals, team sites, etc. Now all that work not only has to be re-done to fit the new SharePoint 2013 look and feel and new functionality, but has to be reset once you do a site collection migration.
When you do a site collection migration from a SharePoint 2010 mode site collection to a SharePoint 2013 mode site collection in SharePoint 2013, the process will reset the master page of the site collection to the default master page. Imagine if you have 1,000’s of site collections, now you have to write scripts to update all these.. now imagine you are on a SharePoint Online Dedicated environment, where you do not have access to run scripts to update them in bulk.. It would be very difficult to do this manually.
This is where we go back to SharePoint 2010 and Microsoft introduced Feature Upgrading. Although at the time this new process was not widely adopted as people still never versioned their features no matter how many updates they applied to them… BUT this is the perfect process for handling the application of a SharePoint 2013 master page when a site collection is upgraded from SharePoint 2010 mode to SharePoint 2013 mode. This is because as part of this site collection upgrade process, it will also trigger a feature upgrade of every feature which is activated on the site or web.
Since you have to redevelop a SharePoint 2013 version of your master page and should be using feature masking to support that “Branding” feature which is activated in SharePoint 2010 to also be activated as a SharePoint 2013 feature. More information about Feature Masking can be found in my previous blog post:
From this point I will assume you know how to migrate / mount a SP2010 content database (mount-spcontentdatabase 🙂 ).
The first thing is feature masking.. you have a farm solution for SharePoint 2010. In my case it is called MasterPage-SP2010.wsp. This solution has a web scope feature which deploys the master page and sets it as the current master page using the feature activation event receiver. This is nothing new, so I expect you know how to do this as well.
The second part of this is to support feature masking I created a SharePoint 2013 version of the solution called (you guessed it!) MasterPage-SP2013.wsp. In order to support feature masking I followed all the same rules defined in the previous blog post regarding the feature folder structure, feature name and feature ID needs to be the same as the feature in which I am masking from SharePoint 2010. See screen shot below (MasterPage-SP2013 on the left and MasterPage-SP2010 on the right).
Now that feature masking is configured the site collection will have a feature of ID “b3add9ff-ee85-453b-80e3-2699b7da4e5d” in the “Activated” collection associated with the 14 hive (SP2010), when upgraded it will still associate with that same feature ID but now be linked to the 15 hive (SP2013). The difference is there is a different assembly which is associated with the SharePoint 2013 solution, which has additional logic to set the master page.
First in the SharePoint 2013 solution, you must include an <UpgradeActions> element. This element defines the event receiver class to run in order to execute the event of FeatureUpgrading. Within this Upgrade Actions element, you define a <VersionRange>. Since most of us never put a version on our SP2010 features, it is assumed to be a version number of 0.0.0.0. So we would need to define a version for our SharePoint 2013 feature and set the range from 0.0.0.0 to that version (in my case I set it to 22.214.171.124). You can see the example below from my test projects where I defined the upgrade actions in my feature.xml file. You will have to do this manually as this is not part of the GUI.
I have included the FeatureUpgrading event code within the feature receiver file I used for activating and deactivating. In order for the upgrade event to fire, you need to specify the “<CustomUpgradeAction Name=”MasterPage2013Upgrade”>” Element in my upgrade action. Since I was just doing this one thing, I originally left this out since it is not required, however I realized my code was not being executed unless I had this defined in the XML. I also added a check in the code to make sure the upgrade action I am executing was indeed the “MasterPage2013Upgrade”, which you can see below.
The one thing which you have to watch out for when creating a module to deploy the master page to the site is where you plan on putting it in the master page gallery. For the most part up until now, we all put our custom master pages in the root of the master page gallery. Now in SharePoint 2013, you have to put it in a sub-folder. If you try to put it in the root of the master page gallery the code or the execution won’t break, however you will not see the master page in the gallery from the browser window. You can however see it if you look at the gallery through SharePoint Designer. This is not ideal as the file is not versioned or has a content type applied to it.
You will need to also add in the Type=”GhostableInLibrary” attribute as well if you want the document to show up in the library.
You can see how I defined my modules folder below…
After all this the key things to remember are to specify a CustomUpgradeAction Name and make sure you push the master page file to a sub folder of the master page gallery.
After all is said and done you should have 2 WSP’s.. One for SP2010 and one for SP2013. You must deploy these via PowerShell and when deploying these WSP’s you must remember to use the “-CompatibilityLevel” Parameter when using both Install-SPSolution and Uninstall-SPSolution.
Hope this helps.