Language versions - internationalization

29 june 2023
Jakub Rojek Jakub Rojek
Photo by Sonny Sixteen from Pexels (https://www.pexels.com/pl-pl/zdjecie/pisanie-rozmyty-biznes-antyczny-17145073/)
Categories: Industry, For clients, Programming, IT fundamentals

Internet często jest nazywany "globalną wioską" i jest w tym dużo słuszności - pomijając kwestie polityczne i cenzorskie, każdy człowiek na świecie może mieć w ten sposób dostęp do materiałów z innych zakątków planety i komunikować się z obcokrajowcami tak "blisko", jak czyni to z rodakami. Jednak należy pamiętać, że nie oznacza to, że wszyscy internauci rozmawiają w jednym języku (chyba że jest to język memów). Co prawda, ostrożnie można założyć, że dominującą mową jest angielska (mimo że pewnie w Chinach czy Rosji mieszkańcy pokazaliby inne wskaźniki), ale większość z nas milej patrzy na treść dostępną w rodzimym języku. Prowadzi nas to do tego samego wniosku, który już dawno, dawno temu miały osoby zajmujące się tworami kultury - treść można i warto tłumaczyć.

Jednak to, o czym dzisiaj będziemy pisać, a więc internacjonalizacja, jest szerszym pojęciem. Oczywiście, większość z nas utożsamia go z translacją językową, jednak to trochę tak, jak w kinematografii - czym innym jest tłumaczenie, a czym innym adaptacja, czego dobrym przykładem jest chociażby Shrek. Internacjonalizacja to bardzo ciekawe zagadnienie, które jednak nie zawsze jest dobrze rozumiane, także przez klientów, w efekcie czego przy tworzeniu aplikacji pojawiają się czasem nieporozumienia. Postaram się dzisiaj rozwiać większość wątpliwości.

Czym jest internacjonalizacja?

Zacznijmy od tego, że "internacjonalizacja" jest długim słowem i z tego powodu często skraca się ją do "i18n", co jest innym zapisem angielskiego terminu internationalization. Liczba 18 wyjaśni się po policzeniu środkowych liter. Ale wracając do meritum - czym to właściwie jest?

Internacjonalizacja to proces projektowania lub przystosowania oprogramowania do obsługi różnych wersji językowych. Do tego obszaru zalicza się nie tylko samo wprowadzenie sformułowań w innym języku, ale też między innymi:

  • obsługa wyboru (ręcznego i automatycznego) języka dla danego użytkownika,
  • dostosowanie interfejsu do różnej długości słów w odpowiednich wersjach,
  • zastosowanie odpowiedniego kodowania znaków,
  • dopasowanie sposobu wyświetlania tekstu, np. dla języka arabskiego, gdzie obowiązuje zapis od prawej do lewej (RTL),
  • (w grach) umożliwienie dopasowania ruchu ust i animacji do wersji językowej.

Gracze komputerowi mogą kojarzyć podobne kwestie z wywiadów z polskimi studiami lokalizującymi popularne tytuły, gdzie w ramach ciekawostek poruszane są takie tematy jak rozszerzanie ramek, aby tekst się zmieścił czy dostosowanie form związanych z płcią. Natomiast nieprzypadkowo użyłem tutaj terminu "lokalizacja" - jest to bowiem słowo określające dostosowanie do konkretnego języka. Mówiąc inaczej - za internacjonalizację powinni odpowiadać twórcy oprogramowania, którzy projektują "narzędzia" umożliwiające lub ułatwiające późniejszą pracę osobom przeprowadzającym lokalizacje (w liczbie mnogiej, gdyz języków może być wiele).

Ponieważ localization również jest dość długim słowem, także tutaj w powszechnym użyciu funkcjonuje odpowiedni skrót, tym razem "l10n". Takich terminów jest dużo więcej, a wśród nich można znaleźć choćby accessibility, czyli dostępność (dla osób z niepełnosprawnościami) oznaczaną jako "a11y". Więcej takich krótszych określeń można znaleźć choćby w tej prezentacji.

Jeszcze warto wspomnieć o dość oczywistej rzeczy - internacjonalizacja jest powszechną praktyką w przypadku otwierania się na inne rynki i wyciągnięcia ze swojego oprogramowania maksimum wartości. Nie oznacza to, że przetłumaczenie aplikacji na np. angielski od razu przyniesie sukces, ale lepiej się na to przygotować i najwyżej nie skorzystać. Do tego jeszcze dzisiaj dojdziemy.

Jak wygląda internacjonalizacja od strony programisty?

Tak, jak wyżej wspomnieliśmy, to zespół realizujący oprogramowanie najczęściej odpowiada za przygotowanie go do obsługi wielu języków. Przy czym nie ma tutaj znaczenia, ile ich będzie - jeśli potrzebna jest internacjonalizacja dla dwóch wersji językowych, to przebiega ona tak samo, jakby była przygotowywana dla kilkunastu. Pewną różnicą jest natomiast projektowanie pod wersje stosujące inny alfabet (np. cyrylicę) lub kultury (np. arabska), gdzie pracy jest nieco więcej z uwagi na dostosowanie kodowania i interfejsu. Należy jednak wspomnieć, że różne frameworki, które są używane do tworzenia oprogramowania, dostarczają narzędzia pomagające w tego typu pracach i wiele z nich rozwiązuje problemy za programistów.

Trochę inaczej wygląda sprawa z wykrywaniem języka lub jego wybieraniem. Oczywiście, różne silniki zapewniają obsługę wielojęzyczności także na tym poziomie, jednak sam sposób wskazywania wersji pozostaje w gestii zespołu, nie tylko programistów, ale też UX-owców. W aplikacjach widać wiele sposobów wizualizacji wielojęzyczności w interfejsie - kliknięcie jednego z przycisków, flagi, rozwinięcie opcji, umieszczenie kontrolki w nagłówku, w stopce itd. Także wykrycie języka na podstawie przeglądarki może mieć większe lub mniejsze znaczenie, podobnie jak adresacja - widzimy strony zapisujące wybrany język w przeglądarce użytkownika, jak i takie, które wprowadzają symbol do adresu, co wiąże się z dostosowaniem routingu. Frameworki bardzo pomagają, jednak nie zrobią wszystkiego za programistę. Warto tutaj przy okazji wspomnieć, że odradzane jest wykorzystywanie flag do wyboru języka, choćby ze względu na to, że użytkownik wybiera właśnie język, a nie kraj. W wielu przypadkach jest to tożsame, ale np. taki Brytyjczyk może mieć opory przy wybraniem flagi amerykańskiej, a Austriak - przy zobaczeniu jedynie fladze niemieckiej.

Inną kwestią jest takie zaprojektowanie interfejsu (ponownie we współpracy z grafikami i UX-owcami), aby w przypadku dłuższych tekstów opcji nadal mieściły się one w wyznaczonych ramach. Klasycznym przykładem jest menu, które najczęściej składa się z kilku przycisków lub linków ustawionych równo obok siebie i "obliczonych" na pewną odległość od siebie. Często zdarza się, że po zlokalizowaniu na inny język (np. hiszpański) wszystko zaczyna wyglądać nienaturalnie ciasno lub wręcz nakłada się na siebie. Niestety, niezależnie od tego, jak wiele czasu się nad tym spędzi, nigdy nie można przewidzieć wszystkich przypadków, dopóki nie będzie się miało konkretnych tekstów w danym języku. Dlatego etap dostosowywania interfejsu najczęściej ma miejsce po uzyskaniu konkretnych tłumaczeń i polega na przygotowaniu poprawek typowo pod daną wersję.

A jak wygląda samo wprowadzanie tłumaczeń do oprogramowania? Tak, jak wspomniałem, dzięki frameworkom jest to zwykle stosunkowo proste. Troszkę nawiązywałem do tego przy okazji rozpisywania się o systemie komentarzy, a poniżej pokażę, jak to wygląda w przypadku silnika, z którego najczęściej korzystamy w Wilda Software w chwili pisania tego tekstu, a więc Yii 2.0.

Weźmy pod uwagę następujący przykład:

<h1>Twoje dane</h1>
<div>Trofea: <?= $trophyCount ?></div>
<div>Twój język: PL</div>

Taki kod HTML (a właściwie PHP, gdyż widać wstawkę z tego języka) jest poprawny, ale nieprzygotowany do internacjonalizacji - wszystkie teksty są wpisane wprost (jak to się mówi kolokwialne, "na sztywno") i tak samo zostaną wyświetlone osobie oczekującej wersji polskiej, jak i takiej wybierającej opcję angielską. Dlatego przygotujmy ten kod do i18n:

<h1><?= Yii::t('app', 'yourData') ?>:</h1>
<div><?= Yii::t('app', 'yourTrophies {n}', ['n => $trophyCount]) ?></div>
<div><?= Yii::t('app', 'yourLanguage {lang}', ['lang' => strtoupper(Yii::$app->language)]) ?></div>

Cóż, gołym okiem widać, że kod stał się bardziej skomplikowany i pojawiło się więcej wstawek PHP-owych. Metoda Yii::t odpowiada za wstawienie w dane miejsce tekstu, który znajduje się w pliku z tłumaczeniami (zaraz go sobie pokażemy). Widać zatem, że tam, gdzie wcześniej znajdowały się "normalne" teksty, teraz to framework będzie odpowiadał za znalezienie odpowiedniej wersji i wczytanie jej. Jednak sam mechanizm jest znacznie bardziej rozbudowany - umożliwia np. podział tłumaczeń na kategorie, co jest ważne w przypadku bardzo dużych aplikacji z wieloma tekstami. W powyższym przykładzie akurat używamy tylko jednej, domyślnej kategorii, którą jest "app", co oznacza, że komunikaty są zgromadzone w pliku app.php. Są one identyfikowane poprzez klucze, dopiero pod którymi znajdują się właściwe tłumaczenia. Natomiast powyższy przykład pokazuje też parametryzowanie tłumaczeń poprzez możliwość podstawienia odpowiednich zmiennych. Sam Yii 2.0 oferuje również mechanizmy do odmian mnogości czy formatowania podstawowych typów danych.

Zobaczmy zatem, jak wyglądają pliki z konkretnymi tekstami, które znajdują się w konkretnym folderze w aplikacji:

// zawartość pliku messages/pl/app.php

return [
	'yourData' => 'Twoje dane',
	'yourTrophies {n}' => 'Trofea: {n}',
	'yourLanguage {lang}' => 'Twój język: {lang}',
];

// zawartość pliku messages/en/app.php

return [
	'yourData' => 'Your data',
	'yourTrophies {n}' => 'Trophies: {n}',
	'yourLanguage {lang}' => 'Your language: {lang}',
];

Jak widać, teksty są zgromadzone w jednym miejscu (przynajmniej w teorii), dzięki czemu można łatwo je modyfikować i później tłumaczyć. Warto wspomnieć, że teoretycznie zamiast kluczy można używać konkretnych tekstów w domyślnym języku, jednak nie jest to polecane, gdyż w przypadku zmian modyfikacja musi nastąpić nie tylko w powyższym pliku, ale także we wszystkich miejscach, gdzie został użyty dany wpis.

Widać też, że Yii 2.0 oferuje możliwość pozyskania aktualnie aktywnego języka (Yii::$app->language) oraz ma odpowiednie mechanizmy do ich ręcznego i automatycznego ustawiania. Oczywiście, nie tylko ten framework to potrafi - np. Angular, wykorzystywany najczęściej we frontendach, ma swój moduł, dzięki któremu tłumaczone wpisy korzystają z plików JSON i są wstawiane w następujący sposób: {{ 'app.yourData' | translate }}. Z kolei Laravel ma jeszcze krótszy zapis: __('yourData').

Jak przebiega tłumaczenie?

Wspomniałem wyżej o tym, że teksty są zgromadzone w jednym miejscu, który zawiera minimum kodu, a właśnie skupia się głównie na treści wiadomości. Ten zbiór jest zwykle wysyłane do tłumaczy, którzy przekładają go na konkretny język, po czym odsyłają zmieniony plik, gotowy do wprowadzenia do aplikacji. Brzmi prosto, ale także tutaj trzeba powiedzieć o kilku rzeczach.

Pierwsza i podstawowa sprawa - jeśli nie zostało ustalone inaczej, software house nie odpowiada za samo tłumaczenie. Wspominałem wyżej, że zespół IT przygotowuje internacjonalizację, czyli m.in. możliwość wprowadzenia tekstów w innym języku. Natomiast to nie oznacza, że programiści siądą i sami przeprowadzą translację na pożądany przez klienta język, nawet jeśli go znają. Dotyczy to także angielskiego, choć wiadomo, że ten jest powszechny w świecie IT i siłą rzeczy programista przy okazji wprowadzania domyślnych tekstów w ojczystej mowie mógłby też wstawiać je po angielsku. Jednak nie ukrywajmy - ta osoba odpowiada za inne rzeczy, bez których oprogramowanie nie będzie poprawnie działać, a zmuszony do samodzielnej translacji po prostu skorzysta z Google Translate. Dlatego to zazwyczaj klient wprowadza swoją firmę tłumaczącą, podczas gdy zadaniem firmy IT jest ułatwić ten proces ekspertom.

Kolejna rzecz to weryfikacja sformułowania "jedno miejsce" - nie zawsze jest możliwe, aby wszystkie teksty stosowane w systemie znajdowały się w wyznaczonym pliku lub folderze. Teksty mogą być podzielone na frontend, backend czy panel administratora, a także być przechowywane w bazie danych przy odpowiednich tzw. tabelach słownikowych. Dlatego tłumacze zazwyczaj dostają nie jeden plik, tylko kilka o różnym formacie. Co rodzi podstawowy problem.

Mianowicie każde techniczne formatowanie (JSON, tablica PHP itd.), nawet dość proste, nie zawsze jest łatwe do "odczytania" dla lokalizatorów. Oczywiście, programiści dostarczają odpowiednie instrukcje, jednak należy pamiętać o tym, że w tekstach mogą pojawić się znaczniki HTML, parametry, znaki specjalne, a także sama konstrukcja plików niekiedy sprawia trochę problemów. Z doświadczenia wiemy, że zawsze są potrzebne poprawki "potłumaczeniowe", które wydłużają czas pracy. Najbezpieczniejszą formą jest arkusz kalkulacyjny, jednak wówczas to software house musi zadbać o konwertery, które wprowadzą dane teksty do aplikacji.

Każdy tłumacz wie, że niezmiernie ważny jest kontekst. Istnieją słowa lub sformułowania, które oznaczają różne rzeczy w danym języku (np. "zamek" w języku polskim), ale w innym każde z nich posiada już inną translację. Z tego powodu tłumacze powinni znać oprogramowanie, które tłumaczą lub przynajmniej omówić to z software housem czy klientem. Wiadomo jednak, że po pierwsze, nie zawsze jest na to czas, a po drugie - niekiedy nie wiadomo, czy dana kwestia faktycznie jest problematyczna (to tzw. wiedza ukryta). Ten kłopot zwykle objawia się w dziełach fabularnych, ale również zdarza się w aplikacjach.

Ostatnia kwestia dotyczy... końca. Z uwagi na to, że oprogramowanie może dynamicznie się rozwijać, dotyczy to także zbioru tekstów. Z tego powodu może się okazać, że sesji tłumaczenia będzie kilka i w czasie, kiedy poprzednia partia zostaje oddana, zostały już stworzone nowe komunikaty i to nie zawsze na końcu pliku (wówczas łatwo byłoby je wyłuskać), ale też w środku, w miejscu oryginalnych tekstów. Dodatkowo, tłumaczenie na końcu ma sens także z powodu interfejsu i całościowego ocenienia, czy wszystkie komunikaty mieszczą się na ekranie i wyglądają estetycznie.

Czy w tłumaczeniu może pomóc AI?

W wielu dziedzinach życia i tworzenia oprogramowania sztuczna inteligencja już bardzo pomaga, a wielu z Was doskonale wie, że tłumaczenia to jeden z oczywistych obszarów, gdzie Google Translate czy DeepL wspiera prace nawet profesjonalnego tłumacza. Czy można jednak całkowicie oprzeć się na tych narzędziach i rezygnować z usługi żywego eksperta?

Jak się pewnie domyślacie, odpowiedź to "raczej nie". Z jednej strony zawsze pojawią się sytuacje, w których ludzkie zrozumienie kontekstu i wiedza człowieka będą nieodzowne. Z drugiej - rozwój AI i automatycznych translatorów sprawia, że już teraz są całkiem przyzwoite w tego typu działaniach. Na pewno są kołem ratunkowym w przypadku, kiedy do przetłumaczenia są teksty w obcym języku, a brakuje czasu oraz budżetu na profesjonalistów. Natomiast w celu przetłumaczenia całego portalu np. fintechowego miałbym duże wątpliwości przy poleganiu na takich narzędziach.

Co nie zmienia faktu, że są to znakomite systemy służące jako API i wykorzystywane do proponowania tłumaczeń tekstów wprowadzanych przez użytkowników, np. kiedy uzupełniają opisy produktów w aplikacji. Nie dość, że zapewniają dużą oszczędność czasu, to dodatkowo stanowią mocny punkt pod kątem marketingowym. Ważne jest jednak to, aby wykorzystywać je jako wsparcie, a nie całkowite zastępstwo żywego specjalisty.

Czy zawsze warto internacjonalizować?

To bardzo dobre pytanie. Z doświadczenia wiemy, że wiele aplikacji powstaje z myślą o lokalnym odbiorcy lub mają bardziej wewnętrzny charakter. Można zatem domniemywać, że są przypadki, kiedy internacjonalizacja będzie nieprzydatna i okazałoby się stratą czasu. Jednak także to samo doświadczenie podpowiada, że nawet wówczas w 90% przypadków warto założyć wprowadzenie i18n i są ku temu mocne podstawy.

Najważniejszym argumentem jest fakt, że o ile na początku oprogramowanie rzeczywiście może być wykorzystywane tylko w lokalnym języku, to w równie wielu przypadkach klient w przyszłości zapragnie wprowadzić je na inny rynek, co wymaga tłumaczenia. Ale nie tylko o inny rynek chodzi - także aplikacje tworzone z myślą o konkretnych firmach muszą założyć, że nie wszyscy pracownicy tej firmy (a więc potencjalni użytkownicy) pochodzą z danego regionu. Doskonałym przykładem jest Polska, w której w wielu zakładach pracy w latach 2010-2022 znacznie zwiększyło się zatrudnienie osób zza wschodniej granicy, co sprawiło, że przydatne okazało się wprowadzenie lokalizacji ukraińskiej czy białoruskiej w celu ułatwienia pracy obcokrajowcom. Gdyby nie myślano o internacjonalizacji od początku, taka potrzeba wiązałaby się z ogromną pracą w aplikacji.

A to jest bez sensu, ponieważ w większości przypadków internacjonalizacja jest po prostu łatwa. Oczywiście, nadal wiąże się z pewną pracą do wykonania i wymaga pewnych kompromisów, ale raz wprowadzona przez większość czasu nie wymaga "opieki" podczas realizacji innych funkcji w aplikacji. Dlatego powinno się ją włączać od samego początku, kiedy oprogramowanie dopiero nabiera kształtów, aby wszyscy przyzwyczaili się do korzystania z i18n. Dużo łatwiej zrobić to wtedy niż internacjonalizować już gotowy program. Oczywiście, podchodząc do tego rozsądnie - jeśli wiemy, że nie będziemy obsługiwać np. języków azjatyckich, nie warto poświęcać długich godzin na przygotowywanie wersji RTL (czytanej od prawej do lewej).

Wprowadzanie internacjonalizacji w trakcie zaawansowanych prac ma jeszcze jedną dużą wadę - znajdowanie w kodzie miejsc, w których teksty zostały wpisane "na sztywno" i zamienianie ich na wersje tłumaczone to niezwykle żmudna i czasochłonna praca, która potrafi zniechęcić. Nie zawsze widać takie wiadomości od razu i oznacza to wnikliwe przeglądanie każdego pliku oraz przenoszenia tekstów w odpowiednie miejsce.

Oczywiście, istnieją przypadki, kiedy wiadomo, że aplikacja zostanie tylko w jednym języku. Przykładem są wewnętrzne aplikacje dla konkretnego, bardzo wąskiego grona odbiorców lub wręcz tymczasowe programy, np. wspomagające krótkotrwałe eksperymenty naukowe. Wówczas można pokusić się o pominięcie internacjonalizacji, jednak są to sytuacje szczególne i należy traktować je jako wyjątki.

Podsumowanie

Internacjonalizacja to z jednej strony temat bardzo prosty, a z drugiej dość głęboki, szczególnie w dużych aplikacjach nastawionych na globalny rynek. Najważniejszy wniosek z artykułu powinien być taki, że przy użyciu odpowiedniego frameworku, lokalizacje oprogramowania są stosunkowo proste (co nie oznacza, że nieczasochłonne), a także że warto zakładać różne wersje językowe od początku.

Pozdrawiam i dziękuję - Jakub Rojek.

We like to write, even a lot, but on a daily basis we develop web and mobile applications. Check some of the programs we have made.

About author

Jakub Rojek

Lead programmer and co-owner of Wilda Software, with many years of experience in software creation and development, but also in writing texts for various blogs. A trained analyst and IT systems architect. At the same time he is a graduate of Poznan University of Technology and occasionally teaches at this university. In his free time, he enjoys playing video games (mainly card games), reading books, watching american football and e-sport, discovering heavier music, and pointing out other people's language mistakes.

Jakub Rojek