Как внедрить i18n в приложение GWT?
У меня проблема с интернационализацией. Я пытаюсь реализовать поддержку двух языков в моем приложении GWT. К сожалению, я так и не нашел полный пример того, как это сделать с помощью UiBinder. Вот что я сделал:
Мой модуль I18nexample.gwt.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='i18nexample'>
<inherits name="com.google.gwt.user.User" />
<inherits name='com.google.gwt.user.theme.clean.Clean' />
<inherits name="com.google.gwt.i18n.I18N" />
<inherits name="com.google.gwt.i18n.CldrLocales" />
<entry-point class='com.myexample.i18nexample.client.ExampleI18N' />
<servlet path="/start" class="com.myexample.i18nexample.server.StartServiceImpl" />
<extend-property name="locale" values="en, fr" />
<set-property-fallback name="locale" value="en" />
</module>
Мой интерфейс Message.java:
package com.myexample.i18nexample.client;
import com.google.gwt.i18n.client.Constants;
public interface Message extends Constants {
String greeting();
}
Тот же пакет com.myexample.i18nexample.client
имеет три файла свойств:
Message.properties:
greeting = hello
Message_en.properties:
greeting = hello
Message_fr.properties:
greeting = bonjour
Мой файл UiBinder Greeting.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder
xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
ui:generateFormat="com.google.gwt.i18n.rebind.format.PropertiesFormat"
ui:generateKeys="com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator"
ui:generateLocales="default" >
<ui:with type="com.myexample.i18nexample.client.Message" field="string" />
<g:HTMLPanel>
<ui:msg key="greeting" description="greeting">Default greeting</ui:msg>
</g:HTMLPanel>
</ui:UiBinder>
Когда приложение запускается, я всегда получаю вывод в браузере:
Default greeting
Зачем? Что я делаю неправильно?
Я пытался запустить приложение с другого URL:
http://127.0.0.1:8888/i18nexample.html?gwt.codesvr=127.0.0.1:9997
http://127.0.0.1:8888/i18nexample.html?locale=en&gwt.codesvr=127.0.0.1:9997
http://127.0.0.1:8888/i18nexample.html?locale=fr&gwt.codesvr=127.0.0.1:9997
Результат не меняется. Хотя я ожидал в последнем случае сообщения bonjour
,
Если, например, я использую g:Buttton
вместо сообщения ui:msg
:
<g:HTMLPanel>
<g:Button text="{string.greeting}" />
</g:HTMLPanel>
Тогда я получаю в результате кнопку с текстом "hello"
И если я введу URL:
http://127.0.0.1:8888/i18nexample.html?locale=fr&gwt.codesvr=127.0.0.1:9997
Текст на кнопке меняется на "bonjour"
, Здесь все работает как положено. Но почему интернационализация не работает в моем первом случае?
И есть ли разница между следующим:
<ui:msg description="greeting">Default greeting</ui:msg>
<ui:msg description="greeting">hello</ui:msg>
<ui:msg description="greeting"></ui:msg>
Должны ли быть разные результаты в этих случаях? Как правильно написать?
Пожалуйста, объясните мне принципы интернационализации в GWT и почему мой пример не работает. Любые предложения будут ценны.
1 ответ
Во-первых, файлы должны быть названы Message_fr.properties
(Соотв. Message_en.properties
) не Message.properties_fr
(Соотв. Message.properties_en
).
затем ui:msg
и другие. в UiBinder сгенерирует интерфейс (расширяющий com.google.gwt.i18n.client.Messages
)), не используйте тот, который вы определили. Для этого вы должны использовать {string.greeting}
(где string
это ui:field
ты дал своему ui:with
). Генератор UiBinder сделает GWT.create()
на type
класс вашего ui:with
, что вы бы сделали в коде Java:
Message string = GWT.create(Message.class);
String localizedGreeting = string.greeting();
В неявном интерфейсе сообщений (сгенерированном UiBinder) различные ui:generateXxx
атрибуты на ui:UiBinder
будут преобразованы в аннотации на интерфейсе (свойства @Generate
аннотация, или значение @GenerateKeys
аннотация).
Затем будет создан один метод для каждого ui:msg
где атрибуты генерируют эквивалентные аннотации (@Key
, @Description
) и содержание ui:msg
элемент является значением @DefaultMessage
аннотаций. Когда у вас есть или виджеты внутри контента, они будут превращены в аргументы метода и заполнителей в @DefaultMessage
текст (значения будут заполнены UiBinder).
Я бы посоветовал вам сначала сделать что-то без UiBinder и понять, как это работает; затем попробуйте ui:msg
в UiBinder, используя -gen
в DevMode или компиляторе, чтобы вы могли точно видеть, какой код генерирует UiBinder (да, он действительно генерирует только тот код, который вы могли бы написать самостоятельно).
Кроме того, вы должны добавить <set-property name="locale" value="en, fr" />
или у вас все еще будет default
вокруг, несмотря на set-property-fallback
(это никогда не будет использоваться)).