Java lokalizáció - Üzenetek formázása

1. Bemutatkozás

Ebben az oktatóanyagban megvizsgáljuk, hogyan tudunk lokalizálja és formázza az üzeneteket alapján Területi beállítás.

Mindkét Java-t használjuk MessageFormat és a harmadik fél könyvtárát, ICU.

2. Lokalizációs használati eset

Amikor alkalmazásunk széles körű felhasználókat szerez a világ minden tájáról, akkor természetesen szeretnénk különböző üzeneteket mutat a felhasználó preferenciái alapján.

Az első és legfontosabb szempont az a nyelv, amelyet a felhasználó beszél. Mások tartalmazhatnak pénznem, szám és dátum formátumot. Végül, de nem utolsósorban a kulturális preferenciák: ami elfogadható az egyik ország felhasználói számára, másoknak elviselhetetlen lehet.

Tegyük fel, hogy van e-mail kliensünk, és értesítéseket szeretnénk megjeleníteni, ha új üzenet érkezik.

Egy ilyen üzenet egyszerű példája lehet ez:

Alice üzenetet küldött neked.

Angolul beszélő felhasználóknak jó, de a nem angolul beszélők nem biztos, hogy örülnek ennek. Például a francia nyelvű felhasználók inkább ezt az üzenetet látják:

Alice küldött és üzenetet küld. 

Bár a lengyel emberek örülnének, ha ezt látnák:

Alice wysłała ci wiadomość. 

Mi van, ha megfelelően formázott értesítést szeretnénk kapni még abban az esetben is, amikor Alice nemcsak egy, hanem kevés üzenetet küld?

Kísértésbe hozhatjuk a kérdés megoldását úgy, hogy különféle darabokat összefűzünk egyetlen karaktersorozatba, így:

String message = "Alice" + mennyiség + "üzeneteket küldött"; 

A helyzet könnyen kikerülhet az irányítás alól, amikor értesítésekre van szükségünk, ha nemcsak Alice, hanem Bob is küldheti az üzeneteket:

Bob két üzenetet küldött. Bob egy küldött deux üzeneteket. Bob wysłał dwie wiadomości.

Figyeljük meg, hogyan változik az ige a lengyel (wysłała vs. wysłał) nyelv. Ez azt a tényt szemlélteti, hogy a banális karakterlánc-összefűzés ritkán elfogadható az üzenetek lokalizálásához.

Amint látjuk, kétféle problémát kapunk: az egyik a fordításokkal, a másik a formátumokkal kapcsolatos. A következő szakaszokban foglalkozzunk velük.

3. Üzenet lokalizálása

Meghatározhatjuk a lokalizáció, vagy l10n, az alkalmazásnak a felhasználó kényelméhez való igazításának folyamata. Néha a kifejezés internalizálás, vagy i18n, szintén használják.

Az alkalmazás lokalizálása érdekében először is szüntessük meg az összes keményen kódolt üzenetet azáltal, hogy áthelyezzük őket az alkalmazásunkba erőforrások mappa:

Minden fájlnak tartalmaznia kell kulcs-érték párokat az üzenetekkel a megfelelő nyelven. Például fájl üzenetek_hu.tulajdonságok a következő párot kell tartalmaznia:

label = Alice üzenetet küldött neked.

üzenetek_pl.tulajdonságok a következő párot kell tartalmaznia:

címke = Alice wysłała ci wiadomość.

Hasonlóképpen más fájlok is megfelelő értékeket rendelnek a kulcshoz címke. Most az értesítés angol nyelvű változatának felvétele érdekében használhatjuk ResourceBundle:

ResourceBundle bundle = ResourceBundle.getBundle ("üzenetek", Nyelv.UK); Karakterlánc-üzenet = bundle.getString ("label");

A változó értéke üzenet lesz - Alice üzenetet küldött neked.

Java Területi beállítás osztály tartalmaz parancsikonokat a gyakran használt nyelvekhez és országokhoz.

A lengyel nyelv esetében a következőket írhatjuk:

ResourceBundle bundle = ResourceBundle.getBundle ("üzenetek", Locale.forLanguageTag ("pl-PL")); Karakterlánc-üzenet = bundle.getString ("label");

Csak említsük meg, hogy ha nem adunk meg területi beállítást, akkor a rendszer alapértelmezettet fog használni. További részleteket erről a kérdésről az „Internacionalizáció és lokalizáció a Java 8-ban” című cikkünkben találhatunk. Ezután a rendelkezésre álló fordítások közül a rendszer kiválasztja azt, amelyik a legjobban hasonlít a jelenleg aktív területi beállításokra.

