In the last post of mine, I discussed certain implications that come with using SharePoint Designer to brand your SharePoint sites. This post will discuss the prefered alternative to SharePoint Designer, building custom site definitions. However, I must start by saying that this philosphophy is by no means a SharePoint standard. Andrew Connell, who's probably one of the most well known and respected SharePiont MVP's ever, begs to differ. Check out this powerful comment on one of his blog posts:
"I still do everything I can to avoid creating site definitions. They are too big and cumbersome making it hard to debug when problems arise. Most importantly, they are very inflexible; once one a site has been created off a site definition, it should never be directly changed." – Andrew Connell
That's a very strong statement indeed! And coming from an MVP causes a peon such as myself (notice descriptive image to the right) to consider it carefully. However, with that said, my question still lingers. How can you enforce a custom brand across your entire farm, including all web applications, site collections, and sites (or conversely, cherry picking large sub-sets of those) without editing Microsoft's pages? I see custom site definitions as the easiest approach to this question for the following reasons:
- As I mentioned in my first post, SharePoint Designer can only scope a brand across one and only one site collection, not many site collections and/or web applications.
- All SharePoint sites by default inherit from one master page, Default.master in the GLOBAL site definition. It is NOT a best practice to edit this page because you run the risk of service packs overriding it, and you lose your warranty with Product Support. Therefore, a better approach is to create a copy of this page and use your own, but how do you assign ALL the webs across a broad scope to use this copy?
There are ways to programmatically set a master page. Maybe you have a feature that when activated, deploys a master page to the master page gallery, and thereafter sets the MasterUrl property of the Web to be that of that new master page (Paul Stork has a good example of this). But what if you have thousands of Webs? You certainly don't want to manually go to each one. You could write another feature or console application that crawls your entire farm and sets the property to be that of your custom master page, but again, what about new sites? I suppose a combination of both those two solutions would do. But that seems like a lot of work, and if you're not a developer, an impossibility (this would be a good Codeplex download, anyone?).
The Benefits to Site Definitions
Here's the bottom line with Site Definitions. When it comes to branding, there's not many better ways to do it. Much like when you edit the Default.master page in the GLOBAL site definition, any changes to your master page that is specified in your custom site definition will propagate to all sites everywhere that use it. You have the power to know for certain that all your sites are consistent, because all your sites use one master page, not copies that are strewn about the database. That, and you won't need to void your warranty.
Therefore, even know it may be controversial, I will conclude nevertheless with stating my second of ten best practices: Build custom Site Definitions if you need to enforce a custom brand across your entire farm. It is very likely that Andrew wasn't thinking along these lines when he wrote that post, because to be honest, I fundamentally agree with his premise. I just don't see a silver bullet with this issue. To me, the benefits to site definitions seem to tip the scales as they say… thoughts?
If all this went over your head, in my upcoming whitepaper I plan on documenting how to build site definitions from scratch that utilize a custom master page (in 10 easy steps naturally). So stay tuned!
<update 06-11-08>
After thinking through this post and receiving some feedback, I have come to see the light in Andrew's concept. I see now how using features to enforce a brand across an entire farm is possible and even the preferable option over creating a custom site definition. Just as I mentioned above how there are programmatic options through feature stapling, if you have the wherewithal it is the most dependable option. Here's those options restated:
First, I would implement Park Stork's example as I mentioned earlier, and have that feature auto-activate upon creation of each site. You would have to edit all the SharePoint site definitions and include that feature as one that is by default activated when the site is created (this is what I failed to see earlier). If you do this, every site everywhere that is created will use your custom mater page, and thus your brand will be maintained. Now for sites that have already been provisioned, I would write another feature scoped at the web application, that when activated would crawl the entire web application and any webs that are not using my custom master page,
the program would set them to use it. With the combination of these two features, you can account for all new and old sites in your farm.
Now if you're not a strong developer, this may still not be the best approach for you, however, I will still agree that it is the preferred practice than creating a custom site definition. Thus, I will restate my second best practice as follows: Use a custom master page deployed via a feature on all your sites to extend your company's brand across an entire farm.
</update>
Thanks ALL!!! I look forward to your feedback.
Phil