Hoe .po-bestanden naar .mo te compileren (4 Methoden)

Je hebt een middag besteed aan het perfectioneren van een Duitse vertaling. Elke string in je de_DE.po bestand leest prachtig, de placeholders zijn intact, de meervouden kloppen. Je uploadt het naar je site, schakelt de taal over naar Duits, en... niets. De pagina is nog steeds in het Engels. Je controleert de bestandsnaam, de map, het text domain. Alles lijkt in orde. Dus waarom toont WordPress je vertaling niet?
Negen van de tien keer is het antwoord hetzelfde: je hebt de .po bewerkt, maar deze nooit gecompileerd naar .mo. WordPress leest .po-bestanden niet tijdens runtime — het laadt de gecompileerde binaire .mo. Als je wilt dat je vertalingen daadwerkelijk verschijnen, moet je de po compileren naar mo elke keer dat je de tekst wijzigt. De .po is je bewerkbare bron; de .mo is wat de site serveert.
Deze gids legt uit waarom die compilatiestap bestaat en beschrijft vervolgens vier betrouwbare manieren om dit te doen: WP-CLI, het klassieke msgfmt commando, Poedit, en een cloudtool die de .mo automatisch voor je genereert. We behandelen ook de meest voorkomende valkuil — het vergeten opnieuw te compileren — en het nieuwere .l10n.php formaat dat WordPress nu verkiest voor snelheid.
Waarom laadt WordPress .mo en niet .po?
WordPress laadt .mo-bestanden omdat het gecompileerde binaire bestanden zijn die geoptimaliseerd zijn voor snelle opzoekingen, terwijl .po-bestanden platte tekst zijn, gemaakt om door mensen te lezen en te bewerken. Tekst parsen bij elke paginalading zou traag zijn; het lezen van een vooraf gebouwde binaire hashtabel is bijna onmiddellijk.
Een .po-bestand is regelgebaseerd en mensvriendelijk. Elke invoer koppelt een bron msgid aan een vertaalde msgstr, plus opmerkingen die aangeven waar de string vandaan komt. Dat is geweldig voor bewerking, maar verschrikkelijk voor de prestaties — de server zou het hele tekstbestand bij elk verzoek opnieuw moeten parsen.
#: includes/cart.php:88
msgid "Your cart is empty"
msgstr "Ihr Warenkorb ist leer"
Een .mo-bestand verpakt diezelfde stringparen in een binair formaat met een interne opzoektabel, zodat WordPress direct naar een vertaling kan springen zonder tekst te scannen. Het nadeel is dat .mo onleesbaar is voor mensen en opnieuw moet worden gegenereerd wanneer de .po verandert. Als het onderscheid tussen .po en .mo nog steeds onduidelijk is, legt onze uitleg over .po vs .mo vs .pot-bestanden elk formaat en hun onderlinge relatie uit.
Vier manieren om po naar mo te compileren
Er is geen enkele "juiste" tool — de beste keuze hangt af van hoe je al werkt. Hieronder staan vier betrouwbare methoden, van een enkel commando tot een volledig geautomatiseerde cloudworkflow. Alle vier produceren de identieke binaire .mo die WordPress tijdens runtime laadt.
Methode 1: WP-CLI
De schoonste moderne aanpak is WP-CLI, die een hele map met .po-bestanden in één commando kan compileren. Als je WordPress al via de commandoregel beheert, past dit natuurlijk in je workflow.
# Compile every .po file in the languages folder to .mo
wp i18n make-mo languages/
# Compile into a specific destination directory
wp i18n make-mo languages/ build/languages/
Het make-mo-commando scant de doelmap, compileert elke .po die het vindt, en schrijft een overeenkomende .mo ernaast (of naar de bestemming die je opgeeft). Het verwerkt batches netjes, wat het ideaal maakt als je veel talen tegelijk beheert. Het is de aanbevolen tool voor elk project dat al WP-CLI gebruikt.
Methode 2: msgfmt
De originele Gettext-utility voor deze taak is msgfmt, onderdeel van het GNU gettext-pakket. Het compileert één .po naar één .mo en is beschikbaar op vrijwel elk Linux- en macOS-systeem.
# Compile one file
msgfmt my-plugin-de_DE.po -o my-plugin-de_DE.mo
# Add statistics about translated, fuzzy, and untranslated strings
msgfmt --statistics my-plugin-de_DE.po -o my-plugin-de_DE.mo
# Install it first if missing
# macOS: brew install gettext
# Debian: sudo apt-get install gettext
De -o vlag benoemt het uitvoerbestand. De --statistics vlag is oprecht nuttig — het vertelt je hoeveel strings zijn vertaald, onzeker (fuzzy) zijn, of nog leeg zijn, zodat je een onvolledige vertaling opmerkt voordat je deze uitbrengt. Voor het scripten van één bestand tegelijk is msgfmt de betrouwbare, no-nonsense keuze.
Omdat msgfmt een eenvoudig commandoregel-tool is, past het naadloos in automatisering. Je kunt het in een shell-loop wikkelen om een hele map te compileren, of het koppelen aan een CI-pipeline, zodat elke commit die een .po aanraakt, automatisch een nieuwe .mo produceert. Een veelvoorkomend patroon is for f in languages/*.po; do msgfmt "$f" -o "${f%.po}.mo"; done, wat elke taal in één keer compileert. De --check vlag voegt validatie toe, waarbij fouten in de opmaakstring tussen msgid en msgstr worden gemarkeerd voordat ze de productie bereiken — een goedkope beveiliging tegen bugs met kapotte placeholders die vertaalde lay-outs stilletjes beschadigen.
Methode 3: Poedit (Compileert bij opslaan)
Als je vertalingen bewerkt in een grafische editor, compileert Poedit deze automatisch voor je. Elke keer dat je een .po-bestand opslaat, schrijft Poedit het overeenkomende .mo-bestand er direct naast — geen apart commando, geen extra stap.
Dit is een reden waarom Poedit populair blijft bij vertalers die niet vertrouwd zijn met de commandoregel. Je opent de .po, typt je vertalingen, klikt op opslaan, en beide bestanden worden samen bijgewerkt. Je kunt het gedrag bevestigen onder de voorkeuren van Poedit, waar automatische .mo-compilatie bij opslaan standaard is ingeschakeld. Poedit en vergelijkbare desktoptools worden beoordeeld in top 5 gratis tools om PO-bestanden te bewerken en te vertalen op Mac en Windows.
Het nadeel van een desktopeditor is dat compilatie alleen plaatsvindt wanneer een mens het bestand opent en opslaat. Dat is prima voor een eenpersoonsproject, maar het schaalt niet naar een dozijn talen of een team dat bestanden heen en weer stuurt. Als iemand een .po bewerkt in een andere tool en deze naar de repository kopieert zonder Poedit te openen, wordt de .mo nooit bijgewerkt. Voor grotere of collaboratieve projecten verwijdert een geautomatiseerde methode — commandoregel of cloud — die afhankelijkheid van het onthouden om op opslaan te drukken.
Methode 4: Een cloudtool die de .mo voor je genereert
De vierde optie verwijdert de compilatiestap volledig: gebruik een cloudservice die de gecompileerde .mo samen met de vertaalde .po teruggeeft. Je voert nooit een commando uit of slaat een bestand twee keer op — je uploadt, en afgewerkte, correct benoemde bestanden komen terug.
SimplePoTranslate werkt precies zo. Je uploadt een .po of .pot, het vertaalt de strings met Context-Aware AI, en het retourneert een enkele ZIP met daarin de .po en .mo naast elkaar gegenereerd — al gecompileerd, al benoemd om te matchen met je text domain en locale. Er is geen aparte compilatiegang en geen kans om er een te vergeten.
Het behandelt ook de details die handmatige workflows onderbreken. Syntax Locking bevriest placeholders zoals %s, %1$s, en {name} plus HTML-tags vóór vertaling, zodat je variabelen intact in de .mo terechtkomen. Volledige Gettext plural ondersteuning betekent dat complexe meervoudsvormen ook correct compileren — een onderwerp dat de moeite waard is om diepgaand te begrijpen, wat we behandelen in Gettext meervouden begrijpen. En omdat het in de cloud draait, is er geen plugin om te installeren en geen build tooling om te onderhouden.
De meest voorkomende valkuil: je bent vergeten opnieuw te compileren
De grootste reden waarom vertalingen niet verschijnen, is het bewerken van de .po maar het vergeten om de .mo opnieuw te compileren. WordPress blijft de oude binaire versie laden, dus je nieuwe formulering verschijnt nooit — en er is geen foutmelding om je te vertellen waarom.
Het mentale model om te onthouden: de .po is je concept, de .mo is wat wordt geleverd. Elke wijziging aan de .po is onzichtbaar voor WordPress totdat je de .mo opnieuw genereert. Maak hercompilatie een reflex na elke bewerking, of gebruik een tool die automatisch compileert zodat de stap nooit kan worden overgeslagen.
Deze valkuil is vooral slinks bij overdrachten van staging naar productie. Een ontwikkelaar bewerkt en hercompileert lokaal, ziet de vertaling werken, en implementeert vervolgens alleen de .po en vergeet de .mo — waardoor de productie stilletjes de oude tekst behoudt. Telkens wanneer je vertaalbestanden tussen omgevingen verplaatst, verplaats dan de .po en de vers gecompileerde .mo samen, of compileer als onderdeel van je implementatiestap, zodat de binaire versie altijd wordt herbouwd vanuit de huidige bron.
Als je vertalingen nog steeds weigeren te verschijnen na het opnieuw compileren, is het probleem meestal een naamverschil, een verkeerde map of een cachinglaag die het oude bestand vasthoudt. De volledige checklist vind je in waarom je vertalingen niet verschijnen in WordPress.
Een opmerking over het nieuwere .l10n.php formaat
Recente WordPress-versies introduceerden een derde runtime-formaat: .l10n.php. In plaats van een binaire .mo, worden vertalingen opgeslagen als een eenvoudig PHP-array dat de PHP-opcodecache in het geheugen kan vasthouden, waardoor opzoekingen op drukke sites zelfs sneller zijn dan bij .mo.
<?php
return [
'domain' => 'my-plugin',
'messages' => [ 'Your cart is empty' => 'Ihr Warenkorb ist leer' ],
];
WordPress genereert automatisch .l10n.php-bestanden wanneer de overeenkomende .mo beschikbaar is, dus je hoeft ze niet handmatig te bouwen. Voor nu blijft het compileren van een correcte .mo de basis — het prestatieformaat is daarvan afgeleid.
Samenvattend
Om po naar mo betrouwbaar te compileren, kies je de methode die past bij jouw manier van werken: WP-CLI voor commandoregel-batches, msgfmt voor enkele bestanden met statistieken, Poedit voor automatische compilatie bij opslaan, of een cloudtool die de .mo voor je bouwt zodat de stap nooit wordt overgeslagen. Alle vier produceren dezelfde binaire versie die WordPress tijdens runtime nodig heeft.
Welke route je ook kiest, onthoud de gouden regel: bewerk de .po, compileer dan naar .mo — elke keer weer. Die ene gewoonte voorkomt de meest frustrerende vertaalbug in WordPress, die waarbij alles er goed uitziet, maar de site koppig in het Engels blijft.
Klaar om de handmatige compilatiestap voorgoed over te slaan? Probeer SimplePoTranslate gratis — geen creditcard nodig. Upload je
.poen download binnen enkele minuten een kant-en-klaar te implementeren.po+.mobundel op de gratis laag.