Liczba mnoga (msgid_plural) w plikach „po” gettext-a w django

Django jest rozbudowanym frameworkiem przewidzianym m.in. do tworzenia wielojęzykowych serwisów. Wykonanie strony w kilku wersjach językowych wymaga uwzględnienia wielu zagadnień, takich jak formaty daty, czasu, waluty a nawet oznaczania części dziesiętnych w liczbach. W poszczególnych językach różny jest porządek sortowania choćby z uwagi na znaki narodowe wzbogacone o akcenty czy ogonki – jak w naszym rodzimym, polskim języku. Sporym wyzwaniem jest też gramatyka w tym szyk zdania, przypadki i liczba mnoga.

Django jest przygotowane do pracy z gettext-em – oprogramowaniem do tworzenia tłumaczeń. To profesjonalne narzędzie uzupełnione wieloplatformowym edytorem plików poedit służącym do edycji plików „.po” (rozszerzenie plików źródłowych gettext-a) i jednocześnie kompilującym owe pliki do formatu binarnego „.mo” przyspiesza i ułatwia umiędzynaradawianie oprogramowania tworzonego w przeróżnych językach programowania. Ja z powodzeniem używałem gettexta w aplikacjach PHP i Python.

Standardowo treść pliku „.po” składa się z szeregu par zmiennych msgid i msgstr, z których pierwsza zawiera treść komunikatu oryginalnego, a druga tłumaczenie.

msgid "Komunikat oryginalny"
msgstr "Tłumaczenie komunikatu"

Istnieją jednak komunikaty wymagające uwzględnienia liczby mnogiej. Na przykład zawierające zmienną wypełnianą dynamicznie.

msgid "We offer %(num_homes)d homes for sale "

Format gettext-a uwzględnia wiele aspektów poszczególnych języków narodowych w tym m.in. różny sposób tworzenia liczby mnogiej. W przypadku języka polskiego jest to sprawa o tyle skomplikowana, że jeden rzeczownik może mieć kilka form liczby mnogiej zależnie od liczby elementów.

Mamy w ofercie 2 domy na sprzedaż
Mamy w ofercie 5 domów na sprzedaż

W takim wypadku wpis w pliku „.po” może wyglądać następująco. Uwzględniona jest wersja pojedyncza oraz wersje mnogie.

msgid "Please correct the error below."
msgid_plural "Please correct %(num_errors)d errors below."
msgstr[0] "Proszę poprawić poniższy błąd."
msgstr[1] "Proszę poprawić %(num_errors)d poniższe błędy."
msgstr[2] "Proszę poprawić %(num_errors)d poniższych błędów."

Aby gettext wiedział jaką logiką ma się posługiwać przy konstruowaniu liczby mnogiej należy go o tym poinformować. Oprócz wyżej wspomnianych zmiennych zawierających etykiety komunikatów oraz komunikaty właściwe, w plikach „.po” znajdują się też komentarze informujące m.in o tym w jakim pliku i w której linii dany komunikat się znajduje. Są też tzw. nagłówki stanowiące swego rodzaju metadane plików tłumaczeń.

Przykładowe nagłówki:

"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 0.2\n"

Większość tychże nagłówków najlepiej pozostawić w postaci oryginalnej, jednak nagłówek informujący o formacie liczby mnogiej może wymagać dodania lub też zmiany.

"Plural-Forms: nplurals=2; plural=(n != 1);\n"

Taki nagłówek jest prawidłowy m.in dla języka angielskiego, niemieckiego, hiszpańskiego itd. Nagłówek dla wersji polskiej jest już bardziej rozbudowany.

Plural-Forms: nplurals=3; \
              plural=n==1 ? 0 : \
                     n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;

Szczegółową listę nagłówków dla różnych języków i grup językowych można znaleźć w dokumentacji getext-a w części poświęconej formom liczby mnogiej.

Na zakończenie dodam jedynie, że brak tego nagłówka w pliku „.po” przy próbie jego zapisu kończy się komunikatem o błędzie krytycznym. W moim przypadku jeśli edytowany był wpis przewidujący liczby mnogie to usunięciu uległy wszystkie zmienne msgstr[0], msgstr[1] itd. znajdujące się pod msgid_plural owych wpisów. Plik był mimo to zapisywany co przy próbie ponownego otwarcia pliku „.po” kończyło się komunikatem o uszkodzeniu pliku. Można to było łatwo naprawić dodają wyżej wspomniane zmienne, jednak problem ostatecznie został rozwiązany po dodaniu odpowiedniego nagłówka.