I love the idea of site definitions. The idea that we can just say ‘give me a site for X’ and in a puff of magic smoke have a site with a feature rich experience just appear – that’s neat! And with SharePoint’s Feature mechanism and object model, we should be able to to a lot with them.
Strangely, after two and a half years working with SharePoint, I’d never built a site definition. (I don’t know how I managed that!) Recently, though, I’ve written several, and all I can say is that I’m older, and greyer than I was before. The reality of Site Definition development did not live up to my hopes.
So what’s wrong with them? Well, at a high level I would sum it up with SharePoint’s private language, ‘Collaborative Application Markup Language’ (CAML). It’s complex, fiddly, poorly documented, and there is too much of it. I would actually prefer to write code to configure my site in C# than CAML – at least then you have better documentation.
More than once I’ve written C# code to do something that I couldn’t find information about from the documentation, only to find out later that you can. In fact, CAML’s documentation is so bad that reverse engineering the out-of-box site definitions (or the Fab 40) is your best bet.
Also, there is no easy way to debug CAML. If you get annoyed with CAML and start using C# code instead, well, you can always put it into a console app on your development system and run it, allowing you to debug it. CAML – it works, or it doesn’t, and it doesn’t always give a useful or meaning error message. Worse is that often it works – but doesn’t do what you expect. Then you just have to try, and try again. That’s a very slow development model, and a bit ‘infinite monkeys’.
The tooling around CAML is, at best, limited. A number of bright chaps – including some at Microsoft – have tried to write applications for taking an existing site and reverse engineering it to CAML. They all have their quirks. There are few other types of tools for generating CAML. I mean even Visual Studio doesn’t recognise the Schema by default (why!? And couldn’t we have a simple executable to set that up?)
So, more specific issues that I’ve had, as an aide de memoire:
- True, TRUE, or true? (Or 1?) CAML seems to use different values for ‘True’ and ‘False’ throughout the system. Sometimes attributes are case sensitive, other times they’re not. Booleans are supposed to have two possible values; these ones have a lot more.
- Could different elements not have different names? I mean, it’s easy to get mixed up between a View and a View.
- Navbars. I can’t control the Left Nav as I’d like. I tried using the NavBars entries to add links in the left nav, but couldn’t get it working for a particular site configuration. Sadly, my nav needed to be different in different configurations – and the Navbars element is poorly documented, and appears to make use of magic numbers. Eventually I managed to add entries to my top nav, but not the left. If someone has good examples of this, please contact me.
- Pages Libraries need need Page Content Types associated with them. Obvious in hindsight, but I created a new Publishing Page content type, and tried to use it as the default page of my site. Well, the page would create, and would have the right page layout – but wouldn’t have the correct content type. No errors were shown, mind you. Between that and the strange user experience of Publishing Pages, this took me ages to figure out.
- ~Site/~SiteCollection don’t work everywhere. The ~Site and ~SiteCollection tokens are very useful ones that resolve to the server relative URL for the Site or Site Collection respectively. That’s pretty neat, as we don’t know those until we’re provisioning our site. Unfortunately, they don’t resolve everywhere; they work in some places, but not in others. What I found was that they didn’t work in WebParts defined in the Site definition. Why not make life easy, and do a substitution on the whole XML file?
- List left Navigation. I can’t get the Left Nav to appear for a List element in a Site Definition. I don’t know why – it should work – but I can’t get it to do so. Fortunately, I can get a ListInstance node of a feature to appear in the left navigation, and then attach that feature to my Site Definition. Sadly, however…
- ListInstance Versioning Settings. I can’t set versioning settings on a ListInstance element. I can on a List, but then my navigation won’t work correctly. Why? All lists have versioning settings! I just want to configure them.
That’s just from my experiences in a few Site Definitions recently. I’m sure that if I work with them more, I will find more puzzling problems that are hard to debug. I’ll blog about them as I find them.
So I guess in summary that Site Definitions are a great idea, but hamstrung by the relic that is CAML and the lack of decent tooling that exists around it. It’s a sad statement that I actually think I’d be more productive writing C# code than CAML