SharePoint often provides several ways to accomplish the same task. And more often than not, the majority of the approaches are far from being effective.
SharePoint often provides several ways to accomplish the same task. And more often than not, the majority of the approaches are far from being effective.
Today I'll describe the XSLT localization approaches and advantages/disadvantages of each of them.
But first, why does that kind of task deserve our attention? That's because of a bunch of awesome webparts, all derived from BaseXsltDataWebPart - you all know them very well, they are: DataViewWebPart (DVWP), DataFormWebPart (DFWP), XsltListViewWebPart (XLV), XsltListFormWebPart (XLF), and ContentByQueryWebPart (CQWP).
So, sooner or later, if you have multilingual portals, you will face the necessity of the XSLT localization. That is inevitable.
Before we start, the first thing you have to remember is that your resources should be placed in theApp_GlobalResources folder under the IIS web application directory. For details on how to do this, you can refer to the article Did you know: provisioning AppGlobalResources in SharePoint 2010 by Waldek Mastykarz.
Copying your resx files to 14/Resources folder will not work for XSLT! In the end, you can reinvent a bicycleend up with a constant ParameterBinding - thus, "on fly" SharePoint 2010 localization will be broken.
The first approach concerns ParameterBindings property.
1
<
ParameterBinding
Name
=
"parameterName"
Location
=
"Resource(resourceFile,resourceName)"
/>
Parameter bindings are passed to XSLT, so you can grab them with xsl:param, providing the same parameterName:
1
<
xsl:param
name
=
"parameterName"
/>
This way is decent, but not very convenient: you will have to add a ParameterBinding each time you will need a resource. After 10-20 resources, trust me, it will become very irritating!
And another peculiar detail: there are no spaces allowed between resourceFile and resourceName!! Thus, a single typo could bring you to a "desperate bug" struggle :)
The most tasty way, however, is what I call "magic". I dislike it a bit, because of the notorious pixel hunting, "hidden urls", etc. - but those all are the same kind of things, actually.
The trick is that using peculiar XPath queries, you will, all of the sudden :), get a localized value. The syntax is as follows:
1
<
xsl:value-of
select
=
"/dsQueryResponse/Rows/@resource.resourceFile.resourceName"
/>
And I can't resist mentioning, that you can't use resx files with dot in their names. Since in our main project at work all the resource files use "Product.Module.resx" naming format, we are overboard with that approach :( #fail
But, these two ways are already described well in the XSLT Parameter Bindings article on MSDN, so you might ask, hey guy, and there are your five cents!?
And yes, here it comes!
It is no secret, that you can use server controls in SharePoint XSLT. Even your own controls, by the way, as it was explained in a recent NothingButSharePoint post Custom controls in XSLT, written by Pranav Sharma. And if you're familiar with ASP.Net localization syntax, you may have had the same idea.
The idea could then be converted into the following XSLT template:
01
<
xsl:template
name
=
"Localize"
>
02
<
xsl:param
name
=
"Name"
/>
03
<
xsl:choose
>
04
<
xsl:when
test
=
"starts-with($Name,'$Resources:')"
>
05
<
SharePoint:EncodedLiteral
runat
=
"server"
text="<% {$Name} %>"/>
06
</
xsl:when
>
07
<
xsl:otherwise
>
08
<
xsl:value-of
select
=
"$Name"
/>
09
</
xsl:otherwise
>
10
</
xsl:choose
>
11
</
xsl:template
>
Despite a slight awkwardness, this is a fairly powerful approach, because you can use standard "$Resources: file, name" syntax in some parameters or even in field values, and this will give us some extra capabilities. For a real example, SharePoint itself uses this approach to localize XmlDefinition xaml controls of XsltListFormWebPart :)