MUI capabilities of SharePoint 2010

For some time now, I’ve wanted to explore the MUI capabilities provided in SharePoint 2010. In general they seem to work out fine, but there are some quirks I find a bit strange.

The first step on the path to multi-lingual SharePoint nirvana is to download the appropriate language pack. This has to be installed on each server.

Once that has been installed, you will have to make a conscious choice to enable the language on your site collection; it doesn’t happen automatically.

This can be done quite easily through the site settings.

Then check off the languages you wish to use.

When this has been enabled, you get a new option on the drop-down menu connected to your login name.

It’s then easy to toggle between the different languages.

When provisioning sites and site collections, you get to choose what the default language should be. This works in both the HTML and Silverlight version. The Silverligth version will also be presented in your chosen language.

                 

Another capability of enabling multiple languages is that you can provide a language specific name for your lists. When you edit the title and description for a list, the current culture is stored together with the value. By changing the the active language, it’s possible to add multiple linguistic versions.


The place where things become a bit strange, is on the the quick launch.

Shared Documents shows a modified version for the English version, but on the Norwegian version it seems to be using a translated version of the original.

For my custom list, it doesn’t seem to be using the Norwegian version at all.

CAML is still the King over SPLinq

SharePoint 2007 was based on .NET 2.0, so when SharePoint 2010 came about, they just had to use some of the new developer goodness they had previously missed out on. Linq is incredibly cool, so they just had to implement a Linq provider for SharePoint. On the surface, it looks great. Who doesn’t like Intellisense? Who really likes to mess about with CAML?

They just forgot one thing; a fundamental fact in SharePoint is that the world our code operates in changes at the blink of an eye. This is a problem that Linq to SQL doesn’t face since the database schema doesn’t suddenly change.

If we take a look at a sample of the file generated by SPMetal.exe:

Can you spot the problem? I have several issues with this code.

Firstly, it’s using the display name to find the list. If a user happens to rename your list, you end up with this:

Secondly, it’s a specific language version being used. If you have to support multiple languages, you have a challenge.

If you don’t care two figs about multiple language, the first issue could have been solved by using the URL instead. Once created, that at least doesn’t change.

Ideally, the DataContext implementation should have some functionality to retrieve the localized strings from the site. One common scenario is to create a number of sites of a specific type where each site may be in a different language. If we could used the same DataContext agains all these sites, that would be helpful.

For the time being, I’ll stick with CAML. It may be nasty, but at least I can create code that adapts to the environment I’m running in.

CAML has left the building.

Site customization options

SharePoint has many ways of defining how the site will be configured once created; Site definitions, web templates, feature stapling. For a full list of the options, check out the following blog posts:

Site Definitions vs. Web Templates

SharePoint 2010 and web templates 

I’d like to complement this information with a bit of my own.

In the new webTemplate element, it’s possible to use resource expressions for title, description and display category. This should make it easier to create localized versions of the templates; no need to use parallel file structures.

Feature stapling is something I only do for MySite. At some point in time you may wonder if a problem exists in the standard templates. If you avoid feature stapling, it’s easy to check if the problem exists and thus report a bug.

Don’t be afraid of creating your own templates, with the new webTemplate option, it doesn’t require much effort. The upside is that you then have the ability to grow as time goes by. If you need a department and project template, go ahead. You don’t have to try and tweak both options into feature stapling against the generic team site.

Why STSADM still kicks ass

With the release of SharePoint 2010, PowerShell has become the new cool kid on the block when it comes to deployment. STSADM has been bullied into a corner and hidden away, soon to be taken behind a shed and put out of it’s missery.

There is one area where STSADM is still the king, and PowerShell is the pimpled kid trying to get out of puberty. And I don’t see how PowerShell will beat it anytime soon.

STSADM rules when it comes to feature activation. Huh?? And the reason is very simple, it’s a good old fashioned console application.

Since it’s a console application, it will always load all the assemblies it needs before it does it’s thing. This ensures that when you activate your features, you will always be using the feature receiver that has been installed in the GAC. Ever gotten strange error messages when you try to activate features using PowerShell? I have.

PowerShell is built on the .NET framework. When an assembly has been loaded, it cannot be unloaded until the hosting Application Domain is terminated. As long as you keep your PowerShell window open, the Application Domain will be loaded. You have to start a new instance in order to have the latest assemblies loaded. With STSADM I can open a console window and keep it open for days. I can toggle between the latest commands as long as I want.

This may not be a big deal for an IT admin, but it sure is for a developer. I make a lot of changes in feature receivers and hence need to activate them. I would go nuts if I had to open new PowerShell windows all the time. STSADM isn’t sexy, but it works.

Sites vs Site Collections

When building a collaboration system, you will soon face a choice between using sites or site collections. In general I tend to favor multiple site collections. i.e. each project or department has their own site collection.

Storage Quotas

Most organizations don’t have an unlimited amount of storage. Keeping the data growth under control is important. In SharePoint it’s possible to impose a quota at the site collection level, but not at the site level. If you chose one big site collection, everybody would be dipping into the same pool. When a site collection is approaching it’s quota, the site collection owners will receive email notifications.

Security

In SharePoint, security groups are defined at the site collection level. i.e. visitors, members and owners. Using seperate site collections, it’s easy to keep track of all the groups and you know they are all related to the content stored in this site collection.

By using multiple sites in the same site collection, you would have to start breaking security inheritance at various levels and adding additional groups. i.e. Project 1 members, Project 2 members, etc. If you have a couple of hundred projects, you end up with several hundred SharePoint groups as well; keeping tabs on what people can do at various levels becomes tricky.  When a site is deleted, the groups supporting it should also be removed; custom code is required.

