Convert “virtual” content types to “physical”
08 Sep 2007 22 Comments
What do you do, if you in a fit of madness/desperation/stupidity created the content types used throughout your site, through the web interface and you now want to do the “right” thing and place them in xml files packaged as a feature?
Well this is description on how to convert the existing “virtual” content type to that xml file, while maintaining the integrity of your existing site and content. Warning: I’m modifying the SharePoint content database directly – use at your own risk!
The basic idea:
- Create a content type xml file and package it in a feature (don’t deploy it yet) as you would if you started in a blank environment
- “Steal or copy” the content id for “virtual” content type from the database and use it in your xml files. In other words the existing content id that is used throughout your existing SharePoint database in the inheritance hierarchy, will remain unchanged
- Modify the database so that SharePoint sees your content type as being feature based instead of “database based”
- Deploy your new content type feature. You can now update that content type as if you had started it out xml based to begin with
It seems fairly straightforward doesn’t it? It actually is.
Information on creating xml based content type can be found here (and on many other sources), it’s really not that hard. Your deployment will be much easier after this.
Right about now would be a good time to do a backup of your content database 😉
Step 1: Steal the Content Type ID
Your content type will need a very specific ID that the SharePoint created for you when you created your new content type in the first place (either through the web frontend or API). It looks like “0x0101……” and will probably be a rather long string. You need to grab this id from the content database:
- Connect to the content database in question, probably named wss_content_XXXX (if you didn’t choose a database name the XXXX will be a guid)
- Execute the following query to find the right content typeselect ResourceDir, ContentTypeId, Definition
where ResourceDir like ‘%Article Page%’
Obviously substitute your own content type name, note that the web interface might have appended some trailing numbers to the name, so you’ll have to do a “like” selection
- Copy the ContentTypeID and insert it into the xml file. You might also want to verifiy that the definition corresponds to your that in your xml file (or just copy it over)
Step 2: Connect the Content Type to the XML File
Now you need to go into the database and modify the ContentType table to make SharePoint see it as a feature based content type as opposed to those solely in the database.
- Connect to the content database again (you might just have kept the window open)
- Execute begin tran once, just to give you an undo option
- Execute the following SQL statementUpdate dbo.ContentTypes
Set Size = 16, Definition = null, IsFromFeature = true
where ContentTypeId = 0x010100C5…..
It should only modify one row
- If the name “ResourceDir” has been mangled by the web interface, you might want to take the opportunity to fix that too now
- If you are satisfied with the update execute commit tran, otherwise rollback tran, do not forget this as you are locking the table for the duration (btw: Isn’t that a neat trick?)
I will not take any responsibility if you lose your databases, however I would like to know if you find flaws with the procedure 😉
If you have many environments this technique only works if they have the same content type id for the same type across the farms. They will have if you did a backup/restore or content deployment from one to the other. They won’t if you created them through the web on both servers. Then you either choose which one is the master of the content or you are out of luck.
Note that if you update/change the content type xml files at a later time, the changes will only apply to the site scoped content type, not the actual list content types that the system created for every list where the type is enabled. This is very bad news, but not to worry I’ll post the fix for that in a few days (give me a bit of time).
If you modify the content type through the web interface after deployment it will once again be disconnected from the xml source, and you’ll have to complete Step 2 (only) to reconnect it.