FunkcePluginCeníkZdroje
Změnit jazyk
ZdrojePoužívání msgctxt: Přidání kontextu do překladů Gettextu

Používání msgctxt: Přidání kontextu do překladů Gettextu

SimplePoTranslate Team15. května 2026
Používání msgctxt: Přidání kontextu do překladů Gettextu

Přeložíte anglické slovo „Book“ do němčiny a váš překladatel s jistotou vrátí „Buch“. O tři týdny později se objeví hlášení o chybě: tlačítko „Book a table“ (rezervovat stůl) na vašem rezervačním formuláři nyní zní „Buch a table“ – podstatné jméno, nikoli sloveso. Slovo bylo správné. Chyběl kontext. Toto je jedna z nejčastějších tichých chyb v softwarové lokalizaci a oprava existuje v Gettextu už desítky let: msgctxt.

Pokud jste někdy vydali překlad, kde byl jeden anglický řetězec správný na jednom místě a nesmyslný na jiném, narazili jste na problém nejednoznačnosti. Stejné zdrojové slovo se mapuje na různé překlady v závislosti na tom, kde se objeví. Bez msgctxt překladatel (člověk nebo AI) nemá způsob, jak tyto případy rozlišit, protože vše, co vidí, je holý řetězec msgid "Book". Tato příručka vysvětluje, jak msgctxt funguje v Gettextu, jak označit váš zdrojový kód pomocí _x() a _ex(), jak se projevuje ve vašich souborech .po a proč je překladatelský pipeline s vědomím kontextu jediným spolehlivým způsobem, jak tyto řetězce správně přeložit ve velkém měřítku.

Problém nejednoznačnosti: Jedno slovo, mnoho významů

Přirozený jazyk je plný slov, která se v angličtině zhroutí do jednoho tokenu, ale v jiných jazycích se rozdělí na více slov. Překladatel vidí pouze zdrojový řetězec, takže když dva nesouvisející prvky uživatelského rozhraní sdílejí stejné anglické slovo, sdílejí stejný msgid – a Gettext je sloučí do jedné položky.

Slova, která se v různých jazycích dělí

Zvažte tři klasické příklady:

  • „Book“ – podstatné jméno (předmět na poličce) versus sloveso („Book a flight“ – rezervovat let). Německy: Buch versus buchen.
  • „Post“ – publikovat obsah versus poslat poštu. Francouzsky: publier versus courrier.
  • „Order“ – pořadí/řazení versus nákup. Španělsky: orden versus pedido.

V angličtině váš kód používá stejný literální řetězec na obou místech:

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

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

Jak se identické řetězce sloučí do jedné položky

Když spustíte wp i18n make-pot nebo xgettext, oba volání se sloučí do jedné položky .po:

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

Je zde přesně jeden msgstr, který je třeba vyplnit. Cokoli si překladatel vybere, jedna ze dvou obrazovek bude špatně. Překladatel to nemůže opravit, i kdyby problému rozuměl, protože samotný formát mu neumožňuje poskytnout dva překlady pro jeden msgid. Nejednoznačnost je zakódována přímo v datech.

Co je msgctxt a jak odstraňuje nejednoznačnost?

msgctxt je kontextový řetězec připojený k položce překladu. Krátká odpověď: přidává druhý klíč vedle msgid, takže Gettext považuje (kontext, msgid) za jedinečnou dvojici. Dvě položky se stejným msgid, ale odlišným msgctxt se stanou dvěma samostatnými, nezávisle přeložitelnými řetězci.

V modelu vyhledávání Gettextu je překlad obvykle klíčován pouze podle zdrojového řetězce. S msgctxt se klíč stává kombinací kontextu a zdroje. To je celý mechanismus a proto funguje tak čistě: neměníte zobrazený text, pouze interní vyhledávací klíč.

Řádek msgctxt v souboru .po

V souboru .po se kontext objeví na svém vlastním řádku přímo nad msgid:

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

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

Nyní jsou zde dvě položky. Mají identické hodnoty msgid, ale odlišné hodnoty msgctxt, takže každá dostane svůj vlastní msgstr. Katalog zobrazí Buch; tlačítko rezervace zobrazí Reservieren. Runtime vybere správnou, protože váš kód mu řekl, jaký kontext má použít.

Porovnejte to s poškozenou verzí s jednou položkou výše. Rozdíl není v kvalitě překladu – je v tom, zda datový model vůbec umožňuje existenci správné odpovědi.

Označování kódu: _x() a _ex()

Pro vložení msgctxt do vaší .po šablony voláte funkci překladu s vědomím kontextu namísto té obyčejné. Ve WordPressu jsou to _x() a její ozvěnující se sourozenec _ex(); v čistém Gettextu se mapují na pgettext().

Volba mezi _x() a _ex()

Běžná funkce __() přijímá řetězec a textovou doménu. Varianta s kontextem vkládá kontext jako druhý 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' );

Druhým argumentem je popisek kontextu. Ten se nikdy nezobrazuje uživatelům – slouží čistě k odstranění nejednoznačnosti, a to jak pro vyhledávání v Gettextu, tak pro toho (nebo to), kdo překládá. Konteksty pište jako krátké, popisné nápovědy: 'podstatné jméno', 'sloveso', 'popisek tlačítka', 'administrační menu'. Vágní kontext jako '1' je technicky platný, ale pro překladatele bezvýznamný.