If information sharing is important for your organization, some additonal steps need to be done if you use multiple site collections. One option is to give everyone read permission through a web application policy. The downside is if a site collection wants to hide its information; i.e. they are working on market sensitive information such as a corporate merger. A different approach is to have a system that synchronizes all of the visitor groups groups; e.g. using  a timer job. Each site collection should then have a mechanism that allows them to opt out of this synchronization.

Content databases

A SharePoint web application can have multiple content databases; each content database equals one SQL database. This allows the amount of data to scale and at the same time keep the SQL databases at a size manageble for disaster recovery. Using administration tools, it’s possible to move a site collection between content databases; something that is not possible for a single site. This functionality can be important in balancing your load across several databases.

Navigation

One area where multiple site collections become a challenge is navigation. For sites within a site collection, sub sites can automatically appear in the navigation controls. These entries are only shown if the current user has access to them; security trimming.

Since site collections don’t have a hierachy and they don’t know about each other, there is not automatic support for cross site collection navigation. You will have to come up with your own system. i.e. using the object model to add entries to the navigation system, or read the navigation configuration from some other location.

Site queries

One web part that can be very handy is the Content Query Web Part.  This allows you to perform a query that rolls up content from your site. Keeping the number of sites within a site collection low, these types of queries have an easier time.

Provisioning challenges

If you go for the multiple site collection approach, additional questions need answering.

  • Who should be able to create new site collections?
  • Should new site collections require approval? If so, by whom?
  • A site collection will have a lifespan. How does one determine the end and what does one do then?
  • Should the requestor become a site collection administrator? This allows them to do anything, including screwing up the whole site collection. This level of access may only be acceptable for certain individuals?

Code vs XML

As a SharePoint developer you can very often chose between code and XML. In my early days as a SharePoint developer, I favored XML, but as I have grown older and wiser, my preference has shifted to doing as much as possible through code. There are two things that you don’t have in XML:

  • Conditional statements
  • Exception handling

From code it’s very easy to check if a list, view, user or whatever you are creating already exists before you try to create it. If your code can handle that something may already exist, the road to creating upgradeable code is very short.

At some point, something will fail. Keeping as much as possible in code makes exception handling easier. In order to understand this we must first see how features work.

Features generally contain one or more XML elements for SharePoint to process. Features may also have a feature receiver that can perform whatever you code it to do. During feature activation, the XML files are processed first, then your feature receiver is called.

If the feature receiver failed, the XML processing might have succeeded. The net result is that some things may remain in the system even though the feature didn’t fully activate. You may correct your error and try again, but then the XML processing may fail since there are some remnants from the previous attempt. Using a pure code approach allows you to adapt to a lot of different scenarios.

There are some things that you cannot do from code; i.e. List Definitions. For those cases I try to split functionality across features and keeping each one as pure as possible.

Feature guidelines

A feature is basically a set of files stored in a folder. Each feature is scoped at a certain level (Farm, Web Application, Site Collection, Site) and can be activated or deactivated on demand. Internally features are referenced using a GUID, but on the file system a more human name is available.  The challenge is that all features are stored in the same folder, so the name is globally unique.

If you wanted to create some Administration links for your solution, you couldn’t call it ‘AdminLinks’ since Microsoft already has taken that name. Creating a feature with a generic name is not a good idea either because somebody else might also be using that name.

The way to get around this is to introduce a naming convention for your features. If you use Visual Studio 2010, the default name of features is <wsp file>_<feature name>. My personal preference is to use a three part dot notation for most cases.

<system>.<area>.<feature>

For each of the parts I have further conventions.

<system>

This represents the project the code is being developed for. If you are developing  a system for The Ministry of Silly Walks, the abbreviation MSW could be appropriate.

<area>

This represents the various functional areas.

COL = Collaboration
PUB = Publishing
SEA = Search
REC = Record Center
MYS = My Site

If left empty it’s applicable across multiple areas.

<feature>

Finally we come to the name of the feature. This should be something that illustrates the function of the feature. Here there are also certain names that I reserve for specific use.

Farm: Things to do at the farm level
WebApplication: Things to do at the web application level
Host: Things to do at the root site collection level (inspired by MySite Host)
Styling: Provisions the files required for visual styling/branding.

Examples:

MSW.COL.WebApplication
MSW.COL.Host
MSW.COL.DocumentLibrary : Customized collaboration document  library.

Experiencing name collisions using such an approach should be rare.

Once the name has been established, what other configuration changes should one consider?

Deployment Path is where you enter your custom name based on an appropriate naming convention.

Title and Description are always useful to fill out.

Activate on default is only applicable to features scoped to farm and web application. If this is active on a web application scoped feature, every web application that is created after this feature was deployed will get this feature activated. If you are writing code that is just so cool that everybody just has to have it, then go ahead and keep it active. If you like to give users the choice of activating your functionality, then let them explicitly activate it. They may of course deactivate it afterwards, but then the damage may already have been done.

IsHidden determines what features to show in the feature list UI. Features cannot be scoped to a single application; they are globally available. Features that are designed for a specific environment, i.e. My Site are available to team sites, search centers and anything else. Try to hide as many features as possible to reduce the potential for confusion. If a feature will always be activated as a result of site provisioning, there is very little point in making it visible to end users.

Version is a new attribute in 2010. Features can now be upgraded from one version to another. If nothing is set, the system will return version 0.0.0.0. Configuring an initial version just makes things clearer; it shows that you have made a conscious decision about it.

 

You may disagree with me on several of the points raised here, and that is fine as long as you have at lease given it some though.