FunctiesPluginPrijzenBronnen
Taal wijzigen
BronnenHoe u .po-vertaling kunt automatiseren in uw CI/CD-pipeline

Hoe u .po-vertaling kunt automatiseren in uw CI/CD-pipeline

SimplePoTranslate Team9 juni 2026
Hoe u .po-vertaling kunt automatiseren in uw CI/CD-pipeline

Uw team merget veertien keer per dag naar main. Elke merge kan een nieuwe gebruikersgerichte string toevoegen – een knoplabel, een foutmelding, een tooltip. En elk van die strings begint zijn leven alleen in het Engels. Ergens in uw releaseproces moet een mens de nieuwe strings opmerken, exporteren, laten vertalen, terugplakken en opnieuw compileren. Die mens is een knelpunt, en in een snel leverend team betekent dat knelpunt dat uw Duitse gebruikers twee sprints lang Engelse placeholders zien.

De oplossing is om vertaling in uw CI/CD-pipeline te automatiseren, zodat nieuwe strings worden vertaald bij dezelfde merge die ze introduceerde – zonder menselijke tussenkomst in het kritieke pad voor de routinematige gevallen. Dit is tegenwoordig volledig haalbaar, maar alleen als u de valkuil vermijdt waar de meeste teams in trappen: het handmatig schrijven van ruwe LLM-aanroepen die stilletjes uw %s-placeholders en .po-structuur corrumperen. Deze gids bespreekt een realistisch CI-pijplijnpatroon, een werkend GitHub Actions-skelet en de ontwerpbeslissingen – idempotentie, alleen-nieuwe-vertalingen, beoordelingspoorten – die een pijplijn die helpt onderscheiden van een die kapotte builds levert.

Waarom handmatige vertaling een releaseknelpunt is

Het antwoord op "waarom niet gewoon vertalen vóór elke release" is dat de timing nooit overeenkomt. Strings worden continu toegevoegd door ontwikkelaars, maar vertaling gebeurt in batches door een andere persoon volgens een ander schema. De kloof tussen die twee cadensen is waar uw lokalisatieschuld zich opbouwt.

Het Twee-Cadans Probleem

Stel u de handmatige workflow voor. Een ontwikkelaar voegt __( 'Export to CSV', 'mytextdomain' ) toe en merget. Niemand genereert de .pot opnieuw. Twee weken later voert iemand wp i18n make-pot uit, merkt veertig nieuwe onvertaalde strings op (sommige van ontwikkelaars die inmiddels met vakantie zijn), raadt de intentie van de helft ervan en stuurt een .po naar een vertaler. De vertaling komt terug, wordt geplakt, en misschien hebben de placeholders het overleefd en misschien ook niet. Ondertussen zijn er drie releases uitgebracht met die strings in het Engels.

Elke stap is handmatig, in batches en foutgevoelig. Het doel van CI/CD-automatisering is om dit samen te voegen tot iets dat automatisch draait bij een merge, alleen vertaalt wat daadwerkelijk is gewijzigd, en luidruchtig faalt wanneer er iets mis lijkt – waardoor vertaling van een periodieke taak verandert in een onzichtbaar onderdeel van de pijplijn.

Het pijplijnpatroon: extraheren, verschillen, vertalen, committen

Op een hoog niveau voert een geautomatiseerde vertaaltaak vier stappen uit bij een merge naar main: de template opnieuw genereren, detecteren wat nieuw is, alleen die strings vertalen en de resultaten terug committen. Het geheel moet idempotent zijn – het uitvoeren op een merge zonder stringwijzigingen moet nul verschil en nul ruis opleveren.

Extraheren en verschillen

Stap één is extractie. Genereer de .pot opnieuw vanuit de huidige bron, zodat deze elke string in de codebase weerspiegelt:

wp i18n make-pot . languages/myplugin.pot

