SharePoint International

Implementing internationalization in SharePoint is pretty straight forward – until you notice it fails for the site’s default language. Peeking into Microsoft’s code with ILSpy you see something like this:

// Microsoft.SharePoint.Navigation.SPNavigationNode
/// <summary>Gets or sets the string used as the anchor text for the node navigation link.</summary>
/// <returns>Returns a string representing the display name that serves as anchor text.</returns>
[ClientCallable, ClientCallableConstraint(Type = ClientCallableConstraintType.MaxLength, Value = 256), ClientCallableConstraint(Type = ClientCallableConstraintType.NotNull)]
public string Title
      if (CultureInfo.CurrentUICulture.LCID == this.Navigation.Web.UICulture.LCID)
         return this.m_strTitle;
      return this.TitleResource.Value;
      if (!SPUtility.StsCompareStrings(this.Title, value))
         this.TitleResource.Value = value;
      if (CultureInfo.CurrentUICulture.LCID == this.Navigation.Web.UICulture.LCID)
         this.m_strTitle = value;

So if the current UI culture equals the site’s default culture m_strTitle is returned with no respect to internationalization.

Unfortunately, the documentation for the title parameter of SPNavigationNode’s constructor states that ‘The string value can be a resource expression such as “$Resources:core,announceList”‘. The code shows this won’t work for the site’s default culture: you’ll see something like ‘$Resources:core,announceList’ in your UI and not ‘Announce list’ as you wanted.

For SharePoint 2010 you’ll have to loop through your supported cultures, setting your thread’s UI culture to each of them and the node’s title to the respective localized title. There are various posts on the Net showing how to do this.

SharePoint 2013 didn’t fix the bug but makes it easier to get around it. It added an SPNavigationNode constructor with three parameters: title, resxTitleResource, and url. Call this constructor with the title set for the site’s default culture, pass your resource expression as the second parameter, and internationalization will work as expected.

This example uses PowerShell and a default culture of 1033 (en-US):

$nodeResource = "`$Resources:My.Solution,NodeTitle;" # escape "$" ("´$Resources:...")
$englishNodeTitle = [Microsoft.SharePoint.Utilities.SPUtility]::GetLocalizedString($nodeResource, $null, 1033)
# $linkUrl = "..."
$node = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode($englishNodeTitle, $nodeResource, $linkUrl)

External References

This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s