Jak zbudować wielojęzyczną aplikację: demo z PHP i Gettext
Opublikowany: 2022-03-11Niezależnie od tego, czy tworzysz stronę internetową, czy pełnoprawną aplikację internetową, udostępnienie jej szerszej publiczności często wymaga, aby była dostępna w różnych językach i lokalizacjach.
Podstawowe różnice między większością ludzkich języków sprawiają, że wcale nie jest to łatwe. Różnice w regułach gramatycznych, niuansach językowych, formatach dat i nie tylko sprawiają, że lokalizacja jest wyjątkowym i potężnym wyzwaniem.
Rozważ ten prosty przykład.
Zasady dotyczące liczby mnogiej w języku angielskim są dość proste: możesz mieć liczbę pojedynczą lub liczbę mnogą słowa.
Jednak w innych językach – takich jak języki słowiańskie – oprócz liczby pojedynczej występują dwie formy liczby mnogiej. Możesz nawet znaleźć języki o łącznej liczbie czterech, pięciu lub sześciu form w liczbie mnogiej, na przykład w słoweńskim, irlandzkim lub arabskim.
Sposób organizacji kodu oraz sposób projektowania komponentów i interfejsu odgrywa ważną rolę w określaniu, jak łatwo można zlokalizować aplikację.
Internacjonalizacja (i18n) Twojej bazy kodu pomaga zapewnić, że można ją stosunkowo łatwo dostosować do różnych języków lub regionów. Internacjonalizacja jest zwykle wykonywana raz, najlepiej na początku projektu, aby uniknąć konieczności wprowadzania dużych zmian w kodzie źródłowym.
Po internacjonalizacji bazy kodu lokalizacja (l10n) staje się kwestią tłumaczenia zawartości aplikacji na określony język/lokal.
Lokalizację należy przeprowadzać za każdym razem, gdy trzeba obsługiwać nowy język lub region. Ponadto za każdym razem, gdy część interfejsu (zawierająca tekst) jest aktualizowana, dostępna staje się nowa treść - która następnie musi zostać zlokalizowana (tj. przetłumaczona) na wszystkie obsługiwane języki.
W tym artykule dowiemy się, jak internacjonalizować i lokalizować oprogramowanie napisane w PHP. Przejdziemy przez różne opcje wdrożenia i różne narzędzia, które są do naszej dyspozycji, aby ułatwić ten proces.
Narzędzia do internacjonalizacji
Najłatwiejszym sposobem na internacjonalizację oprogramowania PHP jest użycie plików tablicowych. Tablice zostaną wypełnione przetłumaczonymi ciągami, które można następnie wyszukać w szablonach:
<h1><?=$TRANS['title_about_page']?></h1>
Nie jest to jednak zalecany sposób w przypadku poważnych projektów, ponieważ z pewnością spowoduje to problemy z konserwacją. Pewne problemy mogą pojawić się nawet na samym początku, takie jak brak obsługi zmiennej interpolacji lub liczby mnogiej rzeczowników i tak dalej.
Jednym z najbardziej klasycznych narzędzi (często traktowanych jako odniesienie dla i18n i l10n) jest narzędzie uniksowe o nazwie Gettext.
Choć pochodzi z 1995 roku, nadal jest wszechstronnym narzędziem do tłumaczenia oprogramowania, które jest również łatwe w użyciu. Chociaż rozpoczęcie pracy jest dość łatwe, nadal ma potężne narzędzia pomocnicze.
Gettext jest tym, czego użyjemy w tym poście. Zaprezentujemy świetną aplikację GUI, którą można wykorzystać do łatwej aktualizacji plików źródłowych l10n, unikając w ten sposób konieczności obsługi wiersza poleceń.
Biblioteki ułatwiające życie
Istnieją główne frameworki i biblioteki PHP obsługujące Gettext i inne implementacje i18n. Niektóre są łatwiejsze do zainstalowania niż inne, mają dodatkowe funkcje lub obsługują różne formaty plików i18n. Chociaż w tym dokumencie skupiamy się na narzędziach dostarczanych z rdzeniem PHP, oto lista kilku innych, o których warto wspomnieć:
oscarotero/Gettext: obsługa Gettext z interfejsem obiektowym; zawiera ulepszone funkcje pomocnicze, potężne ekstraktory dla kilku formatów plików (niektóre z nich nie są obsługiwane natywnie przez polecenie
gettext
). Może również eksportować do formatów innych niż tylko pliki .mo/.po, co może być przydatne, jeśli chcesz zintegrować pliki tłumaczeń z innymi częściami systemu, takimi jak interfejs JavaScript.symfony/translation: Obsługuje wiele różnych formatów, ale zaleca używanie pełnych plików XLIFF. Nie zawiera funkcji pomocniczych ani wbudowanego ekstraktora, ale obsługuje symbole zastępcze używające wewnętrznie
strtr()
.zend/i18n: Obsługuje tablice i pliki INI lub formaty Gettext. Implementuje warstwę pamięci podręcznej, aby uniknąć konieczności odczytywania systemu plików za każdym razem. Zawiera również pomocniki widoków oraz filtry wejściowe i walidatory uwzględniające ustawienia regionalne. Jednak nie ma ekstraktora wiadomości.
Inne frameworki zawierają również moduły i18n, ale nie są one dostępne poza ich kodami bazowymi:
Laravel: Obsługuje podstawowe pliki tablic; nie ma automatycznego ekstraktora, ale zawiera pomocnika
@lang
dla plików szablonów.Yii: Obsługuje translację opartą na tablicach, Gettext i bazach danych oraz zawiera ekstraktor komunikatów. Wspierany przez rozszerzenie
Intl
, dostępne od PHP 5.3 i oparte na projekcie ICU. Pozwala to Yii na wykonywanie potężnych zamienników, takich jak pisownia liczb, formatowanie dat, godzin, interwałów, walut i liczb porządkowych.
Jeśli zdecydujesz się na jedną z bibliotek, które nie udostępniają ekstraktorów, możesz użyć formatów Gettext, więc możesz użyć oryginalnego łańcucha narzędzi Gettext (w tym Poedit), jak opisano w pozostałej części rozdziału.
Instalowanie Gettext
Być może będziesz musiał zainstalować Gettext i powiązaną bibliotekę PHP za pomocą swojego menedżera pakietów, takiego jak apt-get lub yum. Po zainstalowaniu włącz go, dodając extension=gettext.so
(Linux/Unix) lub extension=php_gettext.dll
(Windows) do pliku php.ini
.
Tutaj również będziemy używać Poedit do tworzenia plików tłumaczeniowych. Prawdopodobnie znajdziesz go w menedżerze pakietów swojego systemu; jest dostępny dla systemów Unix, Mac i Windows i można go również pobrać za darmo ze swojej strony internetowej.
Rodzaje plików Gettext
Istnieją trzy typy plików, z którymi zwykle masz do czynienia podczas pracy z Gettext.
Główne z nich to pliki PO (obiekt przenośny) i MO (obiekt maszynowy), pierwszy to lista czytelnych „przetłumaczonych obiektów”, a drugi to odpowiedni plik binarny (do interpretacji przez Gettext podczas lokalizacji). Istnieje również plik POT (szablon PO), który po prostu zawiera wszystkie istniejące klucze z plików źródłowych i może służyć jako przewodnik do generowania i aktualizowania wszystkich plików PO.
Pliki szablonów nie są obowiązkowe; w zależności od narzędzia, którego używasz do robienia l10n, będziesz w porządku tylko z plikami PO/MO. Będziesz mieć jedną parę plików PO/MO na język i region, ale tylko jeden plik POT na domenę.
Oddzielanie domen
W dużych projektach zdarzają się przypadki, w których konieczne może być rozdzielenie tłumaczeń, gdy te same słowa mają różne znaczenie w różnych kontekstach.
W takich przypadkach musisz podzielić je na różne „domeny”, które są w zasadzie nazwanymi grupami plików POT/PO/MO, gdzie nazwą pliku jest wspomniana domena tłumaczenia .
Małe i średnie projekty zwykle dla uproszczenia wykorzystują tylko jedną domenę; jego nazwa jest dowolna, ale w naszych przykładach kodu będziemy używać „main”.
Na przykład w projektach Symfony domeny są używane do oddzielania tłumaczeń dla komunikatów walidacyjnych.
Kod regionu
Ustawienia regionalne to po prostu kod, który identyfikuje jedną wersję języka. Jest zdefiniowany zgodnie ze specyfikacjami ISO 639-1 i ISO 3166-1 alpha-2: dwie małe litery dla języka, po których opcjonalnie następuje podkreślenie i dwie duże litery określające kod kraju lub regionu.
W przypadku rzadkich języków używane są trzy litery.
Dla niektórych mówców część country może wydawać się zbędna. W rzeczywistości niektóre języki mają dialekty w różnych krajach, takie jak austriacki niemiecki (de_AT) lub brazylijski portugalski (pt_BR). Druga część służy do rozróżnienia między tymi dialektami – jeśli nie ma, jest traktowana jako „ogólna” lub „hybrydowa” wersja języka.
Struktura katalogów
Aby korzystać z Gettext, musimy przestrzegać określonej struktury folderów.
Najpierw musisz wybrać dowolny katalog główny dla swoich plików l10n w repozytorium źródłowym. Wewnątrz znajdziesz folder dla każdej potrzebnej lokalizacji oraz stały folder „LC_MESSAGES”, który będzie zawierał wszystkie twoje pary PO/MO.
Formy w liczbie mnogiej
Jak powiedzieliśmy we wstępie, w różnych językach mogą obowiązywać różne zasady liczby mnogiej. Jednak Gettext oszczędza nam tych kłopotów.
Podczas tworzenia nowego pliku .po będziesz musiał zadeklarować reguły liczby mnogiej dla tego języka, a przetłumaczone fragmenty, które są wrażliwe na liczbę mnogą, będą miały inną formę dla każdej z tych reguł.
Wywołując Gettext w kodzie, będziesz musiał podać liczbę powiązaną ze zdaniem (np. dla frazy „Masz n wiadomości.”, będziesz musiał podać wartość n), a on wypracuje poprawną formę do użycia - nawet używając podstawiania ciągów w razie potrzeby.
Reguły w liczbie mnogiej składają się z liczby reguł niezbędnych z testem logicznym dla każdej reguły (test dla co najwyżej jednej reguły można pominąć). Na przykład:
japoński:
nplurals=1; plural=0;
nplurals=1; plural=0;
- jedna zasada: nie ma form liczby mnogiejangielski:
nplurals=2; plural=(n != 1);
nplurals=2; plural=(n != 1);
- dwie zasady: używaj liczby mnogiej tylko wtedy, gdy n nie jest 1, w przeciwnym razie używaj liczby pojedynczej.brazylijski portugalski:
nplurals=2; plural=(n > 1);
nplurals=2; plural=(n > 1);
- dwie zasady, używaj liczby mnogiej tylko wtedy, gdy n jest większe niż 1, w przeciwnym razie użyj liczby pojedynczej.
Aby uzyskać głębsze wyjaśnienie, dostępny jest pouczający samouczek LingoHub online.
Gettext określi, której reguły użyć na podstawie podanej liczby i użyje poprawnej zlokalizowanej wersji ciągu. W przypadku łańcuchów, które wymagają obsługi liczby mnogiej, należy do pliku .po dołączyć inne zdanie dla każdej zdefiniowanej reguły liczby mnogiej.
Przykładowa implementacja
Po całej tej teorii przejdźmy do rzeczy praktycznych. Oto fragment pliku .po (nie martw się zbytnio o składnię, ale zamiast tego po prostu poznaj ogólną zawartość):
msgid "" msgstr "" "Language: pt_BR\n" "Content-Type: text/plain; charset=UTF-8\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "We're now translating some strings" msgstr "Nos estamos traduzindo algumas strings agora" msgid "Hello %1$s! Your last visit was on %2$s" msgstr "Ola %1$s! Sua ultima visita foi em %2$s" msgid "Only one unread message" msgid_plural "%d unread messages" msgstr[0] "So uma mensagem nao lida" msgstr[1] "%d mensagens nao lidas"
Pierwsza sekcja działa jak nagłówek, ponieważ msgid
i msgstr
są puste.
Opisuje kodowanie pliku, formy liczby mnogiej i kilka innych rzeczy. Druga sekcja tłumaczy prosty ciąg z angielskiego na brazylijski portugalski, a trzecia robi to samo, ale wykorzystuje zamianę ciągu z sprintf
, umożliwiając tłumaczenie zawierające nazwę użytkownika i datę wizyty.
Ostatnia sekcja to próbka form w liczbie mnogiej, w której wersje w liczbie pojedynczej i mnogiej są wyświetlane jako msgid
w języku angielskim, a odpowiadające im tłumaczenia jako msgstr
0 i 1 (po liczbie podanej w regule liczby mnogiej).
Tam również używana jest zamiana ciągów, więc liczbę można zobaczyć bezpośrednio w zdaniu, używając %d
. Formy liczby mnogiej zawsze mają dwa msgid
(pojedynczą i mnogą), dlatego nie zaleca się używania złożonego języka jako źródła tłumaczenia.
Klucze lokalizacyjne
Jak mogłeś zauważyć, używamy rzeczywistego zdania w języku angielskim jako identyfikatora źródła. Ten sam msgid
jest używany we wszystkich plikach .po, co oznacza, że inne języki będą miały ten sam format i te same pola msgid
, ale przetłumaczone wiersze msgstr
.
Mówiąc o kluczach tłumaczeniowych, istnieją tutaj dwa standardowe podejścia „filozoficzne”:
1. msgid jako prawdziwe zdanie
Główne zalety tego podejścia to:
Jeśli istnieją części oprogramowania nieprzetłumaczone na dowolny język, wyświetlany klucz nadal zachowuje pewne znaczenie. Na przykład, jeśli wiesz, jak tłumaczyć z angielskiego na hiszpański, ale potrzebujesz pomocy w tłumaczeniu na francuski, możesz opublikować nową stronę z brakującymi francuskimi zdaniami, a części witryny będą wyświetlane w języku angielskim.
Tłumaczowi o wiele łatwiej jest zrozumieć, co się dzieje i dokonać poprawnego tłumaczenia na podstawie
msgid
.Daje „darmowe” l10n dla jednego języka - języka źródłowego.
Z drugiej strony podstawową wadą jest to, że jeśli chcesz zmienić rzeczywisty tekst, musisz zastąpić ten sam msgid
w kilku plikach językowych.
2. msgid jako unikalny, ustrukturyzowany klucz
Opisałoby to rolę zdania w aplikacji w ustrukturyzowany sposób, w tym szablon lub część, w której znajduje się ciąg zamiast jego zawartości.
To świetny sposób na zorganizowanie kodu, oddzielając treść tekstową od logiki szablonu. Może to jednak stwarzać problemy tłumaczowi, który przegapi kontekst.
Potrzebny byłby plik źródłowy w języku źródłowym jako podstawa dla innych tłumaczeń. Na przykład, programista miałby idealnie plik „en.po”, który tłumacze przeczytaliby, aby zrozumieć, co napisać w „fr.po”.
Brakujące tłumaczenia będą wyświetlać na ekranie bezsensowne klawisze („top_menu.welcome” zamiast „Witaj, użytkowniku!” na wspomnianej nieprzetłumaczonej francuskiej stronie).

