there are now six versions of the resource bundle (rb) tool, the three major versions include:
- coreJava: if you don't need other calendars, locales, etc. offered by IBM's ICU4J library. this version uses core Java's Locale and MessageFormat classes. It will operate on any coldfusion host that permits createObject().
- icu4j: Requires the installation of IBM's ICU4J java library which can be obtained here. this version uses the library installed on cf's classpath. it makes use of ICU4J's ULocale, UResourceBundle, and MessageFormat classes. this allows for more locales than are supported by core Java as well as additional locale "keywords" such as calendar, currency and collation (for example, th_TH@calendar=buddhist).
- remoteICU4J: also requires the installation of IBM's ICU4J java library. this version uses a slightly modified "remote" classpath technique for installations where you don't have access to the classpath. you will need to specify the full path to a copy of the icu4j.jar file.
In each of these versions you will find two CFCs:
- javaRB which handles rb files that aren't on coldfusion's classpath (usually deployed on shared hosts)
- rbJava which uses rb files that are on coldfusion's classpath, this is usually the more robust form of this tool
You will also find:
- javaRB.cfm a simple testbed for the javaRB CFC
- rbJava.cfm a simple testbed for the rbJava CFC
- messageFormat.cfm a simple testbed demonstrating the messageFormat method
- testJavaRB.properties base rb file
- testJavaRB_en_US.properties en_US locale rb file
- testJavaRB_th_TH.properties th_TH locale rb file
public methods in the CFCs:
- getResourceBundle returns a structure containing all key/messages value pairs in a given resource bundle file. required argument is rbFile containing absolute path to resource bundle file. optional argument is rbLocale to indicate which locale's resource bundle to use, defaults to us_EN (american english)
- getRBKeys returns an array holding all keys in given resource bundle. required argument is rbFile containing absolute path to resource bundle file. optional argument is rbLocale to indicate which locale's resource bundle to use, defaults to us_EN (american english)
- getRBString returns string containing the text for a given key in a given resource bundle. required arguments are rbFile containing absolute path to resource bundle file and rbKey a string holding the required key. optional argument is rbLocale to indicate which locale's resource bundle to use, defaults to us_EN (american english)
- formatRBString returns string w/dynamic values substituted. performs messageFormat like operation on compound rb string: "You owe me {1}. Please pay by {2} or I will be forced to shoot you with {3} bullets." this function will replace the place holders {1}, etc. with values from the passed in array (or a single value, if that's all there are). required arguments are rbString, the string containing the placeholders, and substitute. Values either an array or a single value containing the values to be substituted. note that the values are substituted sequentially, all {1} placeholders will be substituted using the first element in substitute. Values, {2} with the second, etc. DEPRECATED. only retained for backwards compatibility. please use messageFormat method instead
- messageFormat returns string w/dynamic values substituted. performs MessageFormat operation on compound rb string. required arguments: pattern string to use as pattern for formatting, args array of "objects" to use as substitution values. optional argument is locale, java style locale ID, "th_TH", default is "en_US". for details about format options please see http://java.sun.com/j2se/1.4.2/docs/api/java/text/MessageFormat.html
- verifyPattern verifies MessageFormat pattern. required argument is pattern a string holding the MessageFormat pattern to test. returns a boolean indicating if the pattern is ok or not
In addition, the remoteICU4J CFCs also have another public method:
- getAvailableLocales returns an array of available locales. note that this method is only supplied as a convenience
PS: i've finally added a license.
It seems that with your cfc only one bundle can be load at a time, you set a struct for that. I am o looking for how to use the getbundle java method that could simplify a lot some tests and allow multiple ressource bundle to be loaded. I am stuck with classpath for pointing to ressource bundle. I was trying to set This.mappings with CF8 without results. I tried also more java woraround without results.
Do you have some contacts or other ideas that could help me ?
what exactly are you after?
I need to internationalize a web application with several plug-in or add-in. That mean I cannot centralize the ressource bundles files but I could centralise a function or an object. The other need is something nice to write while coding. I like the way php implements some i18n function like _("my string as a key"). This one is simple to use and do not require to look for keys but work has to be done on performances. I was thinking of convert the ressource bundle into a query object and add arguments for locale and an array of value for messageFormat. Lets see that tomorrow.
After reading posts and documentations (and spend 3 hours with CF mapping, getBundle, and javaload class, I started to write some object additions today. Like init() with variables like ressourceBundle as a struct, the list of ressource bundles loaded, the default language, an appendRessourceBundle("RB path"), resetRessourceBundle(),reoveRessourceBundle(). I was thinking also with a collegue to get better caching system. To put all bundles in the application scope and use a pointer with session scope to that. I am not sure what is the best for performances and memory.
It is also important to keep ICU4j to get ressource for calendar, plural, numericals and more.
I was very surprise that I could not find something I need already built by somebody with CF.
Do you have important recommendations or issues that could be done ?
sorry but i'm not following the "cannot centralize" rb issue. you can place the rb files anywhere you like & either make that part of the classpath or provide the full path to the dir holding them.
as far as caching goes, that's none of my business (well none of the CFCs business anyway). there are way too many different caching mechanisms to please everyone. i left that up to the main app. when clients want caching, i normally use application scope w/session locale, etc as the key but frankly depending on the application, etc. you can probably get away w/out this (ie simply reading the required rb per request).
as far as icu4j goes, i've placed several CFCs (mainly calendars) using it in the public domain. for instance:
http://www.sustainablegis.com/projects/icu4j/calendarsTB.cfm
http://www.sustainablegis.com/things.cfm
# The key consists of all characters on the line from the first non-white space character to the first separator. Separator characters can be included in the key by escaping them with a backslash (\) [...]
Testing a ressource bundle editor I was able to add a key with spaces and other strings. Then I used the javaRB.cfc and I get wrong results into the RB structure. It seems that a structure is not the good way to store the key. I was thinking to store the RB into q auery object. Do you think we could improve your classes to continu a community work for CF at RIAforge for example ?
I am not sure a blog is a best place for discussion but let's continue to share that with the community.
Second thing was to add other ressource bundles for an application with plugins, or centralize the management of the RB by the application (not where they are physically). I found a reference talking about that http://articles.techrepublic.com.com/5100-10878_11-1045670.html# that explain everything in details and gives examples.
I tried to store the RB into a query object but for performances that's very bad. Even with query cache. A structure seems to be the best way for performance issue to use RB and retrieve ressource with a key.
As I told you, the Ressource Bundle editor I used allow spaces and special characters. That's really not good because of the Java enumeration that does not manage that with nextElement() method. This is an issue that developers must be aware.
Now I changed completly my strategy. I will do your way. I think with Java and Coldfusion that's the best. I will put everything in one structure and StructAppend(struct1,struct2,false) for the different RB plugins that I have to load. Caching doesn't seems to be necessary.
I will do also a quick workaround with classpath and CF to see what is the best.
I will not work anymore on how to use a sentence as a key. That is more a Java work.
Could you post your CFCs into Riaforge to push CF community work ?
Again thank you to share your CFCs, for talk and for your work on i18n.