Az üzenetek elhelyezése az erőforrás fájlokban jó lépés az alkalmazás felhasználóbarátabbá tétele felé. Ez megkönnyíti a teljes alkalmazás lefordítását a következő okokból:

  1. a fordítónak nem kell az üzenetet keresnie az alkalmazáson keresztül
  2. egy fordító láthatja az egész kifejezést, amely segít megérteni a kontextust, és ezáltal megkönnyíti a jobb fordítást
  3. nem kell újból lefordítanunk a teljes alkalmazást, amikor készen áll a fordítás egy új nyelvre

4. Üzenet formátuma

Annak ellenére, hogy az üzeneteket külön kódra helyeztük át a kódból, ezek mégis tartalmaznak néhány keményen kódolt információt. Jó lenne, ha személyre szabhatnánk az üzenetekben szereplő neveket és számokat oly módon, hogy nyelvtanilag helyesek maradjanak.

Meghatározhatjuk a formázást a karakterlánc sablon megjelenítésének folyamataként, helyettesítve az értékeket a helyőrzőkkel.

A következő szakaszokban két megoldást vizsgálunk meg, amelyek lehetővé teszik az üzenetek formázását.

4.1. Java MessageFormat

A karakterláncok formázása érdekében a Java számos formázási módszert határoz meg java.lang.String. De még több támogatást kaphatunk a következőn keresztül: java.text.format.MessageFormat.

Szemléltetésképpen hozzunk létre egy mintát, és adjuk hozzá a MessageFormat példa:

String pattern = "{0, date} dátummal {1}" + "{2, választás, 0 # nincs üzenet | 1 # üzenet | 2 # két üzenet | 2 <{2, szám, egész} üzenet} . " MessageFormat formatter = new MessageFormat (pattern, Locale.UK); 

A minta karaktersorozatban három helyőrző van.

Ha minden értéket megadunk:

Karakterlánc üzenet = formatter.format (új objektum [] {dátum, "Alice", 2});

Azután MessageFormat kitölti a sablont és megjeleníti az üzenetünket:

2019. április 27-én Alice két üzenetet küldött neked.

4.2. MessageFormat Szintaxis

A fenti példából láthatjuk, hogy az üzenetminta:

minta = "Be {...}, {..} küldött neked {...}.";

göndör zárójelben lévő helyőrzőket tartalmaz {…} kötelező érvvel index és két választható argumentum, típus és stílus:

{index} {index, típus} {index, típus, stílus}

A helyőrző indexe megegyezik a beilleszteni kívánt objektumok tömbjének elemével.

Ha jelen van, a típus és stílus a következő értékeket veheti fel:

típusstílus
számegész szám, pénznem, százalék, egyéni formátum
dátumrövid, közepes, hosszú, teljes, egyedi formátum
időrövid, közepes, hosszú, teljes, egyedi formátum
választásegyedi formátum

A típusok és stílusok nevei nagyrészt önmagukért beszélnek, de további részletekért áttekinthetjük a hivatalos dokumentációt.

Vizsgáljuk meg közelebbről a egyedi formátum.

A fenti példában a következő formátumkifejezést használtuk:

