Lokalizacija Java - formatiranje poruka

1. Uvod

U ovom uputstvu razmotrit ćemo kako možemo lokalizirati i oblikovati poruke na temelju Lokalno.

Koristit ćemo obje Java Oblik poruke i biblioteka treće strane, JIL.

2. Slučaj upotrebe lokalizacije

Kad naša aplikacija stekne široku publiku korisnika iz cijelog svijeta, možda bismo to prirodno željeli prikazuju različite poruke na temelju korisnikovih preferencija.

Prvi i najvažniji aspekt je jezik kojim korisnik govori. Ostali mogu uključivati ​​formate valuta, brojeva i datuma. Posljednje, ali ne najmanje važno, su kulturne preferencije: ono što je prihvatljivo za korisnike iz jedne zemlje, drugima može biti nepodnošljivo.

Pretpostavimo da imamo klijenta e-pošte i želimo prikazivati ​​obavijesti kad stigne nova poruka.

Jednostavan primjer takve poruke može biti ova:

Alice vam je poslala poruku.

U redu je za korisnike koji govore engleski, ali oni koji ne govore engleski možda nisu toliko sretni. Na primjer, korisnici koji govore francuski radije bi vidjeli ovu poruku:

Alice je poslala poruku izaslaniku. 

Iako bi Poljaci bili zadovoljni kad bi vidjeli ovu:

Alice wysłała ci wiadomość. 

Što ako želimo imati pravilno oblikovanu obavijest čak i u slučaju kada Alice pošalje ne samo jednu poruku, već nekoliko poruka?

Možda ćemo doći u napast da riješimo problem spajanjem različitih dijelova u jedan niz, poput ovog:

String message = "Alice je poslala" + količina + "poruke"; 

Situacija može lako izmaći kontroli kada su nam potrebne obavijesti u slučaju kada poruke ne može poslati samo Alice već i Bob:

Bob je poslao dvije poruke. Bob izaslanik deux poruke. Bob wysłał dwie wiadomości.

Primijetite, kako se glagol mijenja u slučaju poljskog (wysłała nasuprot wysłał) Jezik. To ilustrira činjenicu da spajanje banalnih nizova rijetko je prihvatljivo za lokaliziranje poruka.

Kao što vidimo, imamo dvije vrste problema: jedan je povezan s prijevodima, a drugi s formatima. Obratimo im se u sljedećim odjeljcima.

3. Lokalizacija poruke

Možemo definirati lokalizacija ili lnn, aplikacije kao postupka prilagođavanja aplikacije udobnosti korisnika. Ponekad, pojam internalizacija, ili i18n, također se koristi.

Da bismo lokalizirali aplikaciju, prije svega, uklonimo sve kodirane poruke premještanjem u našu resursi mapa:

Svaka datoteka treba sadržavati parove ključ / vrijednost s porukama na odgovarajućem jeziku. Na primjer, datoteka messages_en.properties treba sadržavati sljedeći par:

label = Alice vam je poslala poruku.

messages_pl.properties treba sadržavati sljedeći par:

oznaka = Alice wysłała ci wiadomość.

Slično tome, druge datoteke ključu dodjeljuju odgovarajuće vrijednosti označiti. Sada, kako bismo preuzeli englesku verziju obavijesti, možemo se poslužiti ResourceBundle:

Bundle ResourceBundle = ResourceBundle.getBundle ("poruke", Locale.UK); String message = bundle.getString ("label");

Vrijednost varijable poruka bit će "Alice ti je poslala poruku."

Java Lokalno razred sadrži prečace do često korištenih jezika i zemalja.

U slučaju poljskog jezika, mogli bismo napisati sljedeće:

Bundle ResourceBundle = ResourceBundle.getBundle ("poruke", Locale.forLanguageTag ("pl-PL")); String message = bundle.getString ("label");

Spomenimo samo da će, ako ne navedemo lokalizaciju, sustav koristiti zadani. Više detalja o ovom pitanju možemo naći u našem članku „Internacionalizacija i lokalizacija u Javi 8“. Tada će, među dostupnim prijevodima, sustav odabrati onaj koji je najsličniji trenutno aktivnom jeziku.

