Wicket中表单组件的国际化标签

时间:2012-07-09 10:52:52

标签: internationalization wicket

如何为表单组件正确创建国际化标签,以便在显示反馈消息时显示国际化字段名称而不是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"))));

是否有可能以更舒适的方式做到这一点?

5 个答案:

答案 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

这导致了以下屏幕(如果我将请求的字段留空并按提交。

enter image description here

这是你在找什么?

答案 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()

这样你会有干净的方式

  1. 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"/> 的文本设置为国际化资源字符串
  2. 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>

只需确保使用FormComponentsetLabel中设置标签,因此唯一需要的是:

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">