Localizing CQWP (ContentByQuery) web part

Content By Query Web Part

SharePoint 2010 provides some most useful Out of the box web parts. CQWP (Content By Query) web part is one of them. There are many articles around web explaining how to customize CQWP. However, apart from XSL customizations, many times we have support multilingual UI interface for the lables or the text being displayed on CQWP. There are different ways to achieve this, like having different language specific XSL templates. Having multiple templates is obiously great deployment and maintainance overhead. This article talks about extending out of the box SharePoint Content by query web part and enabling the localization in easy way. The localized lables will be picked from resx files as usual way. Hence adding new language is also extremely simple.

Extending and Localizing CQWP

For extending OOTB (Out of the box) CQWP you need to derive from ContentByQueryWebPart class localted under Microsoft.SharePoint.Publishing.WebControls namespace which is part of Microsoft.SharePoint.Publishing.dll assembly.

Once done, override ModifyXsltArgumentList. This function gets called before the xsl transformation is applied to the data returend by query to CQWP. Here, we will add one ExtensionObject named LocalizationHelper 

    /// <summary>

    /// Pass additional parameters to XSL stylesheet.

    /// </summary>

    /// <param name="argList">XSL Argument list.</param>

    protected override void ModifyXsltArgumentList(ArgumentClassWrapper argList)

    {

        if (argList == null)

        {

            string msg = "Argument argList can not be null.";

            throw new ArgumentNullException(msg);

        }

        argList.AddExtensionObject("https://localizedcqwp", new LocalizationHelper());

        base.ModifyXsltArgumentList(argList);

    }

 

Following is the code for LocalizationHelper class

 

  /// <summary>

    /// XSL Extension object to return the localized string with given id

    /// </summary>

  public class LocalizationHelper

    {

        #region Constructors

        /// <summary>

        /// Initializes a new instance of the LocalizationHelper class, sets the webObject with the instance of SPWeb supplied

        /// </summary>

        public LocalizationHelper()

        {

        }

        #endregion Constructors

        #region Methods

        /// <summary>

        /// Get the localized string for current UI culture.

        /// </summary>

        /// <param name="resourceId">Resource identifier.</param>

        /// <returns>returns the localized string</returns>

        public static string GetLocalizedString(string resourceId)

        {

            return SPUtility.GetLocalizedString(resourceId, "Contoso", (uint)CultureInfo.CurrentUICulture.LCID);

        }

        #endregion Methods

    }

 

LocaliztionHelper class makes use of out of the box SharePoint 2010 SPUtility.GetLocalizedString function. Which returns the language specific string of given ID from the specified resource file. Here file named "Contoso.resx" will be searched for the string. Please note that, based on the current UI language the variated file will be selected for example, if current UI language is en-US then, Contoso.en-US.resx file will be searched for given resource Id. Once done now we can modify the xsl template to make use of this function. You can use this function in any of ContentQueryMain.xsl, ItemStyle.xsl or HeaderStyle.xsl files or any dependant files where the extension object is properly referenced.

To achieve this, first step is to add the namespace reference at the top of the xslt file.

 

<?xml version="1.0" encoding="utf-8" ?>

<xsl:stylesheet

    version="1.0"

    exclude-result-prefixes="x xsl cmswrt cbq"

    xmlns:x="https://www.w3.org/2001/XMLSchema"

    xmlns:xsl="https://www.w3.org/1999/XSL/Transform"

    xmlns:cmswrt="https://schemas.microsoft.com/WebPart/v3/Publishing/runtime"

    xmlns:cbq="urn:schemas-microsoft-com:ContentByQueryWebPart"

    xmlns:lcqwp="https://localizedcqwp">

  <xsl:output method="xml" indent="no" media-type="text/html" omit-xml-declaration="yes"/>

  <xsl:param name="cbq_isgrouping" />

  <xsl:param name="cbq_columnwidth" />

.

.

.

.

.

.

 

Now, wherever you want to display the localized string, you can call GetLocalizedString function directly from XSLT Code

 

.

.

<!-- Empty template -->

  <xsl:template name="OuterTemplate.EmptyContosoTemplate">

    <div class="contoso_lcqwp">

      <div class="wp-content description">

        <xsl:value-of select="lcqwp:GetLocalizedString('$Resources:lcqwp_webpart_noresults_text;')"/>

      </div>

    </div>

  </xsl:template>

.

.

In this way, Localiztion of CQWP can be achieved by making use of Extenstion objects functionality of XSL templates.