Интернационализированные метки для компонентов формы в калитке
Как правильно создать интернационализированные метки для компонентов формы, чтобы при отображении сообщений обратной связи вместо имени Поля в коде 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 ответов:
Я только что проверил следующее:
<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
' sgetObject()
.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"/>
Таким образом, у вас будет чистый способ
- установка текста
FormComponent
в интернационализированную строку ресурса- повторное использование точно такой же строки ресурса прозрачно для тега
<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">