Localizing Content Query Web Part XSL templates


It’s great to know that the Content Query Web Part (CQWP) is there whenever you need to provide a roll up of some content. Delivering a solution of similar experience, possibilities and flexibility would be really time consuming. Unfortunately there are still some things inside the CQWP which could be improved. Let’s take for example localizing the XSL used for data presentation: do we really have to create a different template for every language or is there a better way?

The truth behind variations

SharePoint 2007 supports out of the box multilingual solutions by providing variations. Using that mechanism you can setup separate branches for different languages. Each time you publish a page in the source variation, it’s being copied to other branches so that the content authors can translate the content. No matter whether you like the way the variations work, they are the way SharePoint deals with multilingual content. But what about the controls?

…do we really have to create a different template for every language?

If you look at the controls shipped with SharePoint you notice, that in general they use resource files provided with language packs. If you want to create a multilingual site, all you need to do, is to install on the web server a language pack for each language and pick the right locale for each of the variation branches. Based on the locale of the site, the controls will get the strings from the right localized resource file. Unfortunately this doesn’t apply to all controls and situations.

The Content Query Web Part wraps up quite complex functionality of querying and presenting content into a single web part which can be configured by power users. Because the presentation of the results is being done using XSLT the CQWP is highly reusable across many different solutions. But there is a consequence to this high flexibility: XSLT doesn’t provide any localization mechanism at all.

XSLT doesn’t provide any localization mechanism at all.

Providing a roll up of some content means very often showing the excerpt of the particular page and adding a “Read more” link which allows the visitors to read the complete content. That’s where the question arises: how do you translate these read-more-links: do you create a different XSL template for each language or have you developed a different way of dealing with this challenge?

Although there are situations when creating a different template is inevitable: for example when on of the language is a western language and the other language is a language which is written right to left. In such situation you don’t only want to get all the content localized but do some formatting (like aligning the text to the right margin) as well. If however, all you need to do is to provide a translation of the read-more-links, there is a more efficient solution available.

Localizing contents of the Content Query Web Part using custom XSLT functions

Nearly a month ago I wrote an article about how you could extend the XSLT functionality of the Content Query Web Part with custom logic. The same concept can be reused to help us deal with localization of some content inside the CQWP XSL.

The first step is to extend the Content Query Web Part with custom functions: just as described in my previous article. Then let’s create a new method called GetLabel(string):

private static ResourceManager resourceManager;

public static string GetLabel(string key)
{
  if (resourceManager == null)
  {
    resourceManager = new ResourceManager("Resources.myAssembly",
      Assembly.Load("App_GlobalResources"));
  }

  return resourceManager.GetString(key,
    SPContext.Current.Web.GetCurrentCulture());
}

This is the method we will be calling from the XSLT to get us the right translation depending on the locale of the site the Web Part is on. First of all you check whether you have an instance to the Resource Manager which retrieves the labels from the resource file. Because the resource manager is reusable (and you’re very likely to call it more than once) you can retrieve it once and store it in a static variable.

To obtain the culture (required for obtaining the right label from the resource files) I have used an extension method. In general, when using variations, you would access the PublishingWeb.Label property to retrieve the culture. As variations allow you to create sites which don’t belong to the variation hierarchy the PublishingWeb.Label property might be null. To capture such exceptions I decided to wrap it up in an easy to call extension method:

public static CultureInfo GetCurrentCulture(this SPWeb site)
{
  CultureInfo ci = CultureInfo.CurrentCulture;

  if (PublishingWeb.IsPublishingWeb(site))
  {
    PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(site);

    if (pubWeb.Label != null)
    {
       ci = new CultureInfo(pubWeb.Label.Language);
    }
  }

  return ci;
}

Having these two methods available in the functions class, all you need to do is to create resource files just as you would do for a custom Web Part and deploy them to App_GlobalResources of your Web Application. Having registered your functions class in the CQWP XSLT you can now retrieve the localized labels:

<xsl:value-of select="imtech:GetLabel('ReadMore')"/>

Summary

Content Query Web Part is a great solution for aggregating content from a SharePoint site. While its standard functionality makes it suitable for many different scenarios it lacks support of multilingual solutions. By extending the standard Web Part with custom XSLT functions you can leverage simple yet very efficient mechanism for retrieving localized labels.

Technorati Tags: SharePoint, SharePoint 2007, MOSS 2007, Content Query Web Part

Others found also helpful: