brain dust

The Absolute.

Monday, May 09, 2005

Localization Method

Localization (or Globalization, depending on who you are talking to)] is quickly becoming a necessity in the web programming world. It is on of the key requirements of my Web Application Framework. But I have never liked the method that Microsoft has employed for several reasons:

1. It splits up, based on Languages, for the same resources into separate files/dll's. If you want to add French then you have to create a French version of the resource file for each resource that you have. On large applications that may mean tons of files. The real issue here comes down to manageability. If you miss resource, the page will break because it cannot find that file.

2. It’s too complex for translation vendors to work with. The resource document is in XML, but it is not simple XML. There's a lot of overhead that has to deal with collections and typing of elements. It is completely unnecessary.

3. I have never liked having to compile resources. They are resources. It should be taken care of by the application when a new one shows up on the scene.


My solution involves having all pages derive from a custom page class, which is in line with my Application Framework anyway. I have exposed a new property in the base class called LanguageFile. The idea is that if you define the language file by name (and the main requirement here is that the file exist in the same directory as the called aspx file, which to me also makes it easier to manage), then the Framework will attempt to localize the page at runtime for you. That's right, it will do it for you! No more freakin "mylabel.Text = ResourceFetherThingy.GetString("Resourcefilelocation.xml", "thisresourcekey")"!

How does this work you ask? It's oh so simple: The Framework recursively goes through the controls on the page. For each control it internally tries to apply the resource string. It does this by assuming that you have an item for this control in this requests language. If it can't find the string for that language it tries to default to en-US. If it can't find anything, then it does nothing. The language files in question are super-simple XML documents that do nothing but hold a collection of resource strings. Because at the end of the day what you need translated are either just simple strings or images which you can also use as pointers to in this method. And since we are talking true XML documents anyway, the Framework also caches them eternally with a dependency on the file itself. So, as long as the application lives and the document doesn't change, your localized resource strings stay in memory. Super-duper fast!

Please note that I have also exposed the actual method that gets the string from the file, GetTranslatedString(“filename.xml”, “ResourceKey”). So you could conceivably handle things that were more dynamic in nature and override what the Framework is trying to do.

Here’s an example of the XML document:

































When I want to add French I just send these simple to read XML documents to my transation company, and when they send them back and I have validated them, then I just copy them to their respective directories and the app is now supporting French!

I like this solution so much that I am going to make it available publicly, probably on GotDotNet.com, as a component.

Friday, May 06, 2005

Updated Multi-Tenent Requirements List

This is an updated list of the requirements for my multi-tenent framework:

Be a multi-tenent web based system.
Support multiple applications.
Be multi-lingual.
Provide developers granular control over linguistics.
Provide Menuing Subsystem to pages (both page based menus and context based menues).
Provide default context sensitive user information at the page level.
Pages can exist as multiple instances per program.
Provide mechanism to allow developers to manage pages within their given applications.
Be farmable.
Applications need to be able to talk to databases different from the Framework database.
Provide mechanism to allow a developer to expose different security contexts within a page.
Provide a form submit and cancel mechanism.
Provide a form wizard control.
Provide in page control type switching by menu.
Provide user feedback on security access within a page.
Provide a way for a developer to send a user to another page and land in a particular security context.
Provide generic error handling.
Provide page versioning within the application/framework.
Provide high-level security.
Provide roles based security.
Provide skin-ability.
Provide ability to offer different UI layouts.

While I have most of the actual Framework Runtime complete, I have just started on the management UI.