Closed maxwellt closed 6 months ago
At work we have extra methods that localize a number, money, currency etc., which has the benefit that you don't need to know the oddities of message support. Also, if you change the parameter format you don't have to adjust that for all translations.
For instance, the key would simply be this:
total.key=Your total is {0}
And used like this:
${localize("total.key", localize(money))}
Sure, that's certainly one way to go, but when using something like ChoiceFormat it make it slightly harder again (not impossible but it would feel a bit hacky):
You have {0, choice, 0#no messages|1#a message|2#two messages|2<{0, number, integer} messages}.
printing out:
localize("key", 0) -> You have no messages.
localize("key", 1) -> You have a message.
localize("key", 2) -> You have two messages.
localize("key", 3) -> You have 3 messages.
Oh, that's right. In fact, we have a localizePlural() exactly for this purpose..
Maybe you could implement only that using MessageFormat?
Otherwise you could try to create some kind of MessageFormatAwareLocalizationSupport.
I will look into it if it's possible and report back here :-).
I had a look at it and came to the conclusion that the only thing I really need to do is HtmlEscape the incoming params myself and then sending the sanitizedParams to the Java MessageSource, in that case there's no need for the LocalizationSupport
anymore as that's basically what it does for me.
So this is what my JteContext
method looks like that can be called from a template:
public static Content get(String key, Object... params) {
Object[] sanitizedParams = Arrays.stream(params)
.map(param -> StringEscapeUtils.escapeHtml4((String) param))
.toArray();
// it's safe to use writeContent because the variables have been sanitized
return (output) -> output.writeContent(TranslateService.getMessage(key, sanitizedParams));
}
Nice, yes that should do the trick.
In order to do internationalization I have implemented the
LocalizationSupport
interface as per the instructions in the JTE documentation.The issue I'm facing is that if you want to make use of Java's MessageFormat, which can have a message value like:
Your total is {0, number, currency}
If you use the
LocalizationSupport
the method you need to implement does the message key lookup, the returned value will then be the message above, butLocalizationSupport
doesn't know how to interpret this.If I bypass the
LocalizationSupport
and usewriteContent
for messages without params andwriteUserContent
for messages with params I don't get the advantage thatLocalizationSupport
offers, which will only usewriteUserContent
when substituting the placeholders for their values, which means a message likeHello <b>{0}</b>
becomes impossible because the message contains variables so I would write the complete message usingwriteUserContent
.Is there any way I can get the best of both worlds?