Loom messages are stored in a MessagesRepository instance specific to each Locale and configured by MessagesRepositoryFactory. MessagesRepository is very similar to the ResourceBundle class included in the JDK.
This is the default MessagesRepository implementation. While in development mode, this class will be aware of any modification to any of its properties files and will reload them as needed. It can only detect changes to files that are not loaded from the classpath.
By default it will use classpath:resources/loom-messages.properties (provided by loom.jar) and /WEB-INF/classes/resources/messages.properties. The latest is where the application is expected to store its own messages.
Note that if a specific Locale is not found the system will fallback to MessagesRepositoryFactory.defaultLocale or the Operating System Locale, if unspecified.
Messages may include parameters:
loom.validation.dateMaxValueFailed=The value of ${propertyName} is bigger than the maximum allowed (${validator.maxValue.date})
When setting parameter values you must indicate if they should be translated or not:
Message message = new Message();
message.setMessageKey("loom.validation.dateMaxValueFailed");
message.addArg("validator", validator);
message.addTranslatedArg("propertyName", "customer.name");
The guessString() method is invoked to translate messages: when asked for "customer.manager.name" it will first search the whole string, then "manager.name", then "name". If none is found it will return "[missing: customer.manager.name]" and mark it as not found to skip further searches.
Guess results are calculated just once to avoid hurting performance.
Missing messages are stored in a missing-messages.properties file in the temporal system folder (%TEMP% in windows, $TEMP in *NIX, and $CATALINA_HOME/temp if you are using tomcat). During development it is usually easier to just start browsing the application and retrieve the messages from this file.
The browser will get a JSON copy of the messsages bundle for the current user locale. This copy will include:
Thus, these two examples are equivalent:
spring.xml:
<loom:config> <loom:messages browserMessages="payment.commit payment.rollback edit.approve"/> </loom:config>
MyAction.java
@BrowserMessages({"payment.commit", "payment.rollback", "edit.approve"})
public class MyAction extends AbstractAction {
}
Both will generate a JSON object that can be used at the browser with:
<l:script action="Resources"/> <script> alert(loom.messages['payment.commit']); </script>
There are several ways to print i18n contents inside your JSP pages:
<!-- Print foo -->
<l:out value="foo" />
<!-- Print foo -->
${messages['foo']}
<!-- Print foo (translated) if printFoo is true; else, print bar (translated) -->
<l:out value="foo" if="${printFoo}" else="bar"/>
<!-- Print foo (translated) if printFoo is true; else, print bar (translated) -->
${messages[printFoo? 'foo' : 'bar']}