FunkcjeWtyczkaCennikZasoby
Zmień język
ZasobyUżywanie msgctxt: Dodawanie kontekstu do tłumaczeń Gettext

Używanie msgctxt: Dodawanie kontekstu do tłumaczeń Gettext

SimplePoTranslate Team15 maja 2026
Używanie msgctxt: Dodawanie kontekstu do tłumaczeń Gettext

Tłumaczysz angielskie słowo „Book” na niemiecki, a Twój tłumacz pewnie zwraca „Buch”. Trzy tygodnie później pojawia się zgłoszenie błędu: przycisk „Book a table” na Twoim formularzu rezerwacji brzmi teraz „Buch a table” – rzeczownik, a nie czasownik. Słowo było poprawne. Brakowało kontekstu. To jedna z najczęstszych, cichych awarii w lokalizacji oprogramowania, a rozwiązanie istnieje w Gettext od dziesięcioleci: msgctxt.

Jeśli kiedykolwiek udostępniłeś tłumaczenie, w którym jeden angielski ciąg znaków był poprawny w jednym miejscu, a bezsensowny w innym, napotkałeś problem dwuznaczności. To samo słowo źródłowe mapuje się na różne tłumaczenia w zależności od miejsca jego wystąpienia. Bez msgctxt tłumacz (człowiek lub AI) nie ma jak odróżnić tych przypadków, ponieważ widzi jedynie surowy ciąg msgid "Book". Ten przewodnik wyjaśnia, jak msgctxt działa w Gettext, jak oznaczyć swój kod źródłowy za pomocą _x() i _ex(), jak pojawia się w plikach .po oraz dlaczego potok tłumaczeniowy uwzględniający kontekst jest jedynym niezawodnym sposobem na poprawne tłumaczenie tych ciągów na dużą skalę.

Problem Dwuznaczności: Jedno Słowo, Wiele Znaczeń

Język naturalny jest pełen słów, które w języku angielskim sprowadzają się do jednego tokenu, ale w innych językach dzielą się na wiele słów. Tłumacz widzi tylko ciąg źródłowy, więc gdy dwa niepowiązane elementy interfejsu użytkownika dzielą to samo angielskie słowo, dzielą to samo msgid – a Gettext łączy je w jeden wpis.

Słowa, które dzielą się w różnych językach

Rozważ trzy klasyczne przykłady:

  • „Book” – rzeczownik (przedmiot na półce) kontra czasownik („Book a flight”). Niemiecki: Buch kontra buchen.
  • „Post” – publikowanie treści kontra wysyłanie poczty. Francuski: publier kontra courrier.
  • „Order” – sekwencja/sortowanie kontra zakup. Hiszpański: orden kontra pedido.

W języku angielskim Twój kod używa tego samego ciągu literalnego w obu miejscach:

// Somewhere in a library catalog screen
echo __( 'Book', 'mytextdomain' );

// Somewhere in a reservation form button
echo __( 'Book', 'mytextdomain' );

Jak identyczne ciągi zapadają się w jeden wpis

Kiedy uruchamiasz wp i18n make-pot lub xgettext, oba wywołania zbiegają się w jeden wpis .po:

#: catalog.php:42 reservation-form.php:88
msgid "Book"
msgstr ""

Jest dokładnie jeden msgstr do wypełnienia. Niezależnie od tego, co wybierze tłumacz, jeden z dwóch ekranów będzie błędny. Tłumacz nie może tego naprawić, nawet jeśli rozumie problem, ponieważ sam format nie pozwala mu dostarczyć dwóch tłumaczeń dla jednego msgid. Dwuznaczność jest wbudowana w dane.

Czym jest msgctxt i jak usuwa dwuznaczności?

msgctxt to ciąg kontekstowy dołączony do wpisu tłumaczeniowego. Krótka odpowiedź: dodaje drugi klucz obok msgid, więc Gettext traktuje (kontekst, msgid) jako unikalną parę. Dwa wpisy z tym samym msgid, ale różnymi msgctxt stają się dwoma oddzielnymi, niezależnie tłumaczalnymi ciągami.

W modelu wyszukiwania Gettext tłumaczenie jest zazwyczaj kluczowane tylko za pomocą ciągu źródłowego. Z msgctxt kluczem staje się kombinacja kontekstu plus źródła. To cały mechanizm i dlatego działa tak czysto: nie zmieniasz wyświetlanego tekstu, a jedynie wewnętrzny klucz wyszukiwania.

Linia msgctxt w pliku .po

W pliku .po kontekst pojawia się w oddzielnej linii bezpośrednio nad msgid:

