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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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"))));

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

答案

我刚刚测试了以下内容:

<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

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

这是你想要的?

另一答案

以下是@bert's的替代方法,一直对我有用(不知道<wicket:label>

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

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

请注意,这与<label>FormComponentLabel无关。 FormComponentLabel是一个可用于模拟<label>标签的组件。

您甚至可以继承FormComponentLabel子类以提供基于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"/>

这样你会有干净的方式

  1. FormComponent的文本设置为国际化资源字符串
  2. <label>标记透明地重用完全相同的资源字符串,甚至根据FormComponent的属性为其添加自定义标记。
另一答案

另一种方法是使用<wicket:label/>的key属性,如下所示:

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

不幸的是,这个属性没有记录在描述wicket的xhtml标签的wiki页面上。支持的所有属性都是使用JavaDoc在处理标记的类(org.apache.wicket.markup.html.form.AutoLabelTextResolver)中记录的。

这种替代方案的优点是不需要额外的编码。

另一答案

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将导致标签设置为“代码中的值设置”,而使用选项2仍将导致标签设置为“名称”。此外,如果标签是通过Java代码设置的,并且属性文件中缺少密钥,则选项2将抛出异常,而选项1将仅使用代码中设置的值。

另一答案

我更喜欢这个:

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

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

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

以上是关于Wicket中表单组件的国际化标签的主要内容,如果未能解决你的问题,请参考以下文章

WICKET:控制组件在更改 CheckBox 时的可见性

Java:如何将值从javascript设置为wicket组件文本字段

Wicket - 表单提交后的 clearInput() 不起作用

使用 Ajax 填充 Wicket 表

Wicket:从内部表单访问字段

在 wicket 中,如何创建未由组件层次结构/布局定义的 RadioGroup?