As it relates to internationalization with VisualForce, I sometimes feel like a spelunker charting the depths of some mysterious cave. The equivalent of the flashlight going out is realizing you’ve rolled something to production you thought was correctly internationalized but in fact, was not. That’s happened to me one to many times in the last year or so and as a result, I’m going to do my best to pass along some of the lessons I’ve learned the hard way.
Beyond the basics of translating your static VisualForce content, I’ve observed two main hot-spots:
For #1, I’ve developed a set of utility methods to make this much easier and placed them in a class called LanguageUtils.cls in apex-lang. Want your VF page to be translated according to user’s browser settings? No problem, simply use the getLangCodeByBrowser() method. Or perhaps you want to allow an http parameter to be passed but in case that’s null, use the currently running user’s language? Use method getLangCodeByHttpParamOrIfNullThenUser(). Trust me, there are hidden gems in these methods like defaulting zh to zh_CN.
For #2, this has been especially painful. You might be tempted to say “dude, just don’t reference static content in Apex Controllers”; however, many times it’s not that simple. You might have a design which is more efficient by referencing static content in an Apex Controller. Or, like I’ve had, a product feature requirement which absolutely necessitated the need for it. Regardless, developers need to be able to reference static content in Apex Controllers. A good example where you can, but absolutely shouldn’t, is Custom Labels: references to Custom Labels in an Apex Controller can ONLY be translated according to the language of currently running user. No matter what value you throw in the apex:page language attribute, a label will only be translated according to the language of the currently running user. I’ve submitted this as a defect to salesforce and I certainly hope they fix this soon. The obvious workaround is to not reference them in an Apex Controller. Unfortunately in this case, that’s the only option.
Another type of static content which is problematic is picklist values. Picklist values can be retrieved in an Apex Controller via a describe. The tricky part is, in order to control the translation via the apex:page language attribute, the describe cannot be done in the constructor for the page’s controller. Instead, the describe must be done in an “onload” action method. Here’s a demo of this issue via the following two links. Both pages will be rendered in Simplified Chinese.
New features include:
- toString() methods for printing out numbers in binary, octal, hex, etc.
- Translations for all force.com supported languages. To see an example use case, see http://rvdemo-developer-edition.na6.force.com/SendEmailDemo
- Language code retrieval methods such as getLangCodeByHttpParamOrIfNullThenUser() and getLangCodeByBrowserOrIfNullThenHttpParam()