在 Wicket 中使用参数化 UI 消息的简单方法?
Wicket 有一个灵活的国际化系统,支持以多种方式参数化 UI 消息。例如 StringResourceModel javadocs 中有一些示例,例如:
WeatherStation ws = new WeatherStation();
add(new Label("weatherMessage", new StringResourceModel(
"weather.${currentStatus}", this, new Model<String>(ws)));
但是我想要一些真正简单的东西,但找不到一个很好的例子。
考虑 .properties 文件中的这种 UI 消息:
msg=Value is {0}
具体来说,我不想仅出于此目的创建模型对象(使用要替换的值的 getter;如上面示例中的 WeatherStation)。如果我已经拥有局部变量中的值,那么这就有点矫枉过正了,否则就不需要这样的对象了。
这里有一个愚蠢的“蛮力”方法,可以用正确的值替换 {0}:
String value = ... // contains the dynamic value to use
add(new Label("message", getString("msg").replaceAll("\\{0\\}", value)));
是否有一种干净、更符合 Wicket 风格的方法来执行此操作(并不比上面的方法长太多) )?
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)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
看一下 StringResourceModel javadoc 中的示例 4 - 您可以传递 null 模型和显式参数:
Take a look at Example 4 in the StringResourceModel javadoc - you can pass a null model and explicit parameters:
我认为最一致的WICKETY方式可以通过改进Jonik 的回答
MessageFormat
:.properties:
.java:
为什么我喜欢它:
StringResourceModel
重用这些属性。注意:
如果您想使用模型,您只需要创建一个简单的模型来重写模型的 toString 函数,如下所示:
并将其作为 MessageFormat 参数传递。
我不知道为什么Wicket在反馈消息中不支持
Model
。但如果它受到支持,就没有理由使用这些解决方案,您可以在任何地方使用 StringResourceModel 。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.有一种方法,虽然仍然涉及创建模型,但不需要带有 getter 的 bean。
在属性文件中给出此消息:
以下是如何用值替换占位符,无论是局部变量、字段还是文字:
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:
当面对问题中描述的问题时,我现在会使用:
.properties:
Java:
Why I like it:
${}
技巧不同)。 编辑:好吧,如果您实际上需要支持多种语言,其中替换的值可能采用不同的顺序,String.format()
是不行的好的。相反,使用 MessageFormat 是一种类似的方法,可以正确支持这一点。免责声明:这“太明显了”,但它比其他解决方案更简单(并且绝对比我原来的
replaceAll()
hack 更好)。我最初寻求一种“Wicket-y”方式,虽然这种方式绕过了 Wicket——话又说回来,谁在乎呢? :-)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? :-)如果您的组件中有一个模型,其中包含一个对象,其中包含您想要从占位符访问的值作为替换,您可以编写:
让我们假设
getModel()
的返回类型是IModel< ;User>
和User
包含诸如firstName
和lastName
之类的字段。在这种情况下,您可以轻松访问属性字符串中的firstName
和lastName
字段:您可以在此处找到更多信息: https://ci.apache.org/projects/wicket/apidocs/8.x/org/apache/wicket/model/StringResourceModel.html#StringResourceModel-java.lang.String-org.apache.wicket.model.IModel-
In case you have a Model in your Component which holds an object with values you want to access from your placeholders as substitutions, you can write:
Let's imagine
getModel()
's return type isIModel<User>
andUser
contains fields likefirstName
andlastName
. In this case you can easily accessfirstName
andlastName
fields inside your property string:Further information you can find here: https://ci.apache.org/projects/wicket/apidocs/8.x/org/apache/wicket/model/StringResourceModel.html#StringResourceModel-java.lang.String-org.apache.wicket.model.IModel-
为您的标签创建模型确实是The Wicket Way。也就是说,您可以通过偶尔使用实用功能来轻松实现这一点。这是我使用的一个:
我在这里掩盖的详细信息是:
ConvertingModel
,它将根据CustomLabel
应用自定义标签文本后处理(详见 这个答案)使用自定义 IConverter(例如温度对象),您可能会得到类似的结果:
这种方法的缺点是您不再能够直接访问标签类,您不能将其子类化以覆盖
isVisible()
或类似的东西。但就我的目的而言,它在 99% 的情况下都有效。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.