If you elect not to use property files for your resource bundles, or need to expand your i18n implementation to include content pulled from other sources, the module allows for the specification of a customResourceService in the configuration.
To begin, create a custom resource service which extends the core i18n resource service:
To override the resource bundle used, you would declare a new loadResourceBundle method. To override the implementation of the getResource( i18nResourceLabel ) you would declare a new getResource method. An example, using your database to retrieve an i18n resource bundle:
Lets say we want to account for a more complex metadata structure in our resource bundles. For example, allow a draft value to allow for administrators to see which items in our bundle are pending review but display the default value to the public. We might also want to add any new resource requests containing a default value as drafts in the system (which we won't cover here). For special circumstances, such as these, we would need to change the implementation of the getResource method to account for this draft functionality:
public string functiongetResource(// The resource (key) to retrieve from the main loaded bundle. required any resource,//A default value to send back if the resource (key) not found any default,//Pass in which locale to take the resource from. By default it uses the user's current set locale any locale="#VARIABLES.i18n.getfwLocale()#",//An array, struct or simple string of value replacements to use on the resource string any values,//default any bundle="default"){//prevent errors via empty label strings from being passedif( !len( trim(resource) ) ) return resource;//protect from a bad locale value being passedif( !len( trim( arguments.locale ) ) ) arguments.locale =VARIABLES.i18n.getfwLocale();var thisLocale = arguments.locale;var resourceString ="";var rBundles =Controller.getSetting("RBundles");var currentUser =Wirebox.getInstance( "SessionService" ).getCurrentUser();if( !structKeyExists( rBundles, arguments.locale ) ){loadBundle( rbLocale=arguments.locale, rbAlias=arguments.bundle ); }var resourceBundle = rBundles[ arguments.locale ];if( structKeyExists( resourceBundle, arguments.resource ){ var resource = resourceBundle[ arguments.resource ];if( resource.published ){returnformatResourceObject( resourceObj=resource, args=arguments ); } else if( !resource.published && currentUser.isAdministrator() ) {returnformatDraftResource( resourceObj=resource, args=arguments ); } } else if( !isNull( arguments.default ) ) {if( !isNull( arguments.values ) ){returnformatRBString( arguments.default, arguments.values ); } else {return arguments.default; } } else { return renderUnknownTranslation( arguments.resource ); }}
The ability to extend and implement custom resource services provides you with a great deal of flexibility in your internationalization efforts. Use cases might include database-driven i18n resources, distributed caching implementations, and variable bundle formats used in third-party tools and plugins.