3

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

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

4

5 回答 5

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

这是你想要的?

于 2012-07-09T11:24:46.490 回答
3

这是@bert 的另一种方法,它一直对我有用(不知道<wicket:label>

发生验证错误时显示的文本FormComponent可以通过 指定FormComponent.setLabel(IModel)。显示的文本将是IModel's的结果getObject()

TextField comp = new TextField("comp");
// Use internationalized text from XML resource file
comp.setLabel(new StringResourceModel("formResources.comp.label", this, null));

Notice this has nothing to do with <label> nor FormComponentLabel. FormComponentLabel is a component that can be used to model <label> tags.

You could even subclass FormComponentLabel to provide the label text based on FormComponent.getLabel(), and maybe output an extra mark when the field is required:

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

This way you would have clean way of

  1. Setting the FormComponent's text to an internationalized resource string
  2. Reusing exactly the same resource string transparently for the <label> tag and even adding custom marks to it based on FormComponent's properties.
于 2012-07-10T08:57:35.667 回答
3

Another alternative is to use the key attribute of <wicket:label/>, like so:

<label wicket:for="name">
   <wicket:label key="label.name">Placeholder label</wicket:label> 
</label>
<input wicket:id="name" type="text"/>

Unfortunately this attribute is not documented on the wiki page describing wicket's xhtml tags. All attributes supported are documented using JavaDoc in the class handling the tag (org.apache.wicket.markup.html.form.AutoLabelTextResolver).

The advantage of this alternative is that there is no additional coding required.

于 2013-05-29T14:16:58.760 回答
1

Wicket throws an exception to tell you that your <wicket:message> tag will be removed because the body of the <wicket:label> tag is replaced. The problem is you cannot nest the <wicket:message> tag inside the <wicket:label> tag (and shouldn't need to).

either this (Option 1):

<label wicket:for="name">
     <wicket:label key="label.name"/>
</label>
<input wicket:id="name" type="text />

or this (Option 2):

<label wicket:for="name">
     <wicket:message key="label.name"/>
</label>
<input wicket:id="name" type="text />

should work for you and result in HTML something like the following (assuming the properties file contains label.name=Name):

<label for="someMarkupId">
    Name
</label>
<input id="someMarkupId" type="text" />

The difference is that if you set the label for the component through the Java code like so:

component.setLabel(new Model("value set in code"));

then using the Option 1 will result in the label being set to "value set in code", while using Option 2 will still result in the label set to "Name". Also if the label is set through Java code, and the key is missing from the properties file the Option 2 will throw an exception, while Option 1 will simply use the value set in the code.

于 2013-07-23T23:44:19.537 回答
0

I prefer this:

<label wicket:for="name"><wicket:label />:</label>
<input type="text" wicket:id="name"></input>

Just make sure to set the label in the FormComponent using setLabel, so the only java needed is:

add(new TextField("name", nameModel).setLabel(Model.of("i18n.name")));      

This will be rendered as (in Dutch):

<label id="name63-w-lbl" for="name63">Naam:</label>
<input type="text" value="" name="name" id="name63">
于 2017-12-29T10:06:47.777 回答