#: catalog.php:42
msgctxt "noun"
msgid "Book"
msgstr "Buch"

#: reservation-form.php:88
msgctxt "verb"
msgid "Book"
msgstr "Reservieren"

Teraz są dwa wpisy. Mają identyczne wartości msgid, ale różne wartości msgctxt, więc każdy otrzymuje swój własny msgstr. Katalog wyświetla Buch; przycisk rezerwacji wyświetla Reservieren. Środowisko wykonawcze wybiera właściwy, ponieważ Twój kod poinstruował je, którego kontekstu użyć.

Porównaj to z powyższą, błędną wersją z pojedynczym wpisem. Różnica nie polega na jakości tłumaczenia – chodzi o to, czy model danych w ogóle pozwala na istnienie poprawnej odpowiedzi.

Oznaczanie kodu: _x() i _ex()

Aby wyemitować msgctxt do szablonu .po, wywołujesz funkcję tłumaczącą uwzględniającą kontekst zamiast zwykłej. W WordPress są to _x() i jej wywołująca echo siostra _ex(); w czystym Gettext mapują się na pgettext().

Wybór między _x() a _ex()

Zwykła funkcja __() przyjmuje ciąg znaków i domenę tekstową. Wariant kontekstowy wstawia kontekst jako drugi argument:

// Without context - ambiguous
__( 'Book', 'mytextdomain' );

// With context - the second argument is the msgctxt
_x( 'Book', 'noun', 'mytextdomain' );        // returns the translated string
_ex( 'Book', 'verb', 'mytextdomain' );       // echoes it directly

// Real-world disambiguation
_x( 'Post', 'verb: publish content', 'mytextdomain' );
_x( 'Post', 'noun: mail item', 'mytextdomain' );
_x( 'Order', 'sequence or sorting', 'mytextdomain' );
_x( 'Order', 'customer purchase', 'mytextdomain' );

Drugi argument to etykieta kontekstu. Nigdy nie jest ona wyświetlana użytkownikom – istnieje wyłącznie w celu usunięcia dwuznaczności, zarówno dla wyszukiwania w Gettext, jak i dla osoby (lub czegokolwiek), która dokonuje tłumaczenia. Pisz konteksty jako krótkie, opisowe wskazówki: 'noun', 'verb', 'button label', 'admin menu'. Niejasny kontekst, taki jak '1', jest technicznie poprawny, ale bezużyteczny dla tłumacza.

Kiedy regenerujesz szablon, ekstraktor rozpoznaje te wywołania i emituje linię msgctxt. Narzędzia takie jak Poedit i inne edytory PO grupują następnie wpisy wizualnie według kontekstu, więc ludzki tłumacz natychmiast widzi, że „Book (rzeczownik)” i „Book (czasownik)” to dwie różne prace. Jeśli nadal konfigurujesz swój łańcuch narzędzi do ekstrakcji lub zmagasz się z tym, jak zmienne wchodzą w interakcje z tymi ciągami, nasz przewodnik Tłumaczenie plików PO bez uszkadzania zmiennych kodu szczegółowo omawia otaczający przepływ pracy.

Dlaczego naiwni tłumacze – i wiele narzędzi AI – popełniają błędy w tym zakresie

Oto niewygodna część. Dodanie msgctxt do kodu źródłowego jest konieczne, ale niewystarczające. Kontekst pomaga tylko, jeśli to, co dokonuje tłumaczenia, faktycznie go odczytuje.

Tryb awarii z odrzuconym kontekstem

Naiwny skrypt tłumaczenia wsadowego działa tak: przechodzi przez wpisy, pobiera każdy msgid, wysyła go do API tłumaczeniowego i zapisuje wynik do msgstr. Nigdy nie patrzy na linię msgctxt. Więc nawet jeśli starannie napisałeś _x( 'Book', 'noun' ) i _x( 'Book', 'verb' ), skrypt wysyła dwa identyczne żądania – „przetłumacz Book” – i wkleja tę samą odpowiedź do obu. Cały Twój wysiłek włożony w oznaczanie jest odrzucany w ostatnim kroku.

Wiele ogólnych narzędzi do tłumaczenia AI ma ten sam martwy punkt. Są one zbudowane do tłumaczenia tekstu, a msgctxt to metadane, a nie tekst. Jeśli narzędzie spłaszcza Twój plik .po do listy ciągów przed wysłaniem go do modelu, kontekst nigdy nie dociera do promptu modelu. Model, pozbawiony jakiegokolwiek sygnału, domyślnie wybiera najbardziej statystycznie powszechne znaczenie słowa – zazwyczaj rzeczownik dla „Book”, sens publikowania dla „Post” – i po cichu błędnie tłumaczy przypadki rzadziej występujące. Nie zobaczysz błędu. Zobaczysz zgłoszenie błędu od niemieckiego użytkownika tygodnie później.

