SharePoint 2013 conflicts with custom site definition

I was updating one of our custom Site Definitions from SharePoint 2010 to SharePoint 2013 recently and everything was going good until I tried to create a site from the updated definition.  I kept getting the error:

Microsoft.SharePoint.SPException: The template you have 
chosen is invalid or cannot be found.

Searching on the internet told me the most common cause of this error was a conflicting ID for the template.  I was pretty sure this couldn’t be the case since we followed the instructions here:  http://msdn.microsoft.com/en-us/library/office/ms454677(v=office.14).aspx which stated:

Change the ID attribute of the Template element to a 
value of 10000 or more. This ensures that your ID will 
not conflict with future site definitions produced by 
Microsoft. If there are other custom site definitions 
on your target farm, make sure that each one has a 
unique ID.

and we had given our template an ID of 10000.  I had previously updated another custom site definition of ours with an ID of 10001 without any issues.

So I decided to give a quick search in the SharePointRoot\template\1033\XML folder for anything that contains ID=”10000″.  Sure enough I found two site definitions, mine and a new one that comes with SharePoint 2013 called the Academic Library.

I found this article:  http://social.technet.microsoft.com/wiki/contents/articles/20149.sharepoint-2013-default-site-templates.aspx which discusses the new site definitions that come with SharePoint 2013.  You can see it listed there as:

ID Name Title
10000 DOCMARKETPLACESITE#0 Academic Library
The Academic Library template provides a rich view and consumption experience for published content and management. Authors populate metadata and apply rules at the time of publishing, such as description, licensing, and optional rights management.(IRM). Visitors of the site can search or browse published titles and add authorized selections to their collection to consume, subject to the rights and rules applied by the author. The site provides an IRM-capable document library, a publishing mechanism for authors to publish documents, detailed views for each document, a check-out mechanism, and related search capabilities.

So it would seem that if you followed the recommendations for SharePoint 2010 and used an ID of 10000 for your custom site definition, then when you try to go to SharePoint 2013, your site definition won’t work.

This is an issue because there is not a way to change the template ID of a site after it’s been created through the API.  Fortunately, I have found 2 ways to get around this.  One of them I haven’t fully run to ground and verified that it works but the concept seems valid and the other isn’t supported by Microsoft.

Option 1:

This option I got the idea from this blog:  http://iknowsharepoint2007.blogspot.com/2010/02/changing-sharepoint-site-definition.html.  The basic idea is you export your site without using compression, change some xml configuration files so they use your new ID, and then import it back into your SharePoint environment.  You might not even have to change any xml files since that post was for SP 2007.  If someone tries this method, please comment below, otherwise if I find time to give it a try, i’ll update with my findings here.

Option 2:

This involved editing data directly in the SharePoint content database.  This is unsupported by Microsoft but worked for me during my testing.  Go to the AllWebs table in the content database for the site in question.  You should be able to find your site listed by scanning the FullUrl column.  Once found, write a SQL update statement which updates the WebTemplate column to the new site definition ID.  This was an instant fix for me as I was able to immediately start the upgrade to SharePoint 2013 for that site collection.

It sucks that Microsoft told us they would never use Site Definitions ID of 10000 or more and then they go back on their word with SharePoint 2013.  Anyways, I hope this helps someone else out trying to complete their migration to SharePoint 2013.  If anyone finds a better way to fix the issue, please post in the comments below.  Thanks.

Warning: SetCookie changes implementation in SharePoint 2013

I was recently working on verifying some of my custom code worked in SharePoint 2013.  I had some older code where I needed to set cookies and use them to remember user preferences.  I was debugging my code and I noticed that all of my cookies were coming back either true or false instead of the value I put into them.  I had been using a SharePoint JavaScript method called SetCookie.  Below is the implementation that has existed in SharePoint for the previous 3 versions (2003, 2007, and 2010).

function SetCookie(name, value, path)
{
	document.cookie=name+"="+value+";path="+path;
}

But for some reason Microsoft decided to change the implementation of this method in SharePoint 2013 to the following:

function SetCookie(sName, value) {
    SetCookieEx(sName, value, false, window);
}
function SetCookieEx(sName, value, isGlobal, wnd) {
    var c = sName + (value ? "=true" : "=false");
    var p = isGlobal ? ";path=/" : "";

    wnd.document.cookie = c + p;
}

Notice this new method tries to evaluate the value into a boolean and then forcefully sets the cookie to true or false.  So if you were storing anything other than boolean values in your cookies and used this method in previous versions of SharePoint, you will now need to update your code.  For this you have two options:

Option 1:  I found there is another method in SharePoint 2013 which still implements the SetCookie the same was as previous versions of SharePoint.

function SetMtgCookie(cookieName, value, path) {
    document.cookie = cookieName + "=" + value + ";path=" + path;

}

So you can easily do a search and replace for SetCookie to be replaced with SetMtgCookie and you’ll be good to go.

Option 2:  This is the option I opted for.  I decided that as tempting as doing a quick search and replace like I suggested in option 1 sounded, I wanted to remove my dependency on SharePoint’s implementation in case it changes again in the future.  Since the older SetCookie is only one line, I just replaced my method call to that line:

document.cookie=name+"="+value+";path="+path;

It was a pretty simple change, only slightly more time taken than option 1 and I removed a dependency.

Anyway, I hope this helps someone else out when troubleshooting code migration to SharePoint 2013.