Интернационализированные метки для компонентов формы в калитке


Как правильно создать интернационализированные метки для компонентов формы, чтобы при отображении сообщений обратной связи вместо имени Поля в коде java отображалось интернационализированное имя поля?

Я читал это:

Https://cwiki.apache.org/WICKET/everything-about-wicket-internationalization.html

А также документация для XHTML wicket's теги:

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 3

5 ответов:

Я только что проверил следующее:

<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

Это привело к следующему экрану (если я оставлю поле requireed пустым и нажму submit.

Введите описание изображения здесь

Это то, что вы ищете?

Вот альтернативный подход к @bert's , который всегда работал для меня (не знал о <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));

Обратите внимание, что это не имеет никакого отношения к <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/>, например:

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

К сожалению, этот атрибут не задокументирован на странице wiki, описывающей теги XHTML wicket. Все поддерживаемые атрибуты документируются с помощью 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>

Просто убедитесь, что вы установили метку в FormComponent с помощью setLabel, поэтому единственное, что требуется 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">