PDA

View Full Version : Ext.LocaleLoader, to dynamically load and apply your locale files (ExtJS + MVC)



TigrouMeow
2 Sep 2011, 2:22 AM
Hello,

I worked on a localization manager / loader recently because I really required a dynamic behavior which fits ExtJS 4 and MVC. I tried the "official" localization examples, as well as the very recently posted "LocaleManager", but it's not what I was looking for. I hope this will help some of you as well :)

I still need to test it (tested on Google Chrome only) and enhance it a bit more.

I posted the project on GitHub, at this url:
https://github.com/TigrouMeow/extjs-locale-loader
(https://github.com/TigrouMeow/extjs-locale-loader)There is an example with it, please try it.

I'd love to get a some feedbacks :) Thanks! ~o)

pef
2 Sep 2011, 8:18 AM
Thanks !
I won't be able to look into this until next week, but I definitely need something like this : just to let you know that at least one person is interested :)

TigrouMeow
2 Sep 2011, 5:17 PM
Great :) I'm looking forward for your feedback!

SMMJ_Dev
3 Sep 2011, 5:34 AM
Nice, I can't wait to try this out when I get time. I am going to try it out for more than locale purposes. This may be good for our project specific naming conventions :):D

TigrouMeow
7 Sep 2011, 10:34 PM
Who did try it? Can't wait to get feedback on this :)

nosklo
19 Sep 2011, 8:37 AM
Hello TigrouMeow,

I'm very interested in your work, but my use case is slightly different, so I don't know if it would fit:

I'm trying to translate existing ExtJS classes. For example, the text on the grid column menu shows "Sort Ascending", and I want to translate that.

On Ext3 I've been including the locale/ext-lang-$language.js file to do that.

On Ext4, I found that Ext.grid.header.Container.prototype contains the string I want to change. But with dynamic loading, just including the locale file doesn't work, since it runs before extjs/grid/header/Container.js gets loaded by the framework. So I get error.

I'm wondering if your code could work for existing Ext classes, and how/where I should put the translations in that case. It would be wonderful if the translation for specific ExtJS file could load just after the actual file.

Any hints?

Thanks in advance
nosklo

TigrouMeow
20 Sep 2011, 1:40 AM
The right way would be to use the ExtJS locale files for that, for sure. The "LocaleLoader" doesn't take in charge the ExtJS locale files yet but it should... so it will :)

It's a bit tricky though, it would have to execute the content of the ext-lang-xx.js everytime a new widget class is loaded. I'm not sure how to do this yet, any idea ?

nosklo
20 Sep 2011, 11:42 AM
The right way would be to use the ExtJS locale files for that, for sure. The "LocaleLoader" doesn't take in charge the ExtJS locale files yet but it should... so it will :)
Thing is, existing ExtJS locale files are not working currently, for dynamic MVC loading. I can't just include it, because when it runs, Ext still didn't load the required classes yet, so it has nothing to apply the string changes to.
The only way I found to make existing locale files to work is to include ext-all.js thus defeating dynamic loading completely.



It's a bit tricky though, it would have to execute the content of the ext-lang-xx.js everytime a new widget class is loaded. I'm not sure how to do this yet, any idea ?

I think we could have something just like you did for your classes, but for Ext classes.

I mean, the same ext-lang-xx.js file wouldn't get executed many times over and over again. Instead, we could have a separate locale/xx/ClassName.js file for each existing ExtJS class, and it would get automatically loaded just after the original file.

Example:

Ext.grid.Panel would load extjs/grid/Panel.js and the LocaleLoader would kick in, loading locale/fr/grid/Panel.js

What do you think? Is that possible?

TigrouMeow
20 Sep 2011, 6:01 PM
I mean, the same ext-lang-xx.js file wouldn't get executed many times over and over again. Instead, we could have a separate locale/xx/ClassName.js file for each existing ExtJS class, and it would get automatically loaded just after the original file.

It's easy to do, but I don't think we should, mainly for two reasons:

we'd have to make available all the files in locale/xx, for every classes
there is a neat ExtJS locale file already, we shouldn't create anything on our own, and use this file instead
The only solution I see is that we must load this file at the beginning (dynamically, by the LocaleLoader, of course), then the LocaleLoader will re-execute the script after every ExtJS widget classes is loaded.

Let me try to implement this today, and let's see how it works

nosklo
21 Sep 2011, 6:49 AM
we'd have to make available all the files in locale/xx, for every classes
there is a neat ExtJS locale file already, we shouldn't create anything on our own, and use this file instead



Well, current ExtJS locale file doesn't work... It fails! Even when I use sencha tools to build my application, execution of code stops on the first unused/undefined class in the current locale file code.

