Sun 2 Dec 2007
Localization without using built in .NET 2.0
Posted by Duvall Buck under DbResouceManager
No Comments
This was a problem that needed to be solved to the okay of the decision makers. .NET 2.0 made a lot of improvements to how to localize/globalize ASPX pages. In the javascript/ASP application world where our current product lives translation was done via a method that queried the database passing in the English string as the lookup key and the user’s chosen language preference to return a translation of the English string. This translation was substituted in the appropriate place and auto-magically the English string was now a translated string. While this was crude but it was effective and the developer didn’t have to do anything special because enclosing the English string in the method call. I will admit that it was also pretty easy. No setting up strongly-typed names, no meta:resourcekey tags in the ASPX pages and no .resx files to manage.
The current product is translated into Spanish, Portuguese(Brazil), German and Italian. I have a lot of scrapping code that finds all of the strings and places them into an XML file. I have code that parses the XML files that are translated and places them into the database. There are small little apps that take the code out of the database and find strings that are missing translation.
On top of all that the translators we use are used to receiving the XML files and using their tools to translate. All in all it is a working process that would have to be changed in order to leverage the .NET way.
So I looked into doing some sort of scrapping of the controls on the page looking for English strings that needed to be translated. This would have to be recursive in order to find controls within controls. I had only a short amount of time to deliver the solution. Actually it was needed, like always, yesterday. So after two sleep deprived nights (not due to the pressure but due to my mind churning the different approaches) I saw two likely candidates to get this done. I could provide a BasePage that had the control looping and scrapping process that would be used on all ASPX pages. I really didn’t like this because it really added code to every page. What I did like was using a PageAdapter that would magically sit in the page life cycle process and do the control looping and scrapping. This way the code was in a single place and made maintaining a lot easier.
However there was this problem about using third party products for UI controls that was my real nightmare to control looping and scrapping. We use Telerik controls and are happy with them. But to recursively cycle through the controls and scrap the English strings was going to take me lot longer to code making delivery by ‘yesterday’ out of the question.
So I settled on a simple approach. I wrote a mimic static class that would be put in the code behind of the ASPX pages. Any properties that would have English string to be translated would call this static class with the method. The developer would have to jump to the code behind but it was similar to what they were doing before. So in the code behind they would do something like this:
SomeControl.Text = MyClass.Translate(”Some English String”);
Another cool thing I was able to add was to use String.Format in the class so:
SomeControl.Text = MyClass.Format(”Some English String {0} {1}”, arg1, arg2);
was possible. One of the issues that translators had was converting some of the sentences that had variables injected into them. So this gives them more flexibility.
One thing I did find out about some of the Telerik controls was that you had to translate the English strings by overriding the OnInit page event. You even had to translate the strings prior to calling base.OnInit(e) in order for the translated strings not to be replaced with the English strings during rendering. In most cases the translation could be done in Page_Load.