Kontekst i liczby mnogie dzielą tę samą przyczynę źródłową

To także miejsce, gdzie krzyżują się obsługa liczby mnogiej i kontekst, ponieważ oba zależą od tego, czy narzędzie rozumie strukturę Gettext, a nie traktuje pliku jako płaskiego tekstu. Jeśli Twoje ciągi znaków obejmują również formy oparte na liczbie, ta sama świadomość strukturalna jest ważna – omawiamy to szczegółowo w Zrozumienie liczby mnogiej w Gettext.

Jak potok świadomy kontekstu używa msgctxt

Potok tłumaczeniowy, który szanuje msgctxt, działa odwrotnie niż naiwny skrypt. Parsuje plik .po jako dane strukturalne, utrzymuje kontekst każdego wpisu dołączony do jego ciągu źródłowego i przekazuje ten kontekst do AI jako część promptu – dzięki czemu model wie, że tłumaczy „Book” konkretnie jako czasownik, a nie abstrakcyjnie.

Kontekst jako sygnał pierwszej klasy

Tak właśnie SimplePoTranslate podchodzi do problemu. Jego AI świadome kontekstu odczytuje linię msgctxt jako sygnał pierwszej klasy: gdy dwa wpisy mają wspólny msgid, ale różnią się kontekstem, są tłumaczone jako odrębne ciągi, którymi faktycznie są, a wskazówka kontekstowa informuje model o wyborze słowa. Rezultatem jest to, że „Book (rzeczownik)” wraca jako Buch, podczas gdy „Book (czasownik)” wraca jako buchen lub reservieren – automatycznie, bez ręcznego poprawiania każdego dwuznacznego terminu.

Co równie ważne, potok zachowuje linię msgctxt w wyjściu. Słabsze narzędzie mogłoby usunąć kontekst podczas dwukierunkowej konwersji, cicho łącząc Twoje dwa wpisy z powrotem w jeden i ponownie wprowadzając dwuznaczność przy następnym scaleniu. Pełne wsparcie Gettext oznacza, że kontekst przetrwa tłumaczenie, kompilację .mo i wszelkie późniejsze ponowne importy – dzięki czemu Twoje usunięcie dwuznaczności jest trwałe, a nie jednorazową ręczną poprawką. W połączeniu z Syntax Locking dla symboli zastępczych wewnątrz tych ciągów, otrzymujesz tłumaczenia, które są zarówno kontekstowo poprawne, jak i strukturalnie nienaruszone.

Decyzja o oznaczeniu nadal należy do Ciebie – tylko Ty wiesz, że dane „Book” to czasownik. Ale po tym, jak opatrzyłeś swój kod źródłowy adnotacjami _x() i _ex(), potok świadomy kontekstu przekształca tę adnotację w poprawne tłumaczenia we wszystkich językach docelowych, bez konieczności nadzorowania każdego ciągu z osobna.

Podsumowanie

Problem dwuznaczności – jedno angielskie słowo, wiele znaczeń – nie jest dziwactwem, które można zignorować; to strukturalna cecha sposobu, w jaki Gettext przechowuje ciągi. Rozwiązaniem jest msgctxt: oznacz dwuznaczne ciągi w swoim kodzie źródłowym za pomocą _x() i _ex(), nadaj każdemu wystąpieniu jasną etykietę kontekstu i pozwól Gettext kluczować tłumaczenie na podstawie pary (kontekst, msgid). Ta część zależy od Ciebie i zajmuje minuty.

Trudniejsza część to upewnienie się, że Twój etap tłumaczenia faktycznie honoruje ten kontekst, zamiast go odrzucać. Naiwne skrypty i narzędzia AI oparte tylko na tekście odrzucają msgctxt i ponownie wprowadzają dokładnie ten błąd, którego próbowałeś zapobiec. Potok świadomy kontekstu odczytuje kontekst, poprawnie tłumaczy każdy jednoznaczny wpis i zachowuje go podczas kompilacji i ponownych importów.

Gotowy, aby przestać dostarczać tłumaczenia ignorujące kontekst? Wypróbuj SimplePoTranslate za darmo — karta kredytowa nie jest wymagana. Darmowy plan obsługuje prawdziwe pliki .po i .pot z pełnym wsparciem kontekstu msgctxt, dzięki czemu Twoje jednoznaczne ciągi są tłumaczone poprawnie za pierwszym razem.

Powiązane tematy