Как внедрить 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 (это никогда не будет использоваться)).

Другие вопросы по тегам