Když šablonu znovu vygenerujete, extraktor rozpozná tato volání a vypíše řádek msgctxt. Nástroje jako Poedit a další PO editory pak položky viditelně seskupí podle kontextu, takže lidský překladatel okamžitě vidí, že „Book (podstatné jméno)“ a „Book (sloveso)“ jsou dvě různé úlohy. Pokud stále propojujete svůj extrakční nástrojový řetězec nebo bojujete s tím, jak proměnné interagují s těmito řetězci, náš průvodce překladem souborů PO bez narušení kódu proměnných podrobně popisuje související pracovní postup.

Proč se naivní překladatelé – a mnoho nástrojů AI – v tomto mýlí

Zde je ta nepříjemná část. Přidání msgctxt do vašeho zdroje je nutné, ale ne dostačující. Kontext pomůže pouze tehdy, když ho to, co překládá, skutečně přečte.

Režim selhání se zahodeným kontextem

Naivní skript pro dávkový překlad dělá toto: prochází položky, vezme každý msgid, pošle ho do překladatelského API a zapíše výsledek do msgstr. Nikdy se nepodívá na řádek msgctxt. Takže i když jste pečlivě napsali _x( 'Book', 'noun' ) a _x( 'Book', 'verb' ), skript pošle dva identické požadavky – „přeložit Book“ – a stejnou odpověď vloží do obou. Veškeré vaše úsilí o označení je v posledním kroku zahozena.

Mnoho obecných nástrojů pro AI překlad má stejnou slepou skvrnu. Jsou vytvořeny pro překlad textu a msgctxt jsou metadata, nikoli text. Pokud nástroj zploští váš .po soubor do seznamu řetězců před odesláním do modelu, kontext se nikdy nedostane do modelu. Model, postrádající jakýkoli signál, se uchýlí k nejstatističtěji běžnému významu slova – obvykle podstatné jméno pro „Book“, význam „publikovat“ pro „Post“ – a tiše nesprávně přeloží menšinový případ. Neuvidíte žádnou chybu. Uvidíte hlášení o chybě od německého uživatele o několik týdnů později.

Kontext a množné číslo sdílejí stejnou kořenovou příčinu

Zde se také protíná zpracování množného čísla a kontextu, protože obojí závisí na tom, zda nástroj rozumí struktuře Gettextu, spíše než aby soubor zpracovával jako plochý text. Pokud vaše řetězce také zahrnují formy založené na počtu, záleží na stejném strukturálním povědomí – to rozebíráme v pochopení plurálů Gettextu.

Jak pipeline s vědomím kontextu používá msgctxt

Překladatelský pipeline, který respektuje msgctxt, dělá opak naivního skriptu. Analyzuje soubor .po jako strukturovaná data, udržuje kontext každé položky připojený k jejímu zdrojovému řetězci a předává tento kontext AI jako součást promptu – takže model ví, že překládá „Book“ konkrétně jako sloveso, nikoli abstraktně.

Kontext jako prvotřídní signál

Přesně takto k problému přistupuje SimplePoTranslate. Její AI s vědomím kontextu čte řádek msgctxt jako prvotřídní signál: když dvě položky sdílejí msgid, ale liší se v kontextu, jsou přeloženy jako skutečně odlišné řetězce, a nápověda kontextu ovlivňuje volbu slova modelem. Výsledkem je, že „Book (podstatné jméno)“ se vrátí jako Buch, zatímco „Book (sloveso)“ se vrátí jako buchen nebo reservieren – automaticky, aniž byste museli ručně opravovat každý nejednoznačný termín.

Stejně důležité je, že pipeline zachovává řádek msgctxt ve výstupu. Slabší nástroj by mohl kontext odstranit během opakovaného zpracování, tiše by sloučil vaše dvě položky zpět do jedné a při dalším sloučení by znovu zavedl nejednoznačnost. Plná podpora Gettextu znamená, že kontext přežije překlad, kompilaci .mo a jakékoli pozdější opětovné importy – takže vaše odstranění nejednoznačnosti je trvalé, nikoli jednorázová manuální oprava. V kombinaci s blokováním syntaxe pro zástupné symboly uvnitř těchto řetězců získáte překlady, které jsou kontextově správné i strukturálně neporušené.

Stále je na vás rozhodnutí o označení – pouze vy víte, že dané „Book“ je sloveso. Ale jakmile svůj zdrojový kód opatříte anotacemi pomocí _x() a _ex(), pipeline s vědomím kontextu přemění tuto anotaci na správné překlady ve všech cílových jazycích bez nutnosti ruční kontroly každého řetězce.

Závěr

Problém nejednoznačnosti – jedno anglické slovo, mnoho významů – není jen libůstka, kterou můžete ignorovat; je to strukturální rys toho, jak Gettext ukládá řetězce. Řešením je msgctxt: anotujte nejednoznačné řetězce ve svém zdrojovém kódu pomocí _x() a _ex(), každému výskytu dejte jasný kontextový popisek a nechte Gettext klíčovat překlad na základě dvojice (kontext, msgid). Tato část je na vás a trvá jen minuty.

Těžší částí je zajistit, aby váš překladatelský krok skutečně respektoval tento kontext, namísto jeho zahazování. Naivní skripty a textové nástroje AI msgctxt ignorují a znovu zavádějí přesně tu chybu, které jste se snažili předejít. Pipeline s vědomím kontextu přečte kontext, správně přeloží každou jednoznačnou položku a zachová ji během kompilace a opětovných importů.

Jste připraveni přestat dodávat překlady bez kontextu? Vyzkoušejte SimplePoTranslate zdarma – není potřeba platební karta. Bezplatná úroveň zpracovává skutečné soubory .po a .pot s plnou podporou kontextu msgctxt, takže se vaše jednoznačné řetězce přeloží správně hned napoprvé.

Související témata