Postavljanje poruka u datoteke s resursima dobar je korak ka tome da aplikaciju učinite korisnijom. Olakšava prijevod cijele aplikacije iz sljedećih razloga:

  1. prevoditelj ne mora pregledavati aplikaciju u potrazi za porukama
  2. prevoditelj može vidjeti cijelu frazu koja pomaže shvatiti kontekst i time omogućuje bolji prijevod
  3. ne moramo ponovno sastaviti cijelu aplikaciju kad je spreman prijevod za novi jezik

4. Format poruke

Iako smo poruke s koda premjestili na zasebno mjesto, one i dalje sadrže neke kodirane informacije. Bilo bi lijepo kad biste mogli prilagoditi imena i brojeve u porukama na takav način da ostaju gramatički ispravni.

Oblikovanje možemo definirati kao postupak prikazivanja predloška niza zamjenom rezerviranih mjesta njihovim vrijednostima.

U sljedećim odjeljcima razmotrit ćemo dva rješenja koja nam omogućuju oblikovanje poruka.

4.1. Java Oblik poruke

Kako bi formatirala nizove, Java definira brojne metode formatiranja u java.lang.String. Ali, još veću podršku možemo dobiti putem java.text.format.MessageFormat.

Da bismo to ilustrirali, stvorimo uzorak i ubacimo ga u Oblik poruke primjer:

Uzorak niza = "Dana {0, datum}, {1} poslao vam je" + "{2, izbor, 0 # nema poruka | 1 # poruka | 2 # dvije poruke | 2 <{2, broj, cijeli broj} poruka} . "; MessageFormat formatter = novi MessageFormat (uzorak, Locale.UK); 

Niz uzorka ima utore za tri rezervirana mjesta.

Ako dostavimo svaku vrijednost:

Niz poruke = formatter.format (novi objekt [] {datum, "Alice", 2});

Zatim Oblik poruke ispunit će predložak i prikazati našu poruku:

27. travnja 2019. Alice vam je poslala dvije poruke.

4.2. Oblik poruke Sintaksa

Iz gornjeg primjera vidimo da obrazac poruke:

pattern = "Dana {...}, {..} poslao vam je {...}.";

sadrži rezervirana mjesta koja su kovrčave zagrade {…} uz traženi argument indeks i dva neobavezna argumenta, tip i stil:

{indeks} {indeks, tip} {indeks, tip, stil}

Indeks rezerviranog mjesta odgovara položaju elementa iz niza objekata koje želimo umetnuti.

Kad je prisutan, tip i stil može poprimiti sljedeće vrijednosti:

tipstil
brojcijeli broj, valuta, postotak, prilagođeni format
datumkratki, srednji, dugi, puni, prilagođeni format
vrijemekratki, srednji, dugi, puni, prilagođeni format
izborprilagođeni format

Imena vrsta i stilova uglavnom govore sama za sebe, ali za više detalja možemo potražiti službenu dokumentaciju.

Pogledajmo izbliza, ipak prilagođeni format.

U gornjem primjeru koristili smo sljedeći izraz formata:

{2, izbor, 0 # nema poruka | 1 # poruka | 2 # dvije poruke | 2 <{2, broj, cijeli broj} poruka}

Općenito, stil izbora ima oblik opcija odvojenih vertikalnom trakom (ili cijevi):

Unutar opcija, vrijednost podudaranja kja i niz vja odvojene su s # osim zadnje opcije. Primijetite da u niz možemo ugnijezditi i druge uzorke vja kao što smo to učinili za zadnju opciju:

{2, izbor, ... | 2 <{2, broj, cijeli broj} poruka}

Vrsta izbora je numerička, tako da postoji prirodni poredak za vrijednosti podudaranja kja koji dijele numeričku crtu na intervale:

Ako damo vrijednost k to pripada intervalu [kja, ki + 1) (uključen je lijevi kraj, isključen je desni), zatim vrijednost vja je odabran.

Razmotrimo detaljnije raspone odabranog stila. U tu svrhu uzimamo ovaj obrazac:

pattern = "Dobili ste" + "{0, izbor, 0 # nema poruka | 1 # poruka | 2 # dvije poruke | 2 <{0, broj, cijeli broj} poruka}.";

i proslijedite razne vrijednosti za svoje jedinstveno rezervirano mjesto:

nporuka
-1, 0, 0.5Nemate poruka.
1, 1.5Imate poruku.
2Imate dvije poruke.
2.5Imate 2 poruke.
5Imate 5 poruka.

4.3. Poboljšati stvari

Dakle, sada formatiramo svoje poruke. Ali, sama poruka ostaje čvrsto kodirana.

Iz prethodnog odjeljka znamo da bismo trebali izvući uzorke nizova u resurse. Da razdvojimo našu zabrinutost, stvorimo još jednu hrpu datoteka resursa pod nazivom formati:

U njima ćemo stvoriti ključ tzv označiti sa sadržajem specifičnim za jezik.

Na primjer, u englesku verziju stavit ćemo sljedeći niz:

label = Dana {0, datum, puni} {1} poslao vam je + {2, izbor, 0 # ništa | 1 # poruku | 2 # dvije poruke | 2 <{2, broj, cijeli broj} poruka}.

Trebali bismo malo izmijeniti francusku verziju zbog slučaja nulte poruke:

label = {0, date, short}, {1} 0 <vous a izaslanik + {2, choice, 0 # aucun message | 1 # un message | 2 # deux messages | 2 <{2, number, integer} messages} .

A morali bismo napraviti slične preinake i u poljskoj i talijanskoj verziji.

Zapravo, poljska verzija ima još jedan problem. Prema gramatici poljskog jezika (i mnogih drugih), glagol se u rodu mora slagati s subjektom. Taj bismo problem mogli riješiti uporabom vrste odabira, ali razmotrimo drugo rješenje.

4.4. JIL Oblik poruke

Iskoristimo Međunarodne komponente za Unicode (ICU) knjižnica. Već smo to spomenuli u našem vodiču za pretvaranje niza u naslove. Riječ je o zrelom i široko korištenom rješenju koje nam omogućuje prilagodbu aplikacije za različite jezike.

Ovdje ga nećemo istraživati ​​u potpunosti. Samo ćemo se ograničiti na ono što treba našoj aplikaciji za igračke. Za najopsežnije i najnovije informacije trebali bismo provjeriti službeno mjesto ICU-a.

U vrijeme pisanja ovog članka, najnovija verzija ICU-a za Javu (ICU4J) je 64,2. Kao i obično, da bismo ga počeli koristiti, trebali bismo ga dodati kao ovisnost našem projektu:

 com.ibm.icu icu4j 64.2 

Pretpostavimo da želimo imati pravilno oblikovanu obavijest na raznim jezicima i za različit broj poruka:

NEngleskiPolirati
0Alice vam nije poslala nijednu poruku.

Bob vam nije poslao nijednu poruku.

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

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

1Alice vam je poslala poruku.

Bob ti je poslao poruku.

Alice wysłała ci wiadomość.

Bob wysłał ci wiadomość.

> 1Alice vam je poslala N poruka.

Bob vam je poslao N poruka.

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

Bob wysłał ci N wiadomości.

Prije svega, trebali bismo stvoriti obrazac u datotekama resursa specifičnih za lokalno okruženje.

Ponovno upotrijebimo datoteku formati.svojstva i dodajte tamo ključ oznaka-icu sa sljedećim sadržajem:

label-icu = {0} poslao vam je + {2, množina, = 0 {nema poruka} = 1 {poruka} + ostale {{2, number, integer} poruke}}.

Sadrži tri rezervirana mjesta koja dovodimo prolazeći tamo niz od tri elementa:

Podaci o objektu [] = novi Objekt [] {"Alice", "female", 0}

Vidimo da u engleskoj verziji rezervirano mjesto s rodom ne koristi, dok u poljskoj:

label-icu = {0} {2, množina, = 0 {nie} ostalo {}} + {1, odaberi, muško {wysłał} žensko {wysłała} ostalo {wysłało}} + ci {2, množina, = 0 { żadnych wiadomości} = 1 {wiadomość} + ostalo {{2, broj, cijeli broj} wiadomości}}.

koristimo ga kako bismo razlikovali wysłał / wysłała / wysłało.

5. Zaključak

U ovom smo tutorijalu razmotrili kako lokalizirati i formatirati poruke koje demonstriramo korisnicima naših aplikacija.

Kao i uvijek, isječci koda za ovaj vodič nalaze se u našem GitHub spremištu.