如何为表单组件正确创建国际化标签,以便在显示反馈消息时显示国际化字段名称而不是java代码中字段的名称?
我读过这个:
https://cwiki.apache.org/WICKET/everything-about-wicket-internationalization.html
以及wicket的xhtml标签的文档:
https://cwiki.apache.org/WICKET/wickets-xhtml-tags.html
<label wicket:for="name">
<wicket:label>
<wicket:message key="label.name"/>
</wicket:label>
</label>
<input wicket:id="name" type="text" wicket:message="placeholder:label.name" />
这会导致以下错误:
Last cause: Expected close tag for '<wicket:label>' Possible attempt to embed
component(s) '<wicket:message key="label.name"/>' in the body of this
component which discards its body
如果我用某些任意文本替换wicket:message
,它会在任何相关的反馈消息中显示该文本。
(有一个相关的jira问题:https://issues.apache.org/jira/browse/WICKET-3903但是我仍然不明白为解决这个问题做了什么以及我必须做些什么......)
刚刚发现有一种方法可以在java中执行此操作:
add(new TextField<String>("name").setRequired(true).setLabel(new Model<String>(getString("label.name"))));
是否有可能以更舒适的方式做到这一点?
答案 0 :(得分:4)
我刚测试了以下内容:
<form wicket:id="form">
<label for="input"><wicket:message key="input">some input</wicket:message></label>
<input wicket:id="input" type="text" name="input">
<input type="submit" value="submit">
</form>
在java类中:
Form<HomePage> form = new Form<HomePage>("form"
, new CompoundPropertyModel<HomePage>(this));
wmc.add(form);
TextField textField = new TextField("input");
textField.setRequired(true);
form.add(textField);
在我提供的属性文件中:
input=SomeInputField
这导致了以下屏幕(如果我将请求的字段留空并按提交。
这是你在找什么?
答案 1 :(得分:3)
以下是@bert's的另一种方法,它一直对我有效(不知道<wicket:label>
)
发生验证错误时FormComponent
显示的文本可以通过FormComponent.setLabel(IModel)
指定。显示的文字将是IModel
的{{1}}。
getObject()
请注意,这与TextField comp = new TextField("comp");
// Use internationalized text from XML resource file
comp.setLabel(new StringResourceModel("formResources.comp.label", this, null));
和FormComponentLabel
无关。 <label>
是可用于对FormComponentLabel
代码进行建模的组件。
您甚至可以将FormComponentLabel子类化为基于<label>
提供标签文本,并在需要该字段时输出额外的标记:
FormComponent.getLabel()
这样你会有干净的方式
public class MyLabel extends SimpleFormComponentLabel{
private boolean required;
public MyLabel (String id, LabeledWebMarkupContainer labelProvider) {
super(id, labelProvider);
if (labelProvider instanceof FormComponent){
required = ((FormComponent)labelProvider).isRequired();
}
}
protected void onComponentTagBody(final MarkupStream markupStream,
final ComponentTag openTag) {
String mark = "";
if (required){
// could be for instance "*"
mark = getString("formResources.requiredField");
}
String text = getModelObjectAsString() + mark;
replaceComponentTagBody(markupStream, openTag, text);
}
}
{
TextField component = new TextField("component");
component.setRequired(true);
component.setOutputMarkupId(true);
IModel labelModel = new StringResourceModel("formResources.component.label",
this, null);
component.setLabel(labelModel);
add(component);
add(new MyLabel("componentLabel", component);
}
<label wicket:id="componentLabel"/>
<input type="text" wicket:id="component"/>
的文本设置为国际化资源字符串FormComponent
标记透明地重复使用完全相同的资源字符串,甚至根据<label>
的属性向其添加自定义标记。答案 2 :(得分:3)
另一种方法是使用<wicket:label/>
的键属性,如下所示:
<label wicket:for="name">
<wicket:label key="label.name">Placeholder label</wicket:label>
</label>
<input wicket:id="name" type="text"/>
不幸的是,在描述wicket的xhtml标签的wiki页面上没有记录这个属性。在处理标记(org.apache.wicket.markup.html.form.AutoLabelTextResolver
)的类中使用JavaDoc记录支持的所有属性。
这种替代方案的优点是不需要额外的编码。
答案 3 :(得分:1)
Wicket抛出异常,告诉您将删除<wicket:message>
标记,因为<wicket:label>
标记的正文已被替换。问题是您无法将<wicket:message>
标记嵌套在<wicket:label>
标记内(并且不应该)。
这个(选项1):
<label wicket:for="name">
<wicket:label key="label.name"/>
</label>
<input wicket:id="name" type="text />
或此(选项2):
<label wicket:for="name">
<wicket:message key="label.name"/>
</label>
<input wicket:id="name" type="text />
应该适合你并导致HTML如下所示(假设属性文件包含label.name=Name
):
<label for="someMarkupId">
Name
</label>
<input id="someMarkupId" type="text" />
不同之处在于,如果通过Java代码设置组件的标签,如下所示:
component.setLabel(new Model("value set in code"));
然后使用选项1将导致标签设置为&#34;在代码&#34;中设置的值,而使用选项2仍将导致标签设置为&#34;名称&#34;。此外,如果标签是通过Java代码设置的,并且属性文件中缺少密钥,则选项2将引发异常,而选项1将仅使用代码中设置的值。
答案 4 :(得分:0)
我更喜欢这个:
<label wicket:for="name"><wicket:label />:</label>
<input type="text" wicket:id="name"></input>
只需确保使用FormComponent
在setLabel
中设置标签,因此唯一需要的是:
add(new TextField("name", nameModel).setLabel(Model.of("i18n.name")));
这将呈现为(荷兰语):
<label id="name63-w-lbl" for="name63">Naam:</label>
<input type="text" value="" name="name" id="name63">