{2, választás, 0 # nincs üzenet | 1 # üzenet | 2 # két üzenet | 2 <{2, szám, egész} üzenet}

Általában a választási stílus a függőleges sávval (vagy csővel) elválasztott opciók formájában van:

Az opciók között az egyezési érték kén és a húr vén az utolsó opció kivételével # -vel vannak elválasztva. Figyelje meg, hogy más mintákat is beágyazhatunk a húrba vén ahogy az utolsó lehetőségnél tettük:

{2, választás, ... | 2 <{2, szám, egész} üzenet}

A választási típus numerikus alapú, tehát természetes a sorrend az egyezési értékekre kén amelyek egy numerikus sort intervallumokra osztanak:

Ha adunk értéket k hogy az intervallumhoz tartozik [kén, ki + 1) (a bal oldalt tartalmazza, a jobbat kizárja), majd érték vén van kiválasztva.

Nézzük meg részletesebben a választott stílus tartományait. Ennek érdekében ezt a mintát vesszük:

minta = "Van" + "{0, választás, 0 # nincs üzenet | 1 # üzenet | 2 # két üzenet | 2 <{0, szám, egész} üzenet}.";

és adja át az egyedi helyőrző különféle értékeit:

nüzenet
-1, 0, 0.5Nincsenek üzeneteid.
1, 1.5Van egy üzeneted.
2Két üzeneted van.
2.52 üzeneted van.
55 üzeneted van.

4.3. A dolgok jobbá tétele

Szóval, most formázzuk üzeneteinket. De maga az üzenet továbbra is kódolt marad.

Az előző szakaszból tudjuk, hogy ki kell vonni a karakterláncmintákat az erőforrásokba. Az aggodalmaink elkülönítése érdekében hozzunk létre egy újabb csomó erőforrásfájlt formátumok:

Ezekben létrehozunk egy nevű kulcsot címke nyelvspecifikus tartalommal.

Például az angol változatban a következő karakterláncot tesszük:

label = {0, dátum, teljes} {1} + {2, choice, 0 # semmi | 1 # üzenetet küldött | 2 # két üzenet | 2 <{2, szám, egész} üzenet}.

Kissé módosítanunk kell a francia változatot a nulla üzenet eset miatt:

label = {0, dátum, rövid}, {1} 0 <vous a küldött + {2, választás, 0 # aucun üzenet | 1 # un üzenet | 2 # deux üzenet | 2 <{2, szám, egész} üzenet} .

És hasonló módosításokat kell elvégeznünk a lengyel és az olasz változatban is.

Valójában a lengyel változat még egy problémát mutat. A lengyel nyelv (és sok más) nyelvtana szerint az igének nemben kell megegyeznie a témával. Megoldhatnánk ezt a problémát a választási típus használatával, de vegyünk fontolóra egy másik megoldást.

4.4. ICU-k MessageFormat

Használjuk a Az Unicode nemzetközi komponensei (ICU) könyvtár. A String to Title Case konvertálása oktatóanyagunkban már említettük. Ez egy kiforrott és széles körben használt megoldás, amely lehetővé teszi számunkra, hogy az alkalmazást testre szabjuk a különböző nyelvekhez.

Itt nem fogjuk részletesen feltárni. Csak arra szorítkozunk, amire a játékalkalmazásunknak szüksége van. A legátfogóbb és legfrissebb információkért ellenőrizze az ICU hivatalos webhelyét.

Az írás idején az ICU for Java legújabb verziója (ICU4J) 64,2. A szokásos módon a használat megkezdéséhez hozzá kell adnunk a projektünk függőségeként:

 com.ibm.icu icu4j 64.2 

Tegyük fel, hogy megfelelően formázott értesítést szeretnénk kapni különböző nyelveken és különböző számú üzenetre:

Nangolfényesít
0Alice még nem küldött üzenetet neked.

Bob nem küldött üzenetet neked.

Alice nie wysłała ci żadnej wiadomości.

Bob nie wysłał ci żadnej wiadomości.

1Alice üzenetet küldött neked.

Bob üzenetet küldött neked.

Alice wysłała ci wiadomość.

Bob wysłał ci wiadomość.

> 1Alice N üzenetet küldött neked.

Bob N üzenetet küldött neked.

Alice wysłała ci N wiadomości.

Bob wysłał ci N wiadomości.

Először létre kell hoznunk egy mintát a területi beállításokhoz tartozó erőforrásfájlokban.

Használjuk újra a fájlt formátumok.tulajdonságok és adj hozzá egy kulcsot label-icu a következő tartalommal:

label-icu = {0} + {2, többes szám, = 0 {nincs üzenet} = 1 {egy üzenet} + további {{2, szám, egész szám} üzenet}}} küldött.

Három helyőrzőt tartalmaz, amelyeket egy háromelemes tömb odaadásával adunk meg:

Objektum [] adatok = új objektum [] {"Alice", "nő", 0}

Látjuk, hogy az angol változatban a nemek szerint értékelt helyőrző nem használ, míg a lengyelben:

label-icu = {0} {2, többes szám, = 0 {nie} egyéb {}} + {1, kiválaszt, férfi {wysłał} nő {wysłała} egyéb {wysłało}} + ci {2, többes szám, = 0 { żadnych wiadomości} = 1 {wiadomość} + egyéb {{2, szám, egész} wiadomości}}.

a megkülönböztetés érdekében használjuk wysłał / wysłała / wysłało.

5. Következtetés

Ebben az oktatóanyagban átgondoltuk, hogyan lokalizálhatjuk és formázhatjuk azokat az üzeneteket, amelyeket bemutatunk az alkalmazásaink felhasználói számára.

Mint mindig, ennek az oktatóanyagnak a kódrészletei is megtalálhatók a GitHub adattárunkban.