Stap twee is het verschil (diff). Dit is de belangrijkste ontwerpbeslissing in de hele pijplijn. U wilt niet elke string opnieuw vertalen bij elke merge – dat verspilt API-aanroepen, riskeert het opnieuw vertalen van strings die een mens al heeft gecorrigeerd, en produceert enorme beoordelingsverschillen (review diffs). In plaats daarvan voegt u de nieuwe .pot samen met elke bestaande .po en vertaalt u alleen de items die nu leeg zijn (de werkelijk nieuwe strings):

# Merge new template into each locale, preserving existing translations.
# Newly-added strings appear with empty msgstr; --backup=none keeps the tree clean.
for po in languages/*.po; do
    msgmerge --update --backup=none "$po" languages/myplugin.pot
done

Na msgmerge hebben alleen gloednieuwe strings een lege msgstr. Alles wat eerder is vertaald, blijft onaangeroerd. Die eigenschap maakt de pijplijn idempotent en houdt uw beoordelingsverschillen klein en overzichtelijk.

Vertalen en committen

Stap drie stuurt alleen die lege items naar een vertaalstap. Stap vier commit het bijgewerkte .po-bestand, compileert .mo, en regenereert eventuele JSON. We zullen dit alles vervolgens in GitHub Actions integreren.

Een GitHub Actions-skelet

Hier is het antwoord op "hoe ziet dit er eigenlijk uit in een workflowbestand": een taak die wordt geactiveerd bij een push naar main, die de cyclus van extraheren-verschillen-vertalen-committen uitvoert en een pull-request opent met de resultaten, in plaats van rechtstreeks naar main te committen.

Het workflowbestand

name: Translate on merge

on:
  push:
    branches: [ main ]

jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install WP-CLI and gettext
        run: |
          sudo apt-get update && sudo apt-get install -y gettext
          curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
          sudo mv wp-cli.phar /usr/local/bin/wp && sudo chmod +x /usr/local/bin/wp

      - name: Regenerate template and merge into locales
        run: |
          wp i18n make-pot . languages/myplugin.pot
          for po in languages/*.po; do
            msgmerge --update --backup=none "$po" languages/myplugin.pot
          done

      - name: Translate only new (empty) strings
        env:
          TRANSLATE_API_KEY: ${{ secrets.TRANSLATE_API_KEY }}
        run: ./scripts/translate-new-strings.sh languages/

      - name: Compile .mo and JSON
        run: |
          wp i18n make-mo languages/
          wp i18n make-json languages/ --no-purge

      - name: Open pull request with translations
        uses: peter-evans/create-pull-request@v6
        with:
          branch: chore/auto-translations
          title: "chore: auto-translate new strings"
          commit-message: "chore: auto-translate new strings"

Waar het echte werk zich schuilhoudt

De translate-new-strings.sh-stap is waar de daadwerkelijke vertaling plaatsvindt. De naïeve versie van dat script leest elke lege invoer, stuurt deze één voor één naar een LLM API en plakt het antwoord terug. Die naïeve versie is precies de valkuil, en het is de moeite waard om expliciet te zijn over waarom.

Waarom handmatige LLM-aanroepen uw bestanden kapotmaken

Het korte antwoord: ruwe LLM-aanroepen behandelen uw .po-strings als proza, en uw .po-strings zijn geen proza – het zijn gestructureerde gegevens met placeholders, meervoudsvormen en context die een chat-completion-aanroep met plezier vernietigt.

De Placeholder-corruptie die u niet in tests zult zien

Stuur Deleted %d of %s files naar een algemeen chat-endpoint en u krijgt mogelijk Supprimé %d des %s fichiers (prima) of Supprimé %d de % s fichiers terug (een spatie is in de placeholder geslopen, en nu werpt sprintf() een runtime-fout op). Stuur een meervoudige invoer en het model kan twee vormen samenvoegen tot één, wat talen met meer dan twee meervoudscategorieën kapotmaakt. Stuur een string met <a href="%s"> en het model kan de URL vertalen of de tag weglaten. Geen van deze fouten verschijnt in uw tests, tenzij u specifiek de gerenderde uitvoer in elke locale test – ze verschijnen als runtime-fouten in productie voor gebruikers van wie u geen bugrapporten kunt lezen.

De onderhoudsvalkuil

U kunt proberen dit te verdedigen met prompt engineering en regex post-processing, en veel teams doen dat ook. Het probleem is dat u nu een fragiele vertaalmachine als een nevenproject onderhoudt, waarbij u elke placeholder-randgeval herontdekt die het Gettext-ecosysteem al heeft opgelost. We catalogiseren de specifieke manieren waarop variabelen worden verminkt – en hoe u ze kunt voorkomen – in vertalen van PO-bestanden zonder codevariabelen te breken. De les daar is direct van toepassing: de modelkwaliteit is zelden het probleem; de structurele afhandeling eromheen wel.

Een API-gestuurde cloudvertaler in CI passen

Dit is waar een API-gestuurde vertaaldienst uw translate-new-strings.sh-gokwerk vervangt. In plaats van handmatig LLM-aanroepen en post-processing regex te schrijven, uploadt uw CI-stap het gewijzigde .po-bestand naar een dienst die de Gettext-structuur al begrijpt en schone uitvoer teruggeeft. De pijplijnvorm blijft identiek – extraheren, verschillen, vertalen, committen – maar de fragiele tussenstap wordt één enkele API-aanroep.

De API-aanroep die uw script vervangt

SimplePoTranslate is precies hiervoor gebouwd. Het biedt een cloud-API die geschikt is voor automatisering en CI, zodat de vertaalstap van uw workflow een verzoek wordt dat de .po overhandigt en een vertaald exemplaar terugkrijgt, zonder per-string-looping. De Syntax Locking houdt %s, %1$s, {count}, HTML en code-tokens automatisch op hun plaats – de hele klasse bugs uit de vorige sectie wordt afgehandeld door de engine in plaats van door regex die u onderhoudt. Met volledige Gettext meervouds- en msgctxt-ondersteuning overleven meervoudsvormen en context de round trip, wat een chat-completion-aanroep niet kan garanderen.

Idempotentie en de beoordelingspoort blijven van u

Twee ontwerpbeslissingen blijven van u, ongeacht welke engine u gebruikt. Ten eerste, idempotentie: blijf alleen de lege items vertalen na msgmerge, zodat no-op merges geen verschillen opleveren. Ten tweede, een beoordelingspoort: laat de taak een pull-request openen, zoals het bovenstaande skelet doet, in plaats van rechtstreeks naar main te committen. Machinetranslatie is uitstekend om strings snel live te krijgen, maar een menselijke blik vóór de merge vangt de zeldzame contextuele misser op – en een PR geeft u die blik zonder het algemene geval te blokkeren. Teams die met veel locales of veel klantwebsites werken, zullen deze vorm herkennen van de ideale lokalisatieworkflow voor bureaus, waar hetzelfde automatiseren-en-daarna-beoordelen-patroon schaalt over tientallen projecten.

Conclusie

Om vertaling in CI/CD te automatiseren zonder kapotte builds te leveren, is het patroon consistent: genereer de .pot opnieuw bij een merge, msgmerge deze in elke locale om alleen nieuwe strings naar voren te brengen, vertaal alleen die strings, en commit het resultaat achter een pull-request beoordelingspoort. Idempotentie houdt uw verschillen schoon; de beoordelingspoort houdt de zeldzame slechte vertaling uit productie.

Het onderdeel dat goed moet zijn, is de vertaalstap zelf. Handmatig geschreven LLM-aanroepen zullen placeholders en meervoudsvormen corrumperen op manieren die uw tests niet zullen vangen, en u zult meer tijd besteden aan het onderhouden van de vertaal-'lijm' dan aan de featurecode die het bedient. Een API-gestuurde engine met Syntax Locking elimineert die hele faalmodus, zodat uw pijplijn nieuwe strings vertaalt bij dezelfde merge die ze introduceerde – en uw niet-Engelse gebruikers geen Engelse placeholders meer zien.

Klaar om vertaling in uw pijplijn te automatiseren zonder placeholders te breken? Probeer SimplePoTranslate gratis — geen creditcard nodig. Begin met de gratis laag, valideer de API tegen uw eigen .po-bestanden, en integreer het in CI wanneer u er klaar voor bent.