Så här översätter du Drupal .po-filer med AI

De flesta associerar .po-filer med WordPress, men gettext-formatet föregick WordPress med årtionden och driver gränssnittsöversättning i hela open source-världen. Drupal är en av dess största användare. Om du driver en flerspråkig Drupal-webbplats flödar varje menylänk, fältbeskrivning, felmeddelande och modulsträng genom .po-filer precis som i WordPress, bara med en annan platshållardialekt och ett annat importarbetsflöde. Och precis som med WordPress, så fort din webbplats växer sig större än ett fåtal strängar, blir manuell översättning av dessa filer flaskhalsen.
Den här guiden handlar om hur man översätter Drupal po-filer med AI utan att förstöra det som gör Drupal till Drupal. Vi kommer att gå igenom Drupals översättningssystem, var strängarna faktiskt kommer ifrån, platshållarsyntaxen som skiljer sig från WordPress och absolut måste bevaras, samt hela loopen för export, översättning och återimport, inklusive drush-kommandon som gör den repeterbar.
Hur Drupals översättningssystem fungerar
Drupal hanterar gränssnittsöversättning via kärnmodulen locale (ibland kallad "Interface Translation" i moderna Drupal). När den är aktiverad hanterar den en databastabell med källsträngar och deras översättningar per språk, och den kan importera och exportera dessa översättningar som standard gettext .po-filer.
Administrationsgränssnittet finns på /admin/config/regional/translate. Därifrån kan du söka efter oöversatta strängar, redigera dem direkt och, viktigast av allt, importera en .po-fil för att massladda översättningar eller exportera det aktuella läget till en .po-fil för offline-redigering. Denna export-/redigera-/importcykel är det arbetsflöde vi optimerar.
Till skillnad från WordPress, där varje plugin och tema levereras med sina egna .po- och .mo-filer i en languages/-katalog, centraliserar Drupal gränssnittssträngar i sin databas och behandlar .po som utbytesformat. Du exporterar, arbetar med filen och importerar den tillbaka. Det kompilerade .mo-steget som WordPress kräver hanteras internt.
Var strängarna kommer ifrån
Drupal-strängar kommer från tre platser, och en komplett översättning måste täcka alla:
- Kärnan levererar tusentals översättbara strängar för admin-gränssnittet, formulär och systemmeddelanden.
- Bidragsmoduler (Views, Webform, Commerce och resten) registrerar var och en sina egna strängar via
t()-funktionen. - Teman bidrar med mallsträngar, regionetiketter och temainställningsbeskrivningar.
När du exporterar från /admin/config/regional/translate kan du begränsa exporten till översatta, oöversatta eller alla strängar. För en ny översättningsomgång ger export av endast oöversatta strängar dig en fokuserad .po-fil med exakt det arbete som återstår.
En praktisk konsekvens av denna trestegsstruktur: ditt översättningsarbete blir aldrig riktigt "klart". Varje gång du lägger till en bidragsmodul, aktiverar en ny funktion eller uppdaterar Drupal-kärnan, visas en ny omgång oöversatta msgid-poster i lokaltabellerna. Det är därför Drupal-team behandlar översättning som en återkommande process snarare än en engångsuppgift vid lansering. Samma loop för export, översättning och återimport körs vid varje utrullning som berör moduler, och ju snabbare den loopen är, desto mindre översättningsskuld ackumuleras mellan releaserna.
Det är också värt att notera att Drupal automatiskt kan hämta samhällsbidragna översättningar från localize.drupal.org för kärnan och populära bidragsmoduler. Dessa täcker de vanliga strängarna, men de täcker sällan dina anpassade moduler, ditt tema eller den projektspecifika frasering din webbplats faktiskt använder. Klyftan mellan samhällsöversättningen och en fullt lokaliserad webbplats är exakt det arbete som en AI-genomgång snabbt åtgärdar.
Drupals platshållare är inte WordPress-platshållare
Här är det viktigaste att förstå innan du skickar någon Drupal .po-fil till en AI-översättare: Drupal använder inte printf-stilens %s- och %1$s-platshållare som dominerar WordPress. Drupals t()-funktion använder tre distinkta platshållarprefix, var och en med olika undantagshantering:
@variable— värdet är HTML-escaped, det säkra standardvärdet för användarinmatad text.%variable— värdet är escaped och omslutet av<em>-framhävningsmarkering.:placeholder— används för URL-attribut, körs genom URL-sanering.
En typisk Drupal-källsträng ser ut så här i den exporterade .po-filen:
#: core/modules/node/node.module
msgid "@count comments"
msgid_plural "@count comments"
msgstr[0] ""
msgstr[1] ""
#: core/modules/user/user.module
msgid "Welcome @name, you last logged in on %date."
msgstr ""
Om en översättare ändrar @count till @cuenta, ersätter @name med det översatta ordet för "name," eller infogar ett mellanslag som förvandlar @count till @ count, matchar platshållaren inte längre vad t()-anropet skickar in. Drupal skriver då ut den bokstavliga token @count på sidan istället för det faktiska numret. Översättningen ser klar ut men webbplatsen är synligt trasig.
Detta är samma typ av bugg som påverkar WordPress %s-strängar, och vi går igenom den allmänna principen på djupet i hur man översätter PO-filer utan att bryta kodvariabler. Drupal-varianten är helt enkelt att det finns tre platshållarstilar istället för en, och ett översättningsverktyg måste känna igen alla.
Varför generiska översättare misslyckas här
Klistra in den där node.module-strängen i en generisk maskinöversättning, så får du ofta @count förvrängd, den <em>-bundna %date lokaliserad till en annan token, eller pluralformerna sammanslagna till en. Inget av dessa verktyg byggdes med gettext-semantik i åtanke. De översätter text; de förstår inte att @count är ett kontrakt med applikationskoden.
En gettext-medveten översättningspipeline med Syntaxlåsning behandlar @variable, %variable och :placeholder som oföränderliga token. De låses före översättning och återställs efteråt, så den omgivande meningen översätts medan platshållarna går igenom orörda. Samma lås täcker WordPress %s och %1$s, i18next {{name}} och inline HTML, vilket är anledningen till att ett enda verktyg kan tjäna ett Drupal-, Symfony- eller Laravel-projekt lika enkelt som ett WordPress-projekt. Drupals pluralformer via msgid_plural bevaras som pluralformer snarare än plattas ut, vilket är viktigt eftersom Drupal-språk kan ha allt från en till sex pluralvarianter.
Det finns också ett mer subtilt felfall som är värt att nämna. Drupal-strängar bäddar ofta in inline-markering och länkar inuti den översättbara texten, som Read the <a href=":url">documentation</a> där :url är en platshållare och <a>-taggarna måste överleva. En översättare som inte förstår strukturen kan översätta href-attributet, tappa bort avslutande tagg eller lokalisera platshållarnamnet. Kontextmedveten AI som läser hela strängen som en enhet, kombinerat med tokenlåsning, håller både markeringen och :url-kontraktet intakt samtidigt som den bara översätter den mänskligt läsbara "documentation"-texten däremellan.
Loopen för export, översättning och återimport
Det repeterbara arbetsflödet har tre steg, och drush gör export och import skriptbara så att du inte behöver klicka dig igenom administratörsgränssnittet varje gång.
Steg 1: Exportera PO-filen
Du kan exportera från användargränssnittet på /admin/config/regional/translate genom att välja ett språk och ett exportomfång, eller göra det från kommandoraden. Locale-modulen exponerar export via Drupals översättningstjänster, och de flesta team skriptar det. Ett typiskt drush-anrop för att utlösa en översättningsimport (det omvända, som vi använder i steg tre) ser ut så här:
# Re-import a translated PO file for Spanish, overwriting customized strings
drush locale:import es /var/www/translations/es-untranslated.po \
--type=customized --override=all
# Rebuild caches so the new strings render immediately
drush cache:rebuild
För exportsidan producerar administrationsformuläret .po-filen; många team omsluter locale-exporttjänsten i ett litet anpassat Drush-kommando för full automation. Oavsett vilket får du en standard gettext .po-fil som innehåller dina oöversatta msgid-poster.
Steg 2: Översätt filen
Detta är steget där AI ersätter timmar av manuell redigering. Ladda upp den exporterade .po-filen till en molnöversättare, välj ditt målspråk och låt den bearbeta. Eftersom Drupal .po-filer för en stor webbplats rutinmässigt överstiger 10MB när kärna, bidrag och teman kombineras, är Smart Batching viktigt här: filen delas upp, översätts och återmonteras utan att du behöver dela den manuellt eller stöta på storleksbegränsningar. Resultatet är en komplett .po-fil med varje msgstr ifylld och varje @count, %date och :url-platshållare exakt där den började.
Steg 3: Importera tillbaka till Drupal
Importera den översatta filen tillbaka via /admin/config/regional/translate eller via drush locale:import-kommandot som visas ovan, bygg sedan om cachen. Drupal sammanfogar översättningarna i sina lokaltabeller, och strängarna visas på webbplatsen omedelbart. Kör loopen igen när du lägger till en modul eller uppdaterar kärnan, eftersom varje sådan åtgärd medför nya oöversatta strängar.
En importdetalj att ha koll på: --override-flaggan styr om inkommande översättningar ersätter befintliga. Använd --override=all när du vill att den AI-översatta filen ska vara auktoritativ, eller en mer konservativ inställning om du har finjusterat vissa strängar i Drupal UI som du inte vill ska skrivas över. För de flesta automatiserade pipelines håller systemet förutsägbart att behandla .po-filen som sanningens källa och skriva över allt: filen i versionskontroll är det som webbplatsen visar, punkt slut.
För flerspråkiga webbplatser med flera målspråk körs loopen en gång per språk. Exportera den oöversatta uppsättningen, översätt den till tyska, importera den; exportera igen, översätt till spanska, importera den; och så vidare. Eftersom varje språk är en oberoende .po-fil kan du köra dem parallellt, och en molnöversättare som bearbetar dem samtidigt förvandlar det som tidigare var en veckas entreprenörstid till en eftermiddag.
Drupal PO är ett av flera format
Det är värt att notera att gettext .po inte är det enda sättet Drupal hanterar översättning på. Konfigurations- och innehållsenheter kan också utbytas som XLIFF, vilket är standarden som Translation Management Tool (TMGMT)-modulen förlitar sig på för arbetsflöden med professionella översättningsleverantörer. Om din Drupal-lokalisering går via XLIFF snarare än gränssnitts .po-filer, är principerna för bevaring av platshållare identiska men filstrukturen skiljer sig, och vi täcker den vägen i översättning av XLIFF-filer för Drupal, Symfony och Angular.
För gränssnittsöversättningsskiktet är dock .po fortfarande arbetshästen. Loopen för export, AI-översättning och återimport förvandlar en flerdagars manuell syssla till några minuters bearbetning, och så länge verktyget du använder verkligen förstår gettext-platshållare, överlever dina @variable-kontrakt intakta och din Drupal-webbplats förblir hel på varje språk du lanserar.
Redo att översätta dina Drupal
.po-filer utan att bryta en enda@variable? Prova SimplePoTranslate gratis — inget kreditkort krävs. Den kostnadsfria nivån hanterar standard gettext.po- och.pot-filer med full Syntaxlåsning, så dina Drupal-platshållare passerar igenom exakt som koden förväntar sig.