In a previous article, I blogged about Flex i18n[1] and an “Inversion of Control” (IOC) approach to radically simplify localization issues within your Flex solutions. That article discussed the issues with the current, traditional localization implementations [used in Flex applications] and then presented the new LocalizationMap solution.
In this Part 2 on Flex l10n solutions, I offer a video tutorial, a demo of a Registration application localized to support Spanish and English, and an architecture diagram of LocalizationMap usages.
Also included with the live Flex demo is source code for both the demo and the l10n LocaleMap library.
Below is a screencast video tutorial; in which I provide a narrated overview of the issue involved with enabling your Flex application to support multiple languages (and locales). I also present LocalizationMaps as a great solution to easily and rapidly provide l10n (localization) features within your custom Flex apps.
Note that the video/podcast tutorial may take 5-10 seconds for streaming to start.
Shown below is a live demo of the localized Registration application. This application has l10n (localization) support for English and Spanish. In the live demo, select the Spanish or English flags to change the current locale. Watch what happens to all the strings and styles.
Be sure to complete the registration fields and click the Register button to see the view state changes to show a localized Thank you with fullname and email parameters (sounds confusing… just try it)!
Simply right-click to access the source code for both the demo and the l10n LocaleMap library. Or click here to download the source code. Before you review the source code, however, I encourage you to review the architecture diagram shown Figure 3 and listen to the Screencast tutorial (Figure 1).
Here is a high-level diagram that illustrates how the LocalizationMap is used within your custom applications. I encourage you to conceptualize the LocalizationMap as a plug-in to your application… an extension that is completely transparent (hidden) from your presentation/GUI layer.
Attention Developers!
Source code and sample projects are now under version control and available on GitHub:
Source Code
Sample Applications
Great! I have added a setup guiide on your github wiki for how to setup flashbuilder 4. http://wiki.github.com/ThomasBurleson/l10nInjection_Samples/
Hope it helps!
Great solution. Has anyone tried this with a XMLList with menuitem elements which is DataProvider for a MenuBar? I’m able to set the “label” property via map, but the change does not appear. Regards
Sascha,
I imagine you are replacing elements or attributes of elements in the XMLList? If so, then the menubar will not update because XMLList does not support databinding notifications. Or are you injecting an entirely new XMLList instance?
Note that your resource bundles can contain embedded XML datasets. These datasets can then be injected on the fly by the l10n injectors.
Please report this as a bug or issue on l10n Injection Git Hub. It would be helpful if you also attached [to the issue] source for a sample app that demonstrates this issue. I will review and attempt to propose or provide a viable solution.
-ThomasB
great article!
I tried to create a ResourceProxy programmatically doing:
var rp:ResourceProxy = new ResourceProxy(obj,
“label”,”app.control.bar.maintenance”);
But Error 1009 is traised. (obj is not null)
¿is it this correct?
thanks!
You discovered a bug in the ResourceProxy constructor; a bug which the <ResourceProxy /> tag implementation sidesteps.
I have fixed that issue; please check the Git Repository for updated code.
- Developer Notes -
ResourceProxy only establishes the mapping to the target. It does not do the injection. It is the ResourceInjector or SmartResourceInjector that iterates all the ResourceProxy instances and performs the injection action for each. So when using a programmatic approach, don’t forget to register your ResourceProxy instances [1 or more] into the registry property of a <ResourceInjector /> instance.
Hi, yes it’s very nice solution. I really like your idea. But. I understand how to set ResourceProxy target for view components inside main window via chain references.
But I have no idea how can I set ResourceProxy target for e.g. Labels placed in view which is dynamically created via PopUpManager? I don’t have reference to such view in Application to inject that view into LocalizationMap.
(In your RegistrationDemo_i18n example you pass SignInPage reference into LocalizationMap via signInPage=”{signIn}”. But how to pass view reference into LocalizationMap if you create that view instance dynamically via PopUpManager?)
How can I do it? Did I miss something?
ThanX,
//pyso
When you do not have a reference to a specific view instance or you have multiple instances, you should look at the SmartResourceInjector tag:
<:SmartResourceInjector target=”{RegistrationForm}”>
<PropertyInjector targetKey=”lblEmailHint.text” source=”{account}” sourceKey=”email” />
</SmartResourceInjector>
What this does is “watch” for any instantiations of the RegistrationForm class. When that class is ready [determined by listening for creationComplete event internally ], the value of account.email is INJECTED into the <instance RegistrationForm>.lblEmailHit.text property. In fact, the injection occurs for ALL instances of RegistrationForm… since SmartResourceInjectors cache all instances [until they are removed from the stage]. And – even better – if you only want instances with SPECIFIC ids to be cached, then you can also use the targetID=”" property of the SmartResourceInjector.
Hi Thomas,
Thanks. This is really great.
I have just started trying it on a new project.
Thanks again.
Thanks for the support/help! Fantastic solution! As Alexander said, “nicely done!”
Great! Can we use this framework with other flex framework, such as Swiz? Do I have to bring in mate dependency?
Thanks again1
The l10nInjection.swc contains all the localization and core Mate files you will need. This library can be used with PureMVC, Swiz, Cairngorm, etc. If you use this library with the Mate framework, make sure this library is loaded FIRST, since some of the core Mate classes have been “tweaked” in the l10nInjection.swc.
Hi, Thanks so much for sharing this great work.
I can’t wait to use this in my project, we are uing mate now, btw. But I find there are many classes with the same name as mate has, such as “Binder”, I know there must have some different places, but how could I know which one was used when the app is running? Would you mind to give me any suggestions?
I find that you did many changes in those classes, so I couldn’t just use the one in mate.
The LocalizationMap uses the Mate core classes that have SOME refactoring and enhancements.
These changes should be released soon as a formal patch to the current Mate framework. Meanwhile [if you need l10n features] use the attached core Mate source for your Mate AND your localization needs.
Hi, very good work, thanks!
Localization worked fine in a new project. But i´m having some problems in my old projects that use mate. The problem is that Bind.bind (from your lib) expects 4 arguments, but mate´s expect 5. Then mate tries to pass 5 arguments to Bind.bind, but it was expecting 4. I tried to compile mate from source, replacing the source you provided, with no success. Do you have any workaround on this?
Thanks!
Pedro,
I discovered the issue. The l10nInjeciton library modified Binder.as and PropertyInjector.as with “refactoring improvements”. Unfortunately, this broke existing apps. And errors occurred: “Binder/bind() expected 4 but got 5 args”
I have fixed the Binder::bind() method to require 5 arguments (as originally defined in the original framework. I also fixed PropertyInjector to provide the “scope” as its first argument.
Attached is the revised l10nInjection source code [with the above fixes]. This should fix your issues. Also here is a link to the RegistrationDemo app with l10n code also updated. Plus here is a link to a sample app that demonstrates l10n injection with Flex 4 view states. Cool stuff!
Thank you for the feedback/issue reports.
This is fantastic! Sure would love to see a Mate example, instead of Cairngorm, but I’ll figure it out. Thanks so much for sharing this resource.
John,
Take any Mate sample application and you should be able to create a LocalizationMap without any changes to your existing source.
Simple create an instance of a LocalizationMap with custom injectors/proxies (also need the *.l10n.* packages included in the source).
Notice the com.thunderbay.locale.LocaleCommand in the RegistrationDemo’s source.
You need to dispatch an LocaleEvent.INITIALIZE event to auto detect the current OS locale, and your custom LocalizationMap will try to use that locale’s resources for injection…
all without changing your Mate view source or EventMaps.
You are a genius! nicely done!!! Pefect presentation! Thank you very much!!!