To dobrze, ponieważ zmusiłoby to tłumaczenie do ukończenia przed publikacją - ale złe, ponieważ problemy z tłumaczeniem byłyby naprawdę okropne w interfejsie. Niektóre biblioteki zawierają jednak opcję określenia danego języka jako „zastępczego”, zachowując się podobnie jak inne podejście.
Podręcznik Gettext faworyzuje pierwsze podejście, ponieważ ogólnie jest to łatwiejsze dla tłumaczy i użytkowników w przypadku problemów. To podejście, którego będziemy używać również tutaj.
Należy jednak zauważyć, że dokumentacja Symfony faworyzuje tłumaczenie oparte na słowach kluczowych, aby umożliwić niezależne zmiany wszystkich tłumaczeń bez wpływu na szablony.
Codzienne użytkowanie
W typowej aplikacji możesz użyć niektórych funkcji Gettext podczas pisania statycznego tekstu na swoich stronach.
Zdania te pojawiałyby się następnie w plikach .po, były tłumaczone, kompilowane do plików .mo, a następnie używane przez Gettext podczas renderowania rzeczywistego interfejsu. Biorąc to pod uwagę, połączmy razem to, co omówiliśmy do tej pory w przykładzie krok po kroku:
1. Przykładowy plik szablonu, zawierający kilka różnych wywołań gettext
<?php include 'i18n_setup.php' ?> <div> <h1><?=sprintf(gettext('Welcome, %s!'), $name)?></h1> <!-- code indented this way only for legibility → <?php if ($unread): ?> <h2> <?=sprintf( ngettext('Only one unread message', '%d unread messages', $unread), $unread )?> </h2> <?php endif ?> </div> <h1><?=gettext('Introduction')?></h1> <p><?=gettext('We\'re now translating some strings')?></p>
gettext()
po prostu tłumaczymsgid
na odpowiadający mumsgstr
dla danego języka. Istnieje również skrócona funkcja_()
, która działa w ten sam sposóbngettext()
robi to samo, ale z regułami liczby mnogiejIstnieje również
dgettext()
idngettext()
, które pozwalają nadpisać domenę dla pojedynczego wywołania (więcej o konfiguracji domeny w następnym przykładzie)
2. Przykładowy plik instalacyjny (i18n_setup.php użyty powyżej), wybór odpowiedniego języka i konfiguracja Gettext
Korzystanie z Gettext to trochę schematyczny kod, ale przede wszystkim chodzi o skonfigurowanie katalogu locales i wybranie odpowiednich parametrów (lokalizacja i domena).
<?php /** * Verifies if the given $locale is supported in the project * @param string $locale * @return bool */ function valid($locale) { return in_array($locale, ['en_US', 'en', 'pt_BR', 'pt', 'es_ES', 'es'); } //setting the source/default locale, for informational purposes $lang = 'en_US'; if (isset($_GET['lang']) && valid($_GET['lang'])) { // the locale can be changed through the query-string $lang = $_GET['lang']; //you should sanitize this! setcookie('lang', $lang); //it's stored in a cookie so it can be reused } elseif (isset($_COOKIE['lang']) && valid($_COOKIE['lang'])) { // if the cookie is present instead, let's just keep it $lang = $_COOKIE['lang']; //you should sanitize this! } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { // default: look for the languages the browser says the user accepts $langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); array_walk($langs, function (&$lang) { $lang = strtr(strtok($lang, ';'), ['-' => '_']); }); foreach ($langs as $browser_lang) { if (valid($browser_lang)) { $lang = $browser_lang; break; } } } // here we define the global system locale given the found language putenv("LANG=$lang"); // this might be useful for date functions (LC_TIME) or money formatting (LC_MONETARY), for instance setlocale(LC_ALL, $lang); // this will make Gettext look for ../locales/<lang>/LC_MESSAGES/main.mo bindtextdomain('main', '../locales'); // indicates in what encoding the file should be read bind_textdomain_codeset('main', 'UTF-8'); // if your application has additional domains, as cited before, you should bind them here as well bindtextdomain('forum', '../locales'); bind_textdomain_codeset('forum', 'UTF-8'); // here we indicate the default domain the gettext() calls will respond to textdomain('main'); // this would look for the string in forum.mo instead of main.mo // echo dgettext('forum', 'Welcome back!'); ?>
3. Przygotowanie tłumaczenia do pierwszego uruchomienia
Jedną z wielkich zalet Gettexta w porównaniu z niestandardowymi pakietami frameworka i18n jest jego rozbudowany i potężny format plików.
Być może myślisz „O rany, to dość trudne do zrozumienia i edycji ręcznej, prosta tablica byłaby łatwiejsza!” Nie popełnij błędu, aplikacje takie jak Poedit są tutaj, aby pomóc - bardzo. Możesz pobrać program z ich strony internetowej, jest bezpłatny i dostępny na wszystkie platformy. Jest to dość łatwe narzędzie, do którego można się przyzwyczaić, a jednocześnie bardzo potężne - korzystające ze wszystkich funkcji dostępnych w Gettext. Będziemy tutaj pracować z najnowszą wersją Poedit 1.8.
W pierwszym uruchomieniu należy wybrać z menu „Plik > Nowy…”. Zostaniesz zapytany o język; wybierz/przefiltruj język, na który chcesz tłumaczyć, lub użyj formatu, o którym wspominaliśmy wcześniej, takiego jak en_US
lub pt_BR
.
Teraz zapisz plik - korzystając z tej struktury katalogów, o której wspomnieliśmy. Następnie powinieneś kliknąć „Wyodrębnij ze źródeł”, a tutaj skonfigurujesz różne ustawienia zadań ekstrakcji i tłumaczenia. Będziesz mógł je znaleźć później, wybierając „Katalog > Właściwości”:
Ścieżki źródłowe: Uwzględnij wszystkie foldery z projektu, w których wywoływana jest funkcja
gettext()
(i rodzeństwo) — zwykle jest to folder(y) szablonów/widoków. To jedyne obowiązkowe ustawienie.Właściwości tłumaczenia:
- Nazwa i wersja projektu, zespół i adres e-mail zespołu: przydatne informacje, które znajdują się w nagłówku pliku .po.
- Formy liczby mnogiej: Oto zasady, o których wspomnieliśmy wcześniej. Przez większość czasu możesz pozostawić ją z domyślną opcją, ponieważ Poedit zawiera już przydatną bazę danych dotyczących liczby mnogiej dla wielu języków.
- Zestawy znaków: najlepiej UTF-8.
- Zestaw znaków kodu źródłowego: zestaw znaków używany przez twoją bazę kodu - prawdopodobnie również UTF-8, prawda?
Słowa kluczowe źródłowe: Oprogramowanie bazowe wie, jak
gettext()
i podobne wywołania funkcji wyglądają w kilku językach programowania, ale równie dobrze możesz stworzyć własne funkcje tłumaczące. To tutaj dodasz te inne metody. Zostanie to omówione później w sekcji „Wskazówki”.
Po ustawieniu tych właściwości, Poedit przeprowadzi skanowanie plików źródłowych, aby znaleźć wszystkie wywołania lokalizacji. Po każdym skanowaniu Poedit wyświetli podsumowanie tego, co zostało znalezione i co zostało usunięte z plików źródłowych. Nowe wpisy będą puste w tabeli tłumaczeń, co pozwoli na wprowadzenie zlokalizowanych wersji tych ciągów. Zapisz go, a plik .mo zostanie (ponownie) skompilowany w tym samym folderze i, presto!, Twój projekt zostanie umiędzynarodowiony!
Poedit może również sugerować popularne tłumaczenia z sieci i z poprzednich plików. Jest to przydatne, więc musisz tylko sprawdzić, czy mają sens i je zaakceptować. Jeśli nie masz pewności co do tłumaczenia, możesz oznaczyć je jako rozmyte, a zostanie ono wyświetlone na żółto. Wpisy niebieskie to te, które nie mają tłumaczenia.
4. Tłumaczenie ciągów znaków
Jak mogłeś zauważyć, istnieją dwa główne typy zlokalizowanych łańcuchów: proste i te z formami liczby mnogiej.
Proste mają tylko dwa pola: źródłowy i zlokalizowany ciąg. Ciąg źródłowy nie może być modyfikowany, ponieważ Gettext/Poedit nie zawiera możliwości zmiany plików źródłowych; raczej będziesz musiał zmienić samo źródło i ponownie przeskanować pliki. ( Wskazówka: jeśli klikniesz prawym przyciskiem myszy wiersz tłumaczenia, wyświetli się wskazówka z plikami źródłowymi i wierszami, w których ten ciąg jest używany).
Ciągi formularzy w liczbie mnogiej obejmują dwa pola pokazujące dwa ciągi źródłowe oraz karty umożliwiające konfigurowanie różnych formularzy końcowych.
Przykład ciągu z liczbą mnogą w Poedit, pokazujący zakładkę tłumaczenia dla każdego z nich.
Za każdym razem, gdy zmienisz pliki kodu źródłowego i musisz zaktualizować tłumaczenia, po prostu naciśnij Odśwież, a Poedit ponownie przeskanuje kod, usuwając nieistniejące wpisy, scalając te, które się zmieniły i dodając nowe.
Poedit może również próbować odgadnąć niektóre tłumaczenia na podstawie innych, które zrobiłeś. Te domysły i zmienione wpisy otrzymają znacznik „Rozmyty”, wskazujący, że wymagają przeglądu, wyświetlany na żółto na liście.
Jest to również przydatne, jeśli masz zespół tłumaczy i ktoś próbuje napisać coś, czego nie jest pewien: po prostu zaznacz to Fuzzy, a ktoś inny sprawdzi to później.
Na koniec, zaleca się, aby najpierw zaznaczyć „Widok > Nieprzetłumaczone wpisy”, ponieważ pomoże to uniknąć zapomnienia jakichkolwiek wpisów. Z tego menu możesz również otworzyć części interfejsu użytkownika, które w razie potrzeby umożliwiają pozostawienie tłumaczom informacji kontekstowych.
Porady & Triki
Serwery internetowe mogą w końcu buforować twoje pliki .mo.
Jeśli używasz PHP jako modułu na Apache (mod_php), możesz napotkać problemy z buforowaniem pliku .mo. Dzieje się tak przy pierwszym odczycie, a następnie, aby go zaktualizować, może być konieczne ponowne uruchomienie serwera.
W Nginx i PHP5 zwykle odświeżenie pamięci podręcznej tłumaczeń zajmuje tylko kilka odświeżeń strony, a w PHP7 jest to rzadko potrzebne.
Biblioteki zapewniają funkcje pomocnicze, dzięki którym kod lokalizacji jest krótki.
Jak woli wielu ludzi, łatwiej jest użyć _()
zamiast gettext()
. Wiele niestandardowych bibliotek i18n z frameworków również używa czegoś podobnego do t()
, aby skrócić przetłumaczony kod. Jest to jednak jedyna funkcja, która ma skrót.
Możesz chcieć dodać do swojego projektu kilka innych, takich jak __()
lub _n()
dla ngettext()
, a może fantazyjny _r()
, który łączyłby wywołania gettext()
i sprintf()
. Inne biblioteki, takie jak Gettext firmy Oscarotero, również udostępniają funkcje pomocnicze, takie jak te.
W takich przypadkach będziesz musiał poinstruować narzędzie Gettext, jak wyodrębnić ciągi z tych nowych funkcji. Nie bój się, to bardzo proste. To tylko pole w pliku .po lub ekran Ustawienia w Poedit (w edytorze ta opcja znajduje się w „Katalog > Właściwości > Słowa kluczowe źródła”).
Pamiętaj: Gettext już zna domyślne funkcje dla wielu języków, więc nie przejmuj się, jeśli ta lista wydaje się pusta. Musisz uwzględnić na tej liście specyfikacje nowych funkcji, zgodnie z następującym formatem:
Jeśli tworzysz coś takiego jak
t()
, które po prostu zwraca tłumaczenie dla łańcucha, możesz określić to jakot
. Gettext będzie wiedział, że jedynym argumentem funkcji jest ciąg do przetłumaczenia;Jeśli funkcja ma więcej niż jeden argument, możesz określić, w którym z nich jest pierwszy ciąg i, jeśli to konieczne, także liczbę mnogą. Na przykład, jeśli podpis naszej funkcji to
__('one user', '%d users', $number)
, specyfikacją będzie__:1,2
, co oznacza, że pierwsza forma to pierwszy argument, a druga forma to drugi argument. Jeśli zamiast tego twoja liczba jest pierwszym argumentem, specyfikacją będzie__:2,3
, co oznacza, że pierwsza forma jest drugim argumentem i tak dalej.
Po dołączeniu tych nowych reguł do pliku .po nowe skanowanie przyniesie nowe ciągi równie łatwo, jak poprzednio.
Spraw, aby Twoja aplikacja PHP była wielojęzyczna dzięki Gettext
Gettext jest potężnym narzędziem do internacjonalizacji twojego projektu PHP. Poza elastycznością, która umożliwia obsługę dużej liczby języków ludzkich, obsługa ponad 20 języków programowania umożliwia łatwe przeniesienie wiedzy na temat używania go z PHP do innych języków, takich jak Python, Java lub C#.
Co więcej, Poedit może pomóc wygładzić ścieżkę między kodem a przetłumaczonymi ciągami, czyniąc proces prostszym i łatwiejszym do naśladowania. Może również usprawnić wspólne tłumaczenia dzięki integracji z Crowdin.
Jeśli to możliwe, rozważ inne języki, którymi posługują się Twoi użytkownicy. Jest to szczególnie ważne w przypadku projektów innych niż angielski: możesz zwiększyć dostęp użytkownika, jeśli opublikujesz go w języku angielskim, a także w swoim ojczystym języku.
Oczywiście nie wszystkie projekty wymagają internacjonalizacji, ale znacznie łatwiej jest rozpocząć i18n w początkach projektu, nawet jeśli początkowo nie jest to potrzebne, niż zrobić to później, jeśli później stanie się to wymogiem. A dzięki narzędziom takim jak Gettext i Poedit jest to łatwiejsze niż kiedykolwiek.