Wicket has a flexible internationalisation system that supports parameterising UI messages in many ways. There are examples e.g. in StringResourceModel javadocs, such as this:
WeatherStation ws = new WeatherStation();
add(new Label("weatherMessage", new StringResourceModel(
"weather.${currentStatus}", this, new Model<String>(ws)));
But I want something really simple, and couldn't find a good example of that.
Consider this kind of UI message in a .properties file:
msg=Value is {0}
Specifically, I wouldn't want to create a model object (with getters for the values to be replaced; like WeatherStation in the above example) only for this purpose. That's just overkill if I already have the values in local variables, and there is otherwise no need for such object.
Here's a stupid "brute force" way to replace the {0} with the right value:
String value = ... // contains the dynamic value to use
add(new Label("message", getString("msg").replaceAll("\\{0\\}", value)));
Is there a clean, more Wicket-y way to do this (that isn't awfully much longer than the above)?
Creating a Model for your Label really is The Wicket Way. That said, you can make it easy on yourself with the occasional utility function. Here's one I use:
Details I'm glossing over here are:
ConvertingModel
which will automatically convert objects to their String representation based on the IConverters available to the given componentCustomLabel
that applies custom label text post-processing (as detailed in this answer)With a custom IConverter for, say, a Temperature object, you could have something like:
The downside to this approach is that you no longer have direct access to the Label class, you can't subclass it to override
isVisible()
or things like that. But for my purposes it works 99% of the time.When faced with something like described in the question, I would now use:
.properties:
Java:
Why I like it:
${}
trick). Edit: well, if you actually need to support many languages where the replaced values might be in different order,String.format()
is no good. Instead, using MessageFormat is a similar approach that properly supports this.Disclaimer: this is "too obvious", but it's simpler than the other solutions (and definitely nicer than my original
replaceAll()
hack). I originally sought for a "Wicket-y" way, while this kinda bypasses Wicket—then again, who cares? :-)Take a look at Example 4 in the StringResourceModel javadoc - you can pass a null model and explicit parameters:
I think the most consistent WICKETY way could be accomplished by improving Jonik's answer with
MessageFormat
:.properties:
.java:
Why I like it:
StringResourceModel
.Notes:
if you want to use Models you simply need to create a simple model that override
toString
function of the model like this:and pass it as
MessageFormat
argument.I don't know why Wicket does not support
Model
in feedback message. but if it was supported there was no reason to use these solutions and you could useStringResourceModel
everywhere.There's a way, which although still involves creating a model, doesn't requires a bean with a getter.
given this message in a properties file:
Here's how to replace the placeholder with a value, be it a local variable, a field or a literal: