BoxLang ๐ A New JVM Dynamic Language Learn More...
Copyright Since 2005 ColdBox Platform by Luis Majano
and Ortus Solutions, Corp
www.coldbox.org | www.ortussolutions.com
Professional internationalization (i18n) and localization support for
ColdBox applications. CBi18n provides a comprehensive solution for
building multilingual applications with support for both traditional
Java .properties
files and modern JSON resource bundles.
.properties
and JSON resource bundles# Install via CommandBox
box install cbi18n
// config/ColdBox.cfc
moduleSettings = {
cbi18n: {
defaultResourceBundle: "includes/i18n/main",
defaultLocale: "en_US",
localeStorage: "cookieStorage@cbstorages",
unknownTranslation: "**NOT FOUND**"
}
};
# Create your resource bundle files
# includes/i18n/main_en_US.properties
user.welcome=Welcome {1}!
user.logout=Logout
# includes/i18n/main_es_ES.properties
user.welcome=ยกBienvenido {1}!
user.logout=Cerrar Sesiรณn
// In handlers, views, layouts
var welcomeMsg = getResource("user.welcome", "", "", ["John"]);
// Or use the shorthand
var logoutText = $r("user.logout");
// Change user's locale dynamically
setFWLocale("es_ES");
CBi18n automatically registers the following models in WireBox:
Service | WireBox ID | Description |
---|---|---|
i18n Service | i18n@cbi18n
| Main service for locale management and resource retrieval |
Resource Service | resourceService@cbi18n
| Handles resource bundle loading and parsing |
You can override the default ResourceService by providing a
customResourceService
in your configuration:
moduleSettings = {
cbi18n: {
customResourceService: "MyCustomResourceService@mymodule"
}
};
For more information, see Custom Resource Services.
Configure CBi18n in your config/ColdBox.cfc
under moduleSettings
:
moduleSettings = {
cbi18n: {
// The base path of the default resource bundle to load
// Path + resource name but excluding _locale.extension
defaultResourceBundle: "includes/i18n/main",
// The default locale of the application (Java format: lang_COUNTRY)
defaultLocale: "en_US",
// Storage service for user's locale persistence
// Use any CBStorages service with full WireBox ID
localeStorage: "cookieStorage@cbstorages",
// Text displayed when a translation is not found
unknownTranslation: "**NOT FOUND**",
// Enable logging of missing translations to LogBox
logUnknownTranslation: true,
// Additional resource bundles to load
resourceBundles: {
"admin": "modules/admin/includes/i18n/admin",
"emails": "includes/i18n/emails"
},
// Custom ResourceService implementation (optional)
customResourceService: ""
}
};
Each ColdBox module can have its own resource bundles. Configure them
in your ModuleConfig.cfc
:
function configure(){
cbi18n = {
defaultLocale: "es_SV",
resourceBundles: {
// Alias => path within module
"module@mymodule": "#moduleMapping#/includes/i18n/module"
}
};
}
Leverage any CBStorages service for locale persistence:
cookieStorage@cbstorages
- Browser cookies (default)sessionStorage@cbstorages
- Server sessioncacheStorage@cbstorages
- Distributed cacheclientStorage@cbstorages
- Client variables// Simple resource lookup
var message = getResource("welcome.message");
// With default value
var title = getResource("page.title", "Default Title");
// Using shorthand alias
var error = $r("validation.required");
// Resource: user.greeting=Hello {1}, you have {2} messages
var greeting = getResource(
"user.greeting",
"",
"",
["John", "5"]
); // Returns: "Hello John, you have 5 messages"
// Get current user's locale
var currentLocale = getFWLocale(); // e.g., "en_US"
// Change user's locale (automatically loads resource bundles)
setFWLocale("es_ES");
// Get resource in specific locale
var spanishTitle = getResource("page.title", "", "es_ES");
// Get resource from specific bundle
var adminMsg = getResource("dashboard.title", "", "", [], "admin");
// Bundle structure in memory:
// {
// "default": { "en_US": {...}, "es_ES": {...} },
// "admin": { "en_US": {...}, "es_ES": {...} }
// }
# main_en_US.properties
user.welcome=Welcome {1}!
user.logout=Logout
error.required=This field is required
# main_en_US.json
{
"user": {
"welcome": "Welcome {1}!",
"logout": "Logout"
},
"error": {
"required": "This field is required"
}
}
This module announces an onUnknownTranslation
interception. The data
announced is a struct with the
following format:
{
resource = ...,
locale = ... ,
bundle = ...
}
CBi18n injects the following helper functions into all ColdBox components (handlers, views, layouts, interceptors):
/**
* Get the user's currently set locale or default locale
* @return string Current locale (e.g., "en_US")
*/
function getFWLocale()
/**
* Set the locale for a specific user
* @locale The locale to set (Java format: en_US)
* @dontLoadRBFlag Skip loading resource bundle for the locale
* @return i18n Service instance
*/
function setFWLocale(string locale="", boolean dontloadRBFlag=false)
/**
* Retrieve a resource from a resource bundle with replacements
* @resource The resource key to retrieve
* @defaultValue Default value if resource not found
* @locale Specific locale to use (defaults to user's locale)
* @values Array/struct/string of replacement values
* @bundle Bundle alias for multiple resource bundles
* @return string Localized resource string
*/
function getResource(
required resource,
defaultValue,
locale,
values,
bundle
)
// Shorthand alias for getResource()
function $r(...)
/**
* Get direct access to the i18n service
* @return i18n@cbi18n service instance
*/
function i18n()
/**
* Get direct access to the resource service
* @return resourceService@cbi18n service instance
*/
function resourceService()
Apache License, Version 2.0. See LICENSE file for details.
CBi18n is a professional open-source project by Ortus Solutions.
Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
www.coldbox.org | www.ortussolutions.com
Because of His grace, this project exists. If you don't like this, then don't read it, its not for you.
"Therefore being justified by faith, we have peace with God through our Lord Jesus Christ: By whom also we have access by faith into this grace wherein we stand, and rejoice in hope of the glory of God. And not only so, but we glory in tribulations also: knowing that tribulation worketh patience; And patience, experience; and experience, hope: And hope maketh not ashamed; because the love of God is shed abroad in our hearts by the Holy Ghost which is given unto us." Romans 5:5
"I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" John 14:1-12
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
setFwLocale
should allow only valid values as well by @GunnarLiebgetFwLocale
should check if the requested locale is valid, else, default to the default one, this protects against cookie corruptionannounce()
Resourceful@cbi18n
cbStorages
dependency on the box.json
causes failures upon installationlocaleStorage
. Basically, we map the incoming locale storage from the old approach: session,client,cookie,request
to the cbStorages
equivalentonUnknownTranslation
thanks to @wpdebruinCookieStorage
is now used as the default for storing localesproperties
json
thanks to @wpdebruini18n()
mixin helper to get easy access to i18n methodsresoureService()
mixin helper to get easy access to the resource service model.properties, .json
) is what determines the resource type to usei18n
settings. You know will use the normal moduleSettings
with a cbi18n
key for settingscbi18n
top level key for configuration for each moduleDefaultLocale
in storage now renamed to CurrentLocale
dontloadRBFlag
removed as it was never used anymore.Improvement
: Updated to new template styleImprovement
: ColdBox 5 updatesImprovement
: Moved i18n listener to afterAspectsLoad to avoid module loading collisionsBug
: Invalid instance
scope usage in modelsgetTZoffset()
thanks to Seb DugganlogUnknownTranslation
getRBKeys()
and getRBString()
to load correct file paths.
$
box install cbi18n