Also, current ExtJS locale file is incomplete anyway - it seems to come unchanged from Ext3. There are lots of new classes and texts to translate on Ext4 classes that aren't mentioned on the current locale file.

To split the current locale file into multiple files isn't much work, and by doing it we would gain benefits:


no locale configuration for classes you're not using.
Ideally, in the final built and minified application, no reference to unused classes would show up since the locale part for those classes wouldn't even get included.
Seems easier to implement since no run-again trick is needed, we would just adapt your current code to load from different path

TigrouMeow
26 Sep 2011, 12:58 AM
Well, current ExtJS locale file doesn't work... It fails! Even when I use sencha tools to build my application, execution of code stops on the first unused/undefined class in the current locale file code.

Also, current ExtJS locale file is incomplete anyway - it seems to come unchanged from Ext3. There are lots of new classes and texts to translate on Ext4 classes that aren't mentioned on the current locale file.

To split the current locale file into multiple files isn't much work, and by doing it we would gain benefits:

no locale configuration for classes you're not using.
Ideally, in the final built and minified application, no reference to unused classes would show up since the locale part for those classes wouldn't even get included.
Seems easier to implement since no run-again trick is needed, we would just adapt your current code to load from different path


I successfully implemented my idea (with the current ExtJS locale files - but corrected, I had to remove the "Ext.onReady"). It works well, the only issue is that it executes the localization code too many times (more than necessary), but it's not enough to impact the performance anyways.

Is the ExtJS locale file fails for you every time you use it, or only during the build? It's maybe incomplete as well, but we can hope that one day Sencha will deliver a complete one. It's not our job do make those ones, is it? :p

About your idea now, I have a main issue. How would the LocaleLoader knows for which class it has to actually load the locale file? We can't possibly load for every single class in the framework.

nosklo
29 Sep 2011, 10:16 AM
I successfully implemented my idea (with the current ExtJS locale files - but corrected, I had to remove the "Ext.onReady"). It works well, the only issue is that it executes the localization code too many times (more than necessary), but it's not enough to impact the performance anyways.

So you have to modify the file anyway...



Is the ExtJS locale file fails for you every time you use it, or only during the build? It's maybe incomplete as well, but we can hope that one day Sencha will deliver a complete one. It's not our job do make those ones, is it? :p

Well, my current "job" is to make the program work, since that's what my boss is asking. :D

However, since extjs4 is lacking this dynamic locale support, my intention is to contribute back the code, since it is open source GPL code.

Ultimately, that makes it our job ;)

The existing locale file fails every time I try to use it with dynamic loading (as in including ext.js). If I use static loading (as in including ext-all.js like in the past with ext3) it works.

My guess is that sencha didn't touch locale files for ext3 -> ext4 transition - it is the same locale file used in ext3 so it can't work on the new class approach. It has to be changed anyway, I don't see why try to use it.

It is not just incomplete. It doesn't work.



About your idea now, I have a main issue. How would the LocaleLoader knows for which class it has to actually load the locale file? We can't possibly load for every single class in the framework.

It should use the name of the class being loaded:


Some requirement of some user class asks for a ext class, (example: Ext.form.field.ComboBox)
Existing ext loader code kicks in, loading the file based on the required class (example: it loads extjs/form/field/ComboBox.js)
LocaleLoader would use the same information (name of the class) to load a locale text overwriter for that class only (if it exists) from the path locale/fr/form/field/ComboBox.js

Steps 1 and 2 already work automatically in ext4 if you use ext.js (dynamic loading).

When any undefined class is requested by some code, ext dynamic loader kicks in and loads that class javascript file based on a simple convention (Ext.foo.bar.Baz becomes extjs/foo/bar/Baz.js). My idea was to use the same convention to load the locale (locale/LANGUAGE_HERE/foo/bar/Baz.js).

Susanta_bmc
29 Sep 2011, 5:05 PM
Hello,

I worked on a localization manager / loader recently because I really required a dynamic behavior which fits ExtJS 4 and MVC. I tried the "official" localization examples, as well as the very recently posted "LocaleManager", but it's not what I was looking for. I hope this will help some of you as well :)

I still need to test it (tested on Google Chrome only) and enhance it a bit more.

I posted the project on GitHub, at this url:
https://github.com/TigrouMeow/extjs-locale-loader
(https://github.com/TigrouMeow/extjs-locale-loader)There is an example with it, please try it.

I'd love to get a some feedbacks :) Thanks! ~o)


Thanks!!.. awesome job.... I implemented in our project today, it works great. But i was wondering in a bigger environment it will be difficult to maintain so many files, Can't we have a single file per locale. rather than for each class.

TigrouMeow
3 Oct 2011, 5:36 PM
Thanks!!.. awesome job.... I implemented in our project today, it works great. But i was wondering in a bigger environment it will be difficult to maintain so many files, Can't we have a single file per locale. rather than for each class.

Thanks a lot, great it works. Well, if you want to use only one file, this LocaleLoader loses a bit of its interest, but YES, it's possible, I can add a config option for that. Just tell me here when you really need it and I'll add the option.

TigrouMeow
3 Oct 2011, 5:40 PM
However, since extjs4 is lacking this dynamic locale support, my intention is to contribute back the code, since it is open source GPL code. Ultimately, that makes it our job ;)


True!



It should use the name of the class being loaded:

Some requirement of some user class asks for a ext class, (example: Ext.form.field.ComboBox)
Existing ext loader code kicks in, loading the file based on the required class (example: it loads extjs/form/field/ComboBox.js)
LocaleLoader would use the same information (name of the class) to load a locale text overwriter for that class only (if it exists) from the path locale/fr/form/field/ComboBox.js
Steps 1 and 2 already work automatically in ext4 if you use ext.js (dynamic loading).

When any undefined class is requested by some code, ext dynamic loader kicks in and loads that class javascript file based on a simple convention (Ext.foo.bar.Baz becomes extjs/foo/bar/Baz.js). My idea was to use the same convention to load the locale (locale/LANGUAGE_HERE/foo/bar/Baz.js).

This is easy to add as it's the current behavior of LocaleLoader of the custom classes. However you don't think that it's going to be a hell of a bunch of files to translate? There will be really many! Don't you think that it's an issue?

Susanta_bmc
3 Oct 2011, 6:39 PM
Thanks a lot, great it works. Well, if you want to use only one file, this LocaleLoader loses a bit of its interest, but YES, it's possible, I can add a config option for that. Just tell me here when you really need it and I'll add the option.

Thanks,Whenever you are ready/publish it let me know i will download it from there.
Please correct me on this:


to get existing ExtJS classes. like the text on the grid column menu shows "Sort Ascending",


I just need to pass the value to extLocalePath in setLocale right?


For example:


Ext.Loader.setLocale({
enabled: true,
//This locale will be driven through the user input
language: Ext.getDom('locale-holder').getAttribute('locale'),
localizedByDefault: false,
extLocalePath:'/itm/include/ext-4.0.6/locale',
types: [ 'view' ]
});

Susanta_bmc
3 Jan 2012, 8:24 AM
Hi TigrouMeow,

I found an issue with the ext-locale-loader, So thought of to share with you,

When i used German locale( de), while using the Ext.util.Format.number , I got to see that the browser is throwing a out of memory exception, On debugging i found that it is happening at: ext-lang-de.js at the line


return Ext.util.Format.__number(v, format || "0.000,00/i");


In the below shown code.


if(Ext.util.Format){
Ext.util.Format.__number = Ext.util.Format.number;
Ext.util.Format.number = function(v, format) {
return Ext.util.Format.__number(v, format || "0.000,00/i");
};

Ext.apply(Ext.util.Format, {
thousandSeparator: '.',
decimalSeparator: ',',
currencySign: '\u20ac', // German Euro
dateFormat: 'd.m.Y'
});
}



So I commented out the


Ext.util.Format.__number = Ext.util.Format.number;
Ext.util.Format.number = function(v, format) {
return Ext.util.Format.__number(v, format || "0.000,00/i");
};



As i did not see anything of these in fr locale though the "," is the decimal separator in Fr locale. Infact I did not see the above code piece anywhere other than German locale.

upon commenting the formatting was fine.

I created the same error with this sample code(cellediting.zip).

1. If you are using IE 8 you gonna see something like this. Out of Memory at line 5753.
2. The attached code has been implemented with MVC, with a ext-locale-loader.js, which loads the localized strings as been configured in app.js

something like this:


Ext.Loader.setLocale({
enabled: true,
language: 'de',
localizedByDefault: false,
extLocalePath:'/ext-4.0.6/locale',
types: [ 'controller', 'view' ]
});


3. I am using Ext 4.0.6 in this example but the same issue is there in 4.0.7

4. Just for the test i have put a line in CellEditingController.js at line number 19:


var formatednumber = Ext.util.Format.number(2.34, '0.0000');


Please let me know if you have more questions.

vitorpfn
25 Jul 2013, 2:21 PM
it's possible have a combobox with some languages and when the user change his value, make a refresh on all views with this plugin? thanks