piątek, 25 kwietnia 2008

GWT - internacjonalizacja

Jeżeli docelową grupą użytkowników naszej aplikacji są ludzie o różnych narodowościach wówczas warto dostosować ją do obsługi wielu języków. Pierwszą rzeczą z którą przyjdzie się nam zmierzyć będzie tłumaczenie tekstów stałych. Samo tłumaczenie tekstów możemy pozostawić lingwistom, natomiast naszym zadaniem jest napisanie tak aplikacji, aby obsługa tych tekstów była możliwa i przy dodawaniu kolejnych tłumaczeń nie wymagała pracy programistycznej.

Oczywiście każdy programista dość szybko poradziłby sobie z tym zagadnieniem wymyślając swój własny mechanizm, ale programista leniwy (czytaj: skuteczny) przegrzebie dokumentację w celu znalezieniu mechanizmu, który już został wymyślony. Jak to wygląda w GWT...

Podstawowym elementem, który umożliwi nam lokalizację tekstów stałych jest moduł zawarty w pakiecie com.google.gwt.i18n oferuje on kilka mechanizmów: Constants, Messages, ConstantsWithLookup, Dictionary, Localizable. Skoncentrujmy się jednak na dwóch podstawowych Constants i Messages, które powinny być używane w większości przypadków.

Jeżeli chcemy skorzystać z tych mechanizmów nasz moduł musi dziedziczyć po module com.google.gwt.i18n.I18N (plik MyModule.gwt.xml w pakiecie com.mycompany.mymodule): Kolejnym krokiem jest stworzenie plików zawierających teksty stałe dla poszczególnych języków oraz plik domyślny.

Plik domyślny MyConstans.properties (w pakiecie com.mycompany.mymodule.client):
Plik dla języka polskiego MyConstans_pl.properties (w pakiecie com.mycompany.mymodule.client):
Plik dla języka angielskiego MyConstans_en.properties (w pakiecie com.mycompany.mymodule.client):
Kolejnym krokiem jest stworznie w pakiecie com.mycompany.mymodule.client interfejsu MyConstans, w którym nazwy metod będą odpowiadać kluczom w plikach z tekstami stałymi:
Aby użyć nasze teksty wystarczą dwie linie kodu w kodzie klasy klienta (np. MyModule.java):
Drugi mechanizm, który niejako stawi rozszerzenie Constants to Messages, różni się on jedynie tym, iż teksty stałe mogą posiadać argumenty. Załóżmy, iż w pliku ErrorMessages.properties mamy tekst:
Wóczas definiujemy interfejs analogiczny do Constants przy czym metody powinny mieć tyle argumentów wejściowych ile zostało wymienonych w tekstach stałych. Definicja interfejsu ErrorMessages.java:
Aby teksty stałe były wyświetlane w danym języku mamy dwie możliwości. Pierwsza polega na ustawieniu właściwości <meta name="gwt:property" content="locale=pl"> bezpośrednio w stronie html:
Druga możliwość to dodanie parametru do URL:
Mechanizmy, ktore zostały opisane można używać tylko w kodzie na podstawie, którego jest generowany JavaScript (czyli który jest umieszczony w pakiecie client). Podczas kompilacji GWT wytwarza dla każdej lokalizacji odrębny plik JavaScript.
Reasumując GWT dostarcza dość kompleksowy mechanizm internacjonalizacji, choć według mnie wystarczyłby mechanizm Messages, bo przecież nie mogę od razu przewidzieć, że mój tekst stały nie będzie miał kiedyś argumentów. Kolejną rzeczą, która stanowi dla mnie pewną wadę jest to, iż nie można używać tych mechanizmów po stronie serwera, co zmusza nas do korzystania ze standardowego rozwiązania dostarczonego przez Java